EXT3: Si el tamaño del bloque es 4K, ¿por qué ls -l muestra tamaños de archivo por debajo de eso?

16

Si ejecuta ls -l en un archivo que contiene una letra, aparecerá en tamaño 2B. Si su sistema de archivos está en bloques de 4k, ¿pensé que redondeaba los archivos al tamaño del bloque? ¿Es porque ls -l realmente lee el recuento de bytes del inodo? ¿En qué circunstancias se le redondea para bloquear las respuestas frente a las respuestas reales de conteo de bytes en las utilidades GNU Kernel de Linux 2.6?

Gregg Leventhal
fuente
2
Tenga en cuenta que ext4 introduce un concepto de "empaque de archivos pequeños", con lo cual un archivo pequeño ocupará el mismo bloque de disco que ocupa su inodo (y, por lo tanto, evitará desperdiciar bloques de disco): lwn.net/Articles/469805
oakad

Respuestas:

20

Supongo que tiene esa letra en el archivo con echo a > fileo vim file, lo que significa que tendrá esa letra y una nueva línea adicional (dos caracteres, por lo tanto, dos bytes). ls -lmuestra el tamaño del archivo en bytes, no bloques (para ser más específico: longitud del archivo ):

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

(nota que cat -Amuestra nuevas líneas como $carácter)

En contraste con ls -l, dumostrará el tamaño real ocupado en el disco:

$ du testfile
4

(en realidad, dumuestra el tamaño en unidades de 1 KB, por lo que aquí el tamaño es 4 × 1024 bytes = 4096 bytes = 4 kiB, que es el tamaño de bloque en este sistema de archivos)

Para lsmostrar esto, deberá usar la -sopción en lugar de / además de -l:

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

La primera columna es el tamaño asignado, nuevamente en unidades de 1 kB. El último se puede cambiar especificando --block-size, p. Ej.

$ ls -ls --block-size=1 testfile
4096 -rw-r--r-- 1 aw aw 2 Apr 28 22:08 testfile
Andreas Wiese
fuente
3
Y, además, es bueno tener las dos informaciones. Los sistemas de archivos pueden hacer "compactación de cola" (sp?) (Usar un bloque compartido entre archivos cortos), "copiar al escribir" y "perforar" ... haciendo que la relación de tamaño de archivo <-> espacio en disco sea compleja.
Rmano
9

Creo que la respuesta profunda es la siguiente:

La longitud lógica del archivo y el espacio en disco ocupado son cosas realmente diferentes.

Como muestran las otras respuestas, en principio un archivo creado con dos bytes tiene una longitud de dos bytes (mostrar por ls -l) y ocupa 4 KiB (mostrar por duo ls -ls).

Ver:

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

Ok, testtiene longitud 1 y tamaño (en disco) 4 KiB. Pero:

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

(el primer comando agrega 8191 bytes cero a test), ahora la prueba tiene una longitud de 8192 pero aún ocupa 4 KiB en el disco (tiene un "agujero") (1).

Algunos sistemas de archivos también pueden compactar archivos cortos para que ocupen menos espacio al compartir bloques (ver, por ejemplo, el empaquetado de cola ) y otros, como btrfs, copian al escribir , por lo que la relación entre un archivo, su longitud lógica y cuánto espacio ocupa en Un disco es complejo.

Notas al pie:

(1) No es realmente un agujero , está al final ... pero aún así, funciona hasta el final del ejemplo.

Rmano
fuente
5

ls -lEs solo un formato largo. ls -lsse usa para mostrar el tamaño del bloque.

Pruebas

echo "1" > 1.txt

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

Como podemos ver, el tamaño del archivo aparece como 2B. Sin embargo, si necesita verificar el tamaño del bloque, debe ejecutar el siguiente comando.

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

El 4 anterior muestra el tamaño de bloque utilizado. También podemos verificar lo mismo usando el statcomando.

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

Ahora surge la pregunta de por qué ls -lsenumera el tamaño de bloque como 4 mientras statmuestra el tamaño de bloque como 8. La razón de este comportamiento se explica claramente en la respuesta aquí .

Muchos discos tienen un tamaño de sector de 512 bytes, lo que significa que cualquier lectura o escritura en el disco transfiere un sector completo de 512 bytes a la vez. Es bastante natural diseñar sistemas de archivos donde un sector no se divide entre archivos (eso complicaría el diseño y afectaría el rendimiento); por lo tanto, los sistemas de archivos tienden a usar fragmentos de 512 bytes para los archivos. De ahí que las utilidades tradicionales como lse duindiquen tamaños en unidades de fragmentos de 512 bytes.

Ramesh
fuente