Ao responder a essa pergunta de U&L intitulada: Que comando eu uso para ver o bloco inicial e final de um arquivo no sistema de arquivos? , Tentei descobrir se era possível determinar o LBA de um arquivo usando seu inode.
Minha resposta determinou que eu poderia usar hdparm
como um método para encontrar LBAs:
$ 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
Mas fiquei curioso se havia algum método usando o inode de um arquivo para obter também os LBAs; sem usar hdparm
.
Eu acho que pode haver métodos alternativos escondidos nas ferramentas filefrag
, stat
, debugfs
, e tune2fs
, mas provocá-lo está me iludindo.
Alguém pode pensar em alternativas?
Aqui estão algumas das minhas pesquisas até agora que podem ser úteis para aqueles corajosos o suficiente para tentar responder a isso.
filefrag
Suspeito que você possa usar a ferramenta filefrag
para fazê-lo, especificamente usando os resultados de sua -e
troca, talvez executando vários cálculos para chegar lá com os quais não estou familiarizado.
saída de amostra
$ 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
Outro método potencial que eu suspeito que possa ter potencial é usar as informações de inode de um arquivo, diretamente ou através de uma matemática complexa pouco documentada nas interwebs.
Exemplo
Primeiro descobrimos o inode do arquivo. Podemos fazer isso usando o stat
comando ou ls -i
.
Estado
$ 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
Com as informações do inode em mãos, agora podemos abrir o sistema de arquivos em que este arquivo se encontra usando a ferramenta debugfs
,.
NOTA: Para determinar o sistema de arquivos um arquivo reside em que você pode usar o comando df <filename>
.
Agora, se executarmos debugfs
e executarmos o comando stat <inode #>
, podemos obter uma lista de extensões que contêm os dados desse arquivo.
$ 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
Agora, temos as informações de extensão acima, e é aqui que me perco e não sei como proceder.
Referências
fonte
filefrag -b512 -v ..
diz "Physical_offset: 211787168 .. 211795719", isso equivaleria aos LBAs? Isso parece aparecer com o mesmo arquivo comhdparm --fibmap
211787168..211795719. Se eu largar o-b512 -v
e usar o def. 1024 e tente mult. por 8, 26473396⋅8..26474464⋅8, recebo 211787168..211795712, que está perto, mas está um pouco fora. Eu estou pensando que o segundo valor deve ser (26474465⋅8) -1 = 211795719, não sei por que.Acontece que converter de extensões para LBAs é bastante simples quando você entende de onde vêm os números. A resposta de @StephaneChazelas foi crítica para obter esse entendimento.
Saída de depuração original
Usando o exemplo a seguir mencionado na pergunta.
Com as informações de extensão, podemos fazer os seguintes cálculos. Mas precisamos de mais uma informação. O tamanho do bloco do sistema de arquivos subjacente. Você pode usar este comando para obtê-lo.
Tamanho do bloco
Convertendo de extensões em LBAs
Portanto, a principal transformação a ser reconhecida aqui é que os LBAs estão em unidades de 512 bytes e o
debugfs
comando acima, que relatou o número de extensões, está relatando isso em blocos de 4096 bytes.Então, 4096/512 = 8. Portanto, precisamos multiplicar as extensões por 8 para convertê-las em valores LBA.
Portanto, a seguinte matemática nos dará nosso LBA inicial:
Então, qual é o nosso final LBA? Para conseguir isso, precisamos reconhecer que nosso inode se encaixa dentro de um único bloco para que sua extensão final seja a mesma que sua extensão inicial. Para calcular o LBA final, podemos usar esta equação.
Então, executando este cálculo:
Confirmando os resultados
Observando a
hdparm
saída original :Vemos que as coisas combinam.
Outro exemplo
Apenas para ter certeza de que estamos certos, aqui está um arquivo maior como segundo exemplo.
Aqui estão as extensões do inode.
Agora fazemos conversões de extensões para LBAs.
E nós confirmamos.
E nós combinamos novamente.
fonte