Al responder esta pregunta de U&L titulada: ¿Qué comando utilizo para ver el bloque de inicio y finalización de un archivo en el sistema de archivos? , Traté de averiguar si era posible determinar el LBA de un archivo usando su inodo.
Mi respuesta determinó que podría usar hdparm
como un método para encontrar LBA:
$ sudo hdparm --fibmap afile
afile:
filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
byte_offset begin_LBA end_LBA sectors
0 282439184 282439191 8
Pero tenía curiosidad si había algún método que usara el inodo de un archivo para obtener también los LBA; sin utilizar hdparm
.
Creo que puede haber métodos alternativos que se esconden en las herramientas filefrag
, stat
, debugfs
, y tune2fs
aunque las burlas hacia fuera me está eludiendo.
¿Alguien puede pensar en alternativas?
Aquí hay algunas de mis investigaciones hasta el momento que podrían ser útiles para aquellos lo suficientemente valientes como para intentar responder esto.
filefrag
Sospecho que podría usar la herramienta filefrag
para hacerlo, específicamente usando los resultados de su -e
cambio, tal vez realizando varios cálculos para llegar allí con los que no estoy tan familiarizado.
salida de muestra
$ filefrag -e afile
Filesystem type is: ef53
File size of afile is 20 (1 block of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 0: 35304898.. 35304898: 1: eof
afile: 1 extent found
inodes
Otro método potencial que sospecho que podría tener potencial es utilizar la información de inodo de un archivo, ya sea directamente o a través de algunas matemáticas complejas que están mal documentadas en las redes.
Ejemplo
Primero descubrimos el inodo del archivo. Podemos hacer esto usando el stat
comando o ls -i
.
stat
$ stat afile
File: ‘afile’
Size: 20 Blocks: 8 IO Block: 4096 regular file
Device: fd02h/64770d Inode: 6560281 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ saml) Gid: ( 1000/ saml)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-12-27 18:40:12.788333778 -0500
Modify: 2013-12-27 18:40:23.103333073 -0500
Change: 2013-12-27 18:44:03.697317989 -0500
Birth: -
ls -i
$ ls -i
6560281 afile
Con la información de i-nodo en la mano, ahora podemos abrir el sistema de archivos Este archivo reside en el uso de la herramienta, debugfs
.
NOTA: Para determinar el sistema de archivos en el que reside un archivo, puede usar el comando df <filename>
.
Ahora, si ejecutamos debugfs
y ejecutamos el comando stat <inode #>
, podemos obtener una lista de extensiones que contienen los datos de este archivo.
$ sudo debugfs -R "stat <6560281>" /dev/mapper/fedora_greeneggs-home
debugfs 1.42.7 (21-Jan-2013)
Inode: 6560281 Type: regular Mode: 0664 Flags: 0x80000
Generation: 1999478298 Version: 0x00000000:00000001
User: 1000 Group: 1000 Size: 20
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 8
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x52be10c3:a640e994 -- Fri Dec 27 18:44:03 2013
atime: 0x52be0fdc:bbf41348 -- Fri Dec 27 18:40:12 2013
mtime: 0x52be0fe7:18a2f344 -- Fri Dec 27 18:40:23 2013
crtime: 0x52be0dd8:64394b00 -- Fri Dec 27 18:31:36 2013
Size of extra inode fields: 28
Extended attributes stored in inode body:
selinux = "unconfined_u:object_r:user_home_t:s0\000" (37)
EXTENTS:
(0):35304898
Ahora tenemos la información de extensión anterior, y aquí es donde me pierdo y no sé cómo proceder.
Referencias
fuente
filefrag -b512 -v ..
dice "physical_offset: 211787168 .. 211795719", ¿esto equivaldría a los LBA? Esto parece coincidir con el mismo archivo conhdparm --fibmap
211787168..211795719. Si dejo caer-b512 -v
y uso el def. 1024, e intento de mult. a las 8, 26473396⋅8..26474464⋅8, obtengo 211787168..211795712, que está cerca pero un poco fuera de lugar. Estoy pensando que el segundo valor debería ser (26474465⋅8) -1 = 211795719, aunque no estoy seguro de por qué.Resulta que la conversión de extensiones a LBA es bastante sencilla una vez que entiendes de dónde provienen los números. La respuesta de @StephaneChazelas fue crítica para obtener esta comprensión.
Salida de depuración original
Usando el siguiente ejemplo que se mencionó en la pregunta.
Con la información de extensión podemos hacer los siguientes cálculos. Pero necesitamos una información adicional. El tamaño de bloque del sistema de archivos subyacente. Puede usar este comando para obtenerlo.
Tamaño de bloque
Conversión de extensiones a LBA
Entonces, la transformación clave para reconocer aquí es que los LBA están en unidades de 512 bytes y el
debugfs
comando anterior que informó el número de extensiones, informa que en bloques de 4096 bytes.Entonces, 4096/512 = 8. Entonces, necesitamos multiplicar las extensiones por 8 para convertirlas a valores LBA.
Entonces las siguientes matemáticas nos darán nuestro LBA inicial:
Entonces, ¿cuál es nuestro LBA final? Para lograrlo, debemos reconocer que nuestro inodo cabe dentro de un solo bloque, por lo que su extensión final es la misma que su extensión inicial. Para calcular el LBA final podemos usar esta ecuación.
Entonces realizando este cálculo:
Confirmando los resultados
Mirando la
hdparm
salida original :Vemos que las cosas coinciden.
Otro ejemplo
Solo para asegurarnos de que tenemos razón, aquí hay un archivo más grande como un segundo ejemplo.
Aquí están las extensiones del inodo.
Ahora hacemos conversiones de extensiones a LBA.
Y lo confirmamos.
Y volvemos a unir.
fuente