slm*_*slm 18
我不是 100% 确定这就是你要找的,但我相信你可以使用 command 来做到这一点hdparm,特别是使用它的--fibmap开关。
摘抄
--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.
Run Code Online (Sandbox Code Playgroud)
假设我们有一个示例文件。
$ echo "this is a test file" > afile
Run Code Online (Sandbox Code Playgroud)
现在当我们运行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
Run Code Online (Sandbox Code Playgroud)
另一种找出文件开始和结束块的好方法是filefrag. 不过,您需要使用适当的开关来获得所需的输出。这个工具的一个好处hdparm是任何用户都可以运行它,所以sudo不需要。您需要使用该-b512开关,以便以 512 字节的块显示输出。此外,我们需要告诉filefrag是冗长的。
$ 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
Run Code Online (Sandbox Code Playgroud)
获取文件 LBA 的第三种方法是使用debugfs. 这种方法需要一点数学知识,但我认为重要的是展示如何从debugfsLBA报告的范围值转换,对于那些可能好奇的人。
所以让我们从文件的 inode 开始。
$ ls -i afile
6560281 afile
Run Code Online (Sandbox Code Playgroud)
注意:我们也可以在其中使用文件名,debugfs但在本演示中,我将使用 inode。
现在让我们stat通过debugfs有关我们的 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\000" (37)
EXTENTS:
(0):35304898
Run Code Online (Sandbox Code Playgroud)
重要信息位于范围部分。这些实际上是此 inode 正在使用的文件系统块。我们只需要将它们转换为 LBA。我们可以通过以下等式来做到这一点。
注意:假设我们的文件系统使用 4k 块大小并且底层硬件使用 512 字节单元,我们需要将扩展区乘以 8。
beginning LBA = (BEGIN EXTENT) * 8
ending LBA = (((ENDING EXTENT) + 1) * 8) - 1
Run Code Online (Sandbox Code Playgroud)
所以在我们的例子中,我们的开始和结束范围是相同的,因为我们的文件适合单个范围。
beginning LBA = 35304898 * 8 = 282439184
ending LBA = ((35304898 + 1) * 8) - 1 = 282439191
Run Code Online (Sandbox Code Playgroud)
所以我们的 LBA 是 282439184..282439191。
(请注意,这hdparm --fibmap是相对于整个磁盘,而不是分区或其他任何包含 FS 的 blockdev。它还需要 root。)
filefrag -e运行良好,并使用通用且高效的FIEMAPioctl,因此它几乎可以在任何文件系统上运行(包括通常很奇怪的 BTRFS,甚至对于 BTRFS 压缩文件)。对于没有 FIEMAP 支持的文件系统/内核,它将回退到 FIBMAP。
$ 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
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 xfs,那么xfs_bmap会有更好的输出:它会向您显示有空洞的位置,而filefrag下一个范围从较晚的扇区开始。它使用 512B 块,而不是实际的文件系统块大小。(Linux 上通常为 4k)。它显示了每个扩展区在哪个分配组中,以及它如何在 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
Run Code Online (Sandbox Code Playgroud)
-l-v使用时是多余的,但出于某种原因,我总是输入-vpl. -pl是更紧凑的输出。
filefrag并xfs_bmap告诉你预分配的程度。$ 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
Run Code Online (Sandbox Code Playgroud)
hdparm --fibmap仅当您想要相对于整个硬盘驱动器的扇区号时才有用,而不是在文件系统所在的分区内。它不能在软件 RAID(或者文件系统和硬盘驱动器之间的任何其他东西)之上工作。它还需要root。尽管选项的名称,它实际上FIEMAP在可用时使用(较新的extent-map ioctl,而不是旧的slow block-map ioctl)。
# hdparm --fibmap ..../xpsp3.vdi
Unable to determine start offset LBA for device, aborting.
Run Code Online (Sandbox Code Playgroud)