Que comando eu uso para ver o bloco inicial e final de um arquivo no sistema de arquivos?

7

Existe algum comando que produza os blocos inicial e final de qualquer arquivo?

    
por precise 27.12.2013 / 19:41

4 respostas

12

hdparm

Eu não tenho 100% de certeza de que é isso que você está procurando, mas acredito que você pode fazer isso usando o comando hdparm , especificamente com a opção --fibmap .

trecho

   --fibmap
          When  used,  this  must  be the only option given.  It requires a 
          file path as a parameter, and will print out a list of the block 
          extents (sector ranges) occupied by that file on disk.  Sector 
          numbers are  given as absolute LBA numbers, referenced from sector 
          0 of the physical device rather than from the partition or 
          filesystem.  This information can then be used for a variety of 
          purposes,  such  as examining the degree of fragmenation of larger 
          files, or determining appropriate sectors to deliberately corrupt 
          during fault-injection testing procedures.

          This option uses the new FIEMAP (file extent map) ioctl() when 
          available,  and  falls  back  to  the older  FIBMAP (file block 
          map) ioctl() otherwise.  Note that FIBMAP suffers from a 32-bit 
          block-number interface, and thus not work beyond 8TB or 16TB.  
          FIBMAP is also very slow, and  does  not  deal well  with  
          preallocated uncommitted extents in ext4/xfs filesystems, unless a 
          sync() is done before using this option.

Exemplo

Digamos que tenhamos um arquivo de amostra.

$ echo "this is a test file" > afile

Agora, quando executarmos hdparm .

$ 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

filefrag

Outro método interessante para descobrir o início & blocos finais é filefrag . Você precisará usar os switches apropriados para obter a saída desejada. Uma vantagem dessa ferramenta sobre hdparm é que qualquer usuário pode executá-la, portanto, não é necessário sudo . Você precisará usar a opção -b512 para que as saídas sejam exibidas em blocos de 512 bytes. Também precisamos informar filefrag para ser detalhado.

Exemplo

