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:s0beginning 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
- Encontrando quais setores do disco rígido ocupam um arquivo
- Identificação do arquivo associado ao setor de disco ilegível
- HOWTO de bloqueio inválido para smartmontools
- C5170 Notas de aula - Representação interna de arquivos - O Unix Sistema de arquivos
- Endereçamento de blocos lógicos
- Layout de disco Ext4