Como posso descobrir o intervalo de um arquivo de LBA usando seu inode?

2 respostas

1

Acontece que converter de extensões para LBAs é bastante simples, uma vez que você entende de onde os números estão vindo. A resposta do @StephaneChazelas foi fundamental para obter esse entendimento.

Saída original do debugfs

Usando o exemplo a seguir mencionado na pergunta.

$ 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$ sudo tune2fs -l /dev/mapper/fedora_greeneggs-home | grep "Block size"
Block size:               4096
0" (37) EXTENTS: (0):35304898

Com as informações de extensões, podemos fazer os seguintes cálculos. Mas precisamos de uma informação adicional. O tamanho do bloco do sistema de arquivos subjacente. Você pode usar este comando para obtê-lo.

Tamanho do bloco

$ calc -d
; 35304898 * 8
    282439184
; 

Convertendo de extensões para LBAs

Portanto, a transformação de chave para reconhecer aqui é que os LBAs estão em unidades de 512 bytes e o comando debugfs acima, que relatou o número de extensões, está relatando isso em 4096 blocos de bytes.

Então, 4096/512 = 8. Então, precisamos multiplicar as extensões por 8 para convertê-las em valores de LBA.

Assim, a seguinte matemática nos dará nosso LBA de início:

ending LBA = ( (extent + 1) * 8 ) - 1

Então, qual é o nosso final LBA? Para conseguir isso, precisamos reconhecer que nosso inode se encaixa dentro de um único bloco, de modo que sua extensão final é igual à sua extensão inicial. Para calcular o LBA final, podemos usar essa equação.

$ calc -d
; ( (35304898 + 1) * 8 ) - 1
    282439191

Então, realizando este cálculo:

 byte_offset  begin_LBA    end_LBA    sectors
           0  282439184  282439191          8

Confirmando os resultados

Olhando para a saída original hdparm :

$ ls -i util-linux-2.19.tar.bz2 
6559005 util-linux-2.19.tar.bz2

Nós vemos que as coisas combinam.

Outro exemplo

Apenas para ter certeza de que estamos certos, aqui está um arquivo maior como um segundo exemplo.

$ sudo debugfs -R "stat <6559005>" /dev/mapper/fedora_greeneggs-home
...
EXTENTS:
(0-1068):26473396-26474464

Aqui estão as extensões do inode.

$ calc -d
; 26473396*8
    211787168
; (26474464+1)*8 - 1
    211795719

Agora fazemos conversões de extensões para LBAs.

$ sudo hdparm --fibmap util-linux-2.19.tar.bz2 
...
 byte_offset  begin_LBA    end_LBA    sectors
           0  211787168  211795719       8552

E confirmamos.

$ 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$ sudo tune2fs -l /dev/mapper/fedora_greeneggs-home | grep "Block size"
Block size:               4096
0" (37) EXTENTS: (0):35304898

E nós combinamos novamente.

    
por 29.12.2013 / 19:06
4

filefrag e debugfs reportam offset expressos em número de blocos do sistema de arquivos.

Para obter o deslocamento no número de unidades de 512 bytes, você precisa multiplicar pelo tamanho do bloco em unidades de 512 bytes. No ext4 FS, o tamanho do bloco é geralmente 4k, então você precisa multiplicar por 8.

Com filefrag , você também pode usar a opção -b 512 para obter o deslocamento em unidades de 512 bytes.

Você pode obter o tamanho do bloco com o comando stats em debugfs ou com o atributo GNU:

stat -fc%s /mount/point

(ou qualquer arquivo nesse sistema de arquivos).

Note que hdparm é um utilitário de disco rígido, ele tentará fornecer o deslocamento dentro do disco em oposição ao dispositivo de bloco no qual o sistema de arquivos está montado (supondo que o dispositivo de bloco resida no disco de alguma forma). Só funciona dessa forma para partições (adicionando o conteúdo de /sys/class/block/the-block-device/start ao deslocamento real) e md dispositivos RAID 1, mas não outros tipos de dispositivos de bloco com backup em disco, como dispositivos de mapeamento de dispositivo, outros níveis de RAID, dispositivos dmraid, loop , nbd ... Observe também que as versões mais antigas do hdparm dependiam do ioctl do FIBMAP que é limitado em qual dispositivo de bloco ele pode ser usado, enquanto as versões mais novas usam o FIEMAP como filefrag .

Então, por exemplo, se você tiver um sistema de arquivos ext2 em /dev/sda1 .

# hdparm --fibmap /file/in/there
/file/in/there:
 filesystem blocksize 1024, begins at LBA 2048; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors
           0     109766     109767          2

Você pode obter esses dois setores (mas observe que o arquivo provavelmente usa apenas parte dele):

dd skip=109766 count=2 if=/dev/sda # not /dev/sda1

Enquanto com filefrag ou debugfs.

# filefrag -v /file/in/there
Filesystem type is: ef53
Filesystem cylinder groups is approximately 12
File size of /file/in/there is 87 (1 block, blocksize 1024)
 ext logical physical expected length flags
   0       0    53859               1 merged,eof

Você obtém a partir do dispositivo de bloqueio real:

dd bs=1024 skip=53859 count=1 if=/dev/sda1
    
por 28.12.2013 / 10:38