是否有任何命令可以输出任何文件的开始和结束块?
是否有任何命令可以输出任何文件的开始和结束块?
Answers:
我不是100%确定这是您要查找的内容,但我相信您可以使用命令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.
说我们有一个样本文件。
$ echo "this is a test file" > afile
现在,当我们跑步时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
。不过,您需要使用适当的开关才能获得所需的输出。该工具的一个好处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
获取文件的LBA的第三种方法是使用debugfs
。这种方法需要一点数学运算,但是我认为debugfs
,对于那些可能会感到好奇的人来说,展示如何将其从报告的范围值转换为LBA 至关重要。
因此,让我们从文件的inode开始。
$ ls -i afile
6560281 afile
注意:我们也可以在其中使用文件名,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
重要信息在范围部分中。这些实际上是此索引节点正在使用的文件系统块。我们只需要将它们转换为LBA。我们可以通过以下方程式实现。
注意:假设我们的文件系统使用4k块大小,并且底层硬件使用512字节单位,我们需要将exents乘以8。
beginning LBA = (BEGIN EXTENT) * 8
ending LBA = (((ENDING EXTENT) + 1) * 8) - 1
因此,在我们的示例中,我们的开始和结束范围是相同的,因为我们的文件适合单个范围。
beginning LBA = 35304898 * 8 = 282439184
ending LBA = ((35304898 + 1) * 8) - 1 = 282439191
因此,我们的LBA为282439184..282439191。
filefrag
。
debugfs
。
filefrag
使用1024和2048的可用块大小。debugfs
具有较大的文件范围:0-12187 ..我会花点时间来理解..这是一个很大的帮助,谢谢...
(请注意,这hdparm --fibmap
是相对于整个磁盘,而不是分区或其他任何包含FS的blockdev。它也需要root用户。)
filefrag -e
可以很好地运行,并使用通用且高效的FIEMAP
ioctl,因此它几乎可以在任何文件系统上运行(包括经常使用的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
如果您使用的是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
-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
hdparm --fibmap
如果你想有一个扇区号是唯一有用的相对于整个硬盘,不分区中的文件系统上。它不能在软件RAID(或文件系统和硬盘驱动器之间的任何其他设备)上运行。它也需要root。尽管有该选项的名称,但实际上它会FIEMAP
在可用时使用(更新的扩展区映射ioctl,而不是旧的慢速块映射ioctl)。
# hdparm --fibmap ..../xpsp3.vdi
Unable to determine start offset LBA for device, aborting.
hdparm --fibmap
将列出文件占用的块。请注意,它们可能不是连续的,因此“开始和结束”没有意义。
--fibmap
。另外,您需要指定一个文件名w /它。范例:hdparm --fibmap afile
。
hdparm
都涉及整个驱动器级别,以前从未将其用于文件。