размер блока файла - разница между stat и ls

9

Я заметил, что когда я делаю:

ls -ls file

Он обеспечивает количество блоков, скажем, 8 блоков.

Когда я делаю:

stat file

Я заметил, что количество блоков равно 16, вдвое больше, чем указано в ls.

Размер блока в моей файловой системе составляет 4096. Я узнал, что произвольная единица для блоков, используемых ls, равна 1024. Правильно ли говорить, что stat использует произвольную единицу в 512 байт при сообщении блоков?

Если да, есть ли причина для несоответствия?

Я использую Ubuntu 11.10 в файловой системе ext4.

stantona
источник

Ответы:

9

Многие диски имеют размер сектора 512 байт, что означает, что любое чтение или запись на диск передает весь 512-байтовый сектор за раз. Вполне естественно проектировать файловые системы, в которых сектор не разделен между файлами (это может усложнить проектирование и снизить производительность); поэтому файловые системы обычно используют 512-байтовые фрагменты для файлов. Следовательно, традиционные утилиты, такие как lsи duуказывают размеры в единицах по 512 байт.

Для человека 512-байтовые блоки не очень значимы. 1 КБ - тот же порядок величины и намного более значимый. Блок файловой системы (наименьшая единица, на которую разделен файл) на самом деле часто состоит из нескольких секторов: 1 кБ, 2 КБ и 4 КБ - это общие размеры блоков файловой системы; поэтому 512-байтовый блок не очень оправдан структурой файловой системы, и нет никаких других причин, кроме традиции, вообще использовать 512-байтовый блок вне драйвера диска.

Таким образом, у вас есть традиция, которая не требует много усилий, и более читаемое соглашение, которое берет на себя. Немного похоже на восьмеричное и шестнадцатеричное: нет правильного и неправильного, это разные способы написания одинаковых чисел.

Многие инструменты имеют возможность выбирать единицы отображения: ls --block-size=512для GNU ls, настройка POSIXLY_CORRECT=1в среде для GNU dfи GNU duдля получения 512-байтовых единиц (или передачи -kдля принудительной установки 1 кБ единиц). То, что statкоманда в GNU coreutils предоставляет как «размер блока» ( %Bзначение), является зависящим от ОС значением внутреннего интерфейса; в зависимости от ОС, он может быть или не быть связан с размером, используемым файловой системой или кодом диска (обычно это не так - см. Различие между размером блока и размером кластера ). В Linux это значение равно 512, независимо от того, что делает какой-либо основной драйвер. Ценность %Bникогда не имеет значения, это просто причуды, что она существует вообще.

Жиль "ТАК - перестань быть злым"
источник
4

После изучения исходного кода и стандарта POSIX я бы сказал, что ответы @ antje-m и @Gilles в основном правильные.

Стоит процитировать комментарий от POSIX.1-2008 , в качестве резюме:

Использование 512-байтовых модулей является исторической практикой и поддерживает совместимость с ls и другими утилитами в этом томе POSIX.1-2008. Это не требует, чтобы сама файловая система была основана на 512-байтовых блоках. Опция -k была добавлена ​​в качестве компромиссной меры. Разработчики стандарта согласились с тем, что 512 байт было лучшим модулем по умолчанию из-за его полной исторической согласованности в System V (по сравнению со смешанным использованием 512/1024 байт в системах BSD) и что опция -k для переключения на 1024- Единицы байтов были хорошим компромиссом. Пользователи, которые предпочитают более логичное 1024-байтовое количество, могут легко использовать псевдоним df для df -k, не нарушая многие исторические сценарии, полагаясь на 512-байтовые блоки.

Для размера блока в ls -s:

POSIX говорит, что размер блока по умолчанию определяется реализацией, если -kне указана опция.

Размер блока по умолчанию, реализованный в GNU coreutils ls, определяется в GNU gnulib: gnulib/lib/human.c

/* The default block size used for output.  This number may change in
   the future as disks get larger.  */
#ifndef DEFAULT_BLOCK_SIZE
# define DEFAULT_BLOCK_SIZE 1024
#endif

который происходит от старого коммита:

commit 96e78d1f64d7c8d2acc5ad27dc3e73b96ae80585
Author: Jim Meyering <jim@meyering.net>
Date:   Mon Jun 29 15:23:04 1998 +0000

Само сообщение о фиксации ничего не говорит о числе 1024.

И обратите внимание, что размер блока, который используется duи dfсоставляет также 1024, lsпросто решил с ними заключить. Хотя для duи dfэто противоречие со стандартом POSIX (поэтому здесь переменная окружения POSIXLY_CORRECTприходит). Это, кажется, решение команды GNU, см. Страницу POSIX в Википедии об этом противоречии.

Для команды stat.

Это не часть стандарта POSIX, но системный вызов . Однако единица измерения для размера блока не стандартизирована ( sys_stat.h ):stat

Модуль для элемента st_blocks структуры stat не определен в POSIX.1-2008.

Команда statпросто отображает информацию, предоставленную statсистемным вызовом, и использует размер блока 512 за небольшим исключением (они не являются Linux, например, HP-UX, IBM AIX и т. Д., См. Макросы, определенные в gnulib/lib/stat-size.h).

Так что число 512 - это скорее исторический выбор и соглашение Linux.

GNU coreutils(Отсюда и lsкоманда) не является частью Linux ядра (отсюда и statвызов), они нацелены на различные аспекты системы, GNU coreutilsбольше для человека (легче читать), и Linux ядро для аппаратного абстрактных (отсюда ближе к аппаратным средствам).

Изменить: размер блока 4096 является размером "блока ввода-вывода", реальный размер физического блока, вероятно, все еще 512 байт, как объяснено в этом вопросе .

Эдди Сяо
источник
1

В statкоманды использует физический размер блока на жестком диске. В основном все жесткие диски с момента их создания в 1956 году использовали блоки по 512 байт. Однако в последнее время это начало меняться с появлением расширенного формата.

Я подозреваю, что lsразмер блока 1024 байта также имеет историческую причину. Возможно, когда-то файловая система обычно имела размер блока 1024 или она использовалась, чтобы дать вам размер в килобайтах. Но (по крайней мере, с помощью GNU coreutils) вы можете указать размер блока с помощью --block-size=опции.

Антье-м
источник