EXT3: Если размер блока равен 4 КБ, почему ls -l показывает размеры файлов ниже этого?

16

Если вы запустите ls -l для файла, который содержит одну букву, он будет указан как 2B. Если ваша файловая система состоит из блоков 4k, я думал, что она округляет файлы до размера блока? Это потому, что ls -l на самом деле читает число байтов из inode? При каких обстоятельствах вас округляют, чтобы заблокировать ответы по сравнению с ответами по фактическому количеству байтов в Linux 2.6 Kernel GNU?

Грегг Левенталь
источник
2
Имейте в виду, что ext4 вводит концепцию «упаковки небольших файлов», при которой маленький файл будет занимать тот же блок диска, который занимает его inode (и, таким образом, избегать потери дисковых блоков): lwn.net/Articles/469805
oakad

Ответы:

20

Я предполагаю, что вы поместили одну букву в файл с echo a > fileили vim file, что означает, что у вас будет эта буква и дополнительный символ новой строки (два символа, то есть два байта). ls -lпоказывает размер файла в байтах, а не в блоках (точнее, длину файла ):

$ echo a > testfile
$ ls -l testfile
-rw-r--r-- 1 user user 2 Apr 28 22:08 testfile
$ cat -A testfile
a$

(обратите внимание, что cat -Aновые строки отображаются в виде $символов)

В отличие от ls -l, duпокажет реальный размер занимаемого на диске:

$ du testfile
4

(фактически, du показывает размер в единицах 1 кБ, поэтому здесь размер равен 4 × 1024 байт = 4096 байт = 4 кБ, что является размером блока в этой файловой системе)

Чтобы lsпоказать это, вы должны будете использовать -sопцию вместо / в дополнение к-l :

$ ls -ls testfile
4 -rw-r--r-- 1 user user 2 Apr 28 22:08 testfile

Первый столбец - это выделенный размер, опять же в единицах 1 кБ. Последний можно изменить, указав --block-size, например,

$ ls -ls --block-size=1 testfile
4096 -rw-r--r-- 1 aw aw 2 Apr 28 22:08 testfile
Андреас Визе
источник
3
И, кроме того, приятно иметь две информации. Файловые системы могут выполнять «хвостовое сжатие» (sp?) (Использовать один блок, общий для коротких файлов), «копировать при записи» и «пробивать дыры» ... делая сложным соотношение размера файла <-> на диске.
Rmano
9

Я думаю, что глубокий ответ заключается в следующем:

Логическая длина файла и занимаемое дисковое пространство - это действительно разные вещи.

Как показывают другие ответы, в принципе, файл, созданный из двух байтов, имеет длину два байта (показывать по ls -l) и занимать 4 КиБ (показывать поdu или ls -ls).

Видеть:

1& [:~/tmp] % echo -n A > test
1& [:~/tmp] % ls -l test
-rw-rw-r-- 1 romano romano 1 Apr 28 14:31 test
1& [:~/tmp] % du test
4 test

Хорошо, testимеет длину 1 и размер (на диске) 4 КиБ. Но:

1& [:~/tmp] % truncate -s +8191 test
1& [:~/tmp] % ls -l test
-rw-rw-r-- 1 romano romano 8192 Apr 28 14:33 test
1& [:~/tmp] % du test
4   test

(первая команда добавляет 8191 нулевых байтов к test ), теперь тест имеет длину 8192, но все еще занимает 4 КиБ на диске (в нем есть «дыра») (1).

Некоторые файловые системы также могут сжимать короткие файлы, чтобы они занимали меньше места за счет совместного использования блоков (см., Например, пакетную компоновку ), а другие, такие как btrfs, копируют при записи , поэтому взаимосвязь между файлом, его логической длиной и объемом занимаемого пространства диск сложный.

Примечания:

(1) Это на самом деле не дыра , это в конце ... но, тем не менее, это работает до конца примера.

Rmano
источник
5

ls -lэто просто длинный формат. ls -lsиспользуется для отображения размера блока.

тестирование

echo "1" > 1.txt

bash-3.2$ ls -l 1.txt
-rw-rw-r-- 1 ramesh ramesh 2 Apr 28 15:15 1.txt

Как мы видим, размер файла указан как 2B. Однако, если вам нужно проверить размер блока, вам нужно выполнить приведенную ниже команду.

bash-3.2$ ls -ls 1.txt
4 -rw-rw-r-- 1 ramesh ramesh 2 Apr 28 15:15 1.txt

4 выше отображает размер используемого блока. Мы также можем проверить то же самое с помощью statкоманды.

bash-3.2$ stat 1.txt
  File: `1.txt'
  Size: 2               Blocks: 8          IO Block: 4096   regular file
Device: 805h/2053d      Inode: 48267720    Links: 1
Access: (0664/-rw-rw-r--)  Uid: (  505/  ramesh)   Gid: (  508/  ramesh)
Access: 2014-04-28 15:17:31.000000000 -0500
Modify: 2014-04-28 15:15:58.000000000 -0500
Change: 2014-04-28 15:15:58.000000000 -0500

Теперь возникает вопрос: почему ls -lsразмер блока указан как 4, а statразмер блока - как 8. Причина такого поведения четко объяснена в ответе здесь .

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

Рамеш
источник