tamaño de bloque de archivo: diferencia entre stat y ls

9

Me di cuenta de que cuando hago un:

ls -ls file

Proporciona conteo de bloques, digamos 8 bloques.

Cuando lo hago:

stat file

Noté que el recuento de bloques es 16, el doble del número dado por ls.

El tamaño de bloque en mi sistema de archivos es 4096. Aprendí que la unidad arbitraria para los bloques usados ​​por ls es 1024. ¿Es correcto decir que stat usa una unidad arbitraria de 512 bytes cuando informa bloques?

Si es así, ¿hay alguna razón para la inconsistencia?

Estoy ejecutando Ubuntu 11.10 en un sistema de archivos ext4.

stantona
fuente

Respuestas:

9

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. Por lo tanto, las utilidades tradicionales como lse duindican tamaños en unidades de fragmentos de 512 bytes.

Para los humanos, las unidades de 512 bytes no son muy significativas. 1kB es el mismo orden de magnitud y mucho más significativo. Un bloque de sistema de archivos (la unidad más pequeña en la que se divide un archivo) en realidad a menudo consta de varios sectores: 1kB, 2kB y 4kB son tamaños de bloque de sistema de archivos comunes; por lo tanto, la unidad de 512 bytes no está fuertemente justificada por el diseño del sistema de archivos, y no hay otra buena razón que la tradición para usar una unidad de 512 bytes fuera de un controlador de disco.

Entonces, tienes una tradición que no tiene mucho que ver, y una convención más legible que está asumiendo. Un poco como octal y hexadecimal: no hay uno que esté bien y uno que esté mal, son diferentes formas de escribir los mismos números.

Muchas herramientas tienen una opción para seleccionar unidades de visualización: ls --block-size=512para GNU ls, establecer POSIXLY_CORRECT=1en el entorno para GNU dfy GNU dupara obtener unidades de 512 bytes (o pasar -kpara forzar unidades de 1kB). Lo que el statcomando en GNU coreutils expone como el "tamaño de bloque" (el %Bvalor) es un valor dependiente del sistema operativo de una interfaz interna; dependiendo del sistema operativo, puede o no estar relacionado con un tamaño utilizado por el sistema de archivos o el código del disco (por lo general, no lo es; consulte Diferencia entre el tamaño del bloque y el tamaño del clúster ). En Linux, el valor es 512, independientemente de lo que esté haciendo cualquier controlador subyacente. El valor de %Bnunca importa, es solo una peculiaridad que existe en absoluto.

Gilles 'SO- deja de ser malvado'
fuente
4

Después de profundizar en el código fuente y el estándar POSIX, diría que la respuesta de @ antje-m y @Gilles es en su mayoría correcta.

Vale la pena citar el comentario de POSIX.1-2008 , como resumen:

El uso de unidades de 512 bytes es una práctica histórica y mantiene la compatibilidad con ls y otras utilidades en este volumen de POSIX.1-2008. Esto no exige que el sistema de archivos se base en bloques de 512 bytes. La opción -k se agregó como una medida de compromiso. Los desarrolladores estándar acordaron que 512 bytes era la mejor unidad predeterminada debido a su coherencia histórica completa en el Sistema V (frente al uso mixto de 512/1024 bytes en sistemas BSD), y que una opción -k para cambiar a 1024- unidades de bytes fue un buen compromiso. Los usuarios que prefieren la cantidad más lógica de 1024 bytes pueden alias fácilmente df a df -k sin romper muchos scripts históricos que dependen de las unidades de 512 bytes.

Para el tamaño del bloque en ls -s:

POSIX dice que el tamaño de bloque predeterminado está definido por la implementación, a menos que -kse brinde la opción.

El tamaño de bloque predeterminado implementado en GNU coreutils lsse define en 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

que proviene de un viejo commit:

commit 96e78d1f64d7c8d2acc5ad27dc3e73b96ae80585
Author: Jim Meyering <[email protected]>
Date:   Mon Jun 29 15:23:04 1998 +0000

El mensaje de confirmación en sí no decía nada sobre el número 1024.

Y tenga en cuenta que el tamaño de bloque utilizado duy dftambién es 1024, lssimplemente eligió consistir en ellos. Aunque para duy dfes un conflicto con el estándar POSIX (aquí POSIXLY_CORRECTviene la variable de entorno ). Esto parece una decisión del equipo de GNU, vea la página de wikipedia POSIX sobre esta controversia.

Por el comando stat.

No es parte del estándar POSIX, pero la llamada del sistema sí . Sin embargo, la unidad para el tamaño de bloque no está estandarizada ( sys_stat.h ):stat

La unidad para el miembro st_blocks de la estructura estadística no está definida en POSIX.1-2008.

El statcomando simplemente muestra la información proporcionada por la statllamada al sistema, y ​​con un tamaño de bloque de 512 con pocas excepciones (no son Linux, por ejemplo, HP-UX, IBM AIX, etc., consulte las macros definidas en gnulib/lib/stat-size.h).

Entonces, el número 512 es más una elección histórica y una convención de Linux.

El GNU coreutils(de ahí el lscomando) no es parte del kernel de Linux (de ahí la statllamada), apuntan a diferentes aspectos del sistema, GNU coreutilses más para humanos (más fácil de leer) y el kernel de Linux para resumen de hardware (por lo tanto, más cercano al hardware).

Editar: el tamaño del bloque 4096 es el tamaño del "bloque IO", el tamaño del bloque físico real probablemente todavía sea 512 Byte como se explica en esta pregunta .

Eddy Xiao
fuente
1

Los statcomandos utilizan el tamaño de bloque físico del disco duro. Básicamente, todos los discos duros desde su creación en 1956 han utilizado bloques de 512 bytes. Sin embargo, esto ha comenzado a cambiar recientemente con el próximo formato avanzado.

Sospecho que ls'1024byte-blocksize también tiene una razón histórica. Quizás alguna vez fue común que el sistema de archivos tuviera un tamaño de bloque de 1024 o se usó para darle el tamaño en kilobytes. Pero (al menos con GNU coreutils) puede especificar el tamaño del bloque con la --block-size=opción.

antje-m
fuente