$ filefrag -b512 -v afile
Filesystem type is: ef53
File size of afile is 20 (8 block of 512 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..       7:  282439184.. 282439191:      8:             eof
afile: 1 extent found

debugfs

Um terceiro método para obter os LBAs de um arquivo é fazer uso de debugfs . Esse método exigirá um pouco de matemática, mas achei importante mostrar como é possível converter o valor de extensões relatado por debugfs para LBAs, para aqueles que podem ser curiosos.

Então, vamos começar com o inode do arquivo.

$ ls -i afile
6560281 afile

OBSERVAÇÃO: Também poderíamos usar o nome do arquivo em debugfs , mas para esta demonstração, usarei o inode.

Agora vamos obter as informações de stat via debugfs sobre nosso inode.

$ 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: 0x52bff8a1:a9f08020 -- Sun Dec 29 05:25:37 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
beginning LBA = (BEGIN EXTENT) * 8
ending LBA    = (((ENDING EXTENT) + 1) * 8) - 1
0" (37) EXTENTS: (0):35304898

As informações importantes estão na seção de extensões. Estes são, na verdade, blocos do sistema de arquivos que estão sendo usados por este inode. Nós só precisamos convertê-los para o LBA. Podemos fazer isso através da seguinte equação.

OBSERVAÇÃO: Assumindo que nosso sistema de arquivos usa tamanhos de blocos de 4k e que o hardware subjacente usa unidades de 512 bytes, precisamos multiplicar os exatos por 8.

beginning LBA = 35304898 * 8             = 282439184
ending LBA    = ((35304898 + 1) * 8) - 1 = 282439191

Exemplo

Portanto, no nosso exemplo, a extensão inicial e final é a mesma, já que o arquivo se encaixa em uma única extensão.

   --fibmap
          When  used,  this  must  be the only option given.  It requires a 
          file path as a parameter, and will print out a list of the block 
          extents (sector ranges) occupied by that file on disk.  Sector 
          numbers are  given as absolute LBA numbers, referenced from sector 
          0 of the physical device rather than from the partition or 
          filesystem.  This information can then be used for a variety of 
          purposes,  such  as examining the degree of fragmenation of larger 
          files, or determining appropriate sectors to deliberately corrupt 
          during fault-injection testing procedures.

          This option uses the new FIEMAP (file extent map) ioctl() when 
          available,  and  falls  back  to  the older  FIBMAP (file block 
          map) ioctl() otherwise.  Note that FIBMAP suffers from a 32-bit 
          block-number interface, and thus not work beyond 8TB or 16TB.  
          FIBMAP is also very slow, and  does  not  deal well  with  
          preallocated uncommitted extents in ext4/xfs filesystems, unless a 
          sync() is done before using this option.

Portanto, nossos LBAs são 282439184..282439191.

Referências

por 28.12.2013 / 00:41
4

Número do setor relativo ao dispositivo de bloco que contém o FS (não todo o disco)

(Observe que hdparm --fibmap é relativo a todo o disco, não à partição ou qualquer outro blockdev que contenha o FS. Ele também requer raiz.)

filefrag -e funciona bem e usa o genérico e eficiente FIEMAP ioctl , por isso deve funcionar em praticamente qualquer sistema de arquivos (incluindo o BTRFS, muitas vezes esquisito, mesmo para arquivos compactados com BTRFS). Ele retornará ao FIBMAP para sistemas de arquivos / kernels sem suporte ao FIEMAP.

$ filefrag xpsp3.vdi          # some old sparse disk image I had lying around
xpsp3.vdi: 110 extents found
$ filefrag -e xpsp3.vdi
Filesystem type is: 58465342
File size of xpsp3.vdi is 5368730112 (1310726 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..       5: 1322629241..1322629246:      6:            
   1:       13..      13: 1322620799..1322620799:      1: 1322629247:
   2:       15..      47: 1323459271..1323459303:     33: 1322620800:
...
 160:   899498..  915839: 1325792977..1325809318:  16342: 1325725438:
 161:  1307294.. 1307391: 1323938199..1323938296:     98: 1325809319: last
xpsp3.vdi: 110 extents found

somente XFS

Se você estiver usando o xfs, então xfs_bmap tem uma saída mais agradável: ele mostra onde há furos, enquanto filefrag tem a próxima extensão começando em um setor posterior. Ele usa blocos de 512B, não o que o blockystem de sistema de arquivos realmente é. (tipicamente 4k no Linux). Ele mostra a você qual grupo de alocação cada extensão está e como ela está alinhada nos limites da faixa RAID.

$ xfs_bmap -vvpl xpsp3.vdi   # the extra -v prints a key to the flags
xpsp3.vdi:
 EXT: FILE-OFFSET           BLOCK-RANGE              AG AG-OFFSET              TOTAL FLAGS
   0: [0..47]:              10581033928..10581033975 13 (83912..83959)            48 01111
   1: [48..103]:            hole                                                  56
   2: [104..111]:           10580966392..10580966399 13 (16376..16383)             8 01010
   3: [112..119]:           hole                                                   8
 ...
 322: [10458352..10459135]: 10591505592..10591506375 13 (10555576..10556359)     784 01111
 323: [10459136..10485807]: hole                                               26672
FLAG Values:   # this part is only here with -vv
    010000 Unwritten preallocated extent
    001000 Doesn't begin on stripe unit
    000100 Doesn't end   on stripe unit
    000010 Doesn't begin on stripe width
    000001 Doesn't end   on stripe width

-l é redundante quando -v é usado, mas, por algum motivo, sempre digito -vpl . -pl é uma saída mais compacta.

Tanto filefrag quanto xfs_bmap mostram extensões pré-alocadas.

$ fallocate --length $((1024*1024*8)) prealloced_file
$ filefrag -e prealloced_file
Filesystem type is: 58465342
File size of prealloced_file is 8388608 (2048 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..    2047: 1325371648..1325373695:   2048:             last,unwritten,eof
prealloced_file: 1 extent found
$ xfs_bmap -vvpl prealloced_file 
prealloced_file:
 EXT: FILE-OFFSET      BLOCK-RANGE              AG AG-OFFSET            TOTAL FLAGS
   0: [0..16383]:      10602973184..10602989567 13 (22023168..22039551) 16384 10010
 FLAG Values:
    010000 Unwritten preallocated extent
    001000 Doesn't begin on stripe unit
    000100 Doesn't end   on stripe unit
    000010 Doesn't begin on stripe width
    000001 Doesn't end   on stripe width
$ dd if=/dev/zero of=prealloced_file conv=notrunc bs=4k count=10 seek=10000
40960 bytes (41 kB) copied, 0.000335111 s, 122 MB/s
$ xfs_bmap -vpl prealloced_file                                           
prealloced_file:
 EXT: FILE-OFFSET      BLOCK-RANGE              AG AG-OFFSET            TOTAL FLAGS
   0: [0..16383]:      10602973184..10602989567 13 (22023168..22039551) 16384 10010
   1: [16384..79999]:  hole                                             63616
   2: [80000..80895]:  10603013120..10603014015 13 (22063104..22063999)   896 00111
 # oops, wrote past EOF and extended the file, instead of in the middle of the preallocated extent
$ dd if=/dev/zero of=prealloced_file conv=notrunc bs=4k count=10 seek=100
40960 bytes (41 kB) copied, 0.000212986 s, 192 MB/s
$ xfs_bmap -vpl prealloced_file 
prealloced_file:
 EXT: FILE-OFFSET      BLOCK-RANGE              AG AG-OFFSET            TOTAL FLAGS
   0: [0..16383]:      10602973184..10602989567 13 (22023168..22039551) 16384 10010
   1: [16384..79999]:  hole                                             63616
   2: [80000..80895]:  10603013120..10603014015 13 (22063104..22063999)   896 00111
# If you check *right away*, XFS's delayed allocation hasn't happened yet.
# FIEMAP on xfs only reflects allocations, which lag behind completed writes.  fsync first if you need it, IIRC.
$ xfs_bmap -vpl prealloced_file 
prealloced_file:
 EXT: FILE-OFFSET      BLOCK-RANGE              AG AG-OFFSET            TOTAL FLAGS
   0: [0..799]:        10602973184..10602973983 13 (22023168..22023967)   800 10111
   1: [800..879]:      10602973984..10602974063 13 (22023968..22024047)    80 01111
   2: [880..16383]:    10602974064..10602989567 13 (22024048..22039551) 15504 11010
   3: [16384..79999]:  hole                                             63616
   4: [80000..80895]:  10603013120..10603014015 13 (22063104..22063999)   896 00111
$ filefrag -e prealloced_file 
Filesystem type is: 58465342
File size of prealloced_file is 41000960 (10010 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..      99: 1325371648..1325371747:    100:             unwritten
   1:      100..     109: 1325371748..1325371757:     10:            
   2:      110..    2047: 1325371758..1325373695:   1938:             unwritten
   3:    10000..   10111: 1325376640..1325376751:    112: 1325373696: last,eof
prealloced_file: 2 extents found

hdparm --fibmap só é útil se você quiser um número de setor relativo a todo o disco rígido , não dentro da partição em que o sistema de arquivos está. Não funciona em cima de software RAID (ou presumivelmente qualquer outra coisa entre o sistema de arquivos e um disco rígido). Também requer raiz. Apesar do nome da opção, ele realmente usa FIEMAP quando disponível (o ioctl de mapa de extensão mais recente, não o ioctl de mapa de bloco lento antigo).

# hdparm --fibmap ..../xpsp3.vdi
Unable to determine start offset LBA for device, aborting.
    
por 29.02.2016 / 05:57
0

Então, para um determinado arquivo, você quer saber qual bloco de disco os números contêm o início e o fim desse arquivo.

debugfs (8) parece promissor para FSs ext2 / 3/4

stat (1), ls -i, lsof (8) fornecem o número do inode, mas não muito mais sobre os blocos de disco.

head / tail --bytes = 1024 é útil para conteúdo de arquivo, mas não blocos de disco.

dd (1) será o que você deseja inspecionar o bloco conteúdo - fique atento à diferença entre o seek = e skip = parameters, e evite de = / dev / ... a menos que você realmente queira que o arquivo de saída seja um dispositivo.

    
por 27.12.2013 / 20:49
0

hdparm --fibmap listará os blocos que um arquivo ocupa. Note que eles podem não ser contíguos, então "início e fim" não faz sentido.

    
por 27.12.2013 / 22:19