ファイルの開始ブロックと終了ブロックを出力するコマンドはありますか?
これがあなたが探しているものかどうかは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
ファイルの最初と最後のブロックを見つけるもう1つの方法は、filefrag
です。ただし、目的の出力を得るには、適切なスイッチを使用する必要があります。このツールのhdparm
に対する利点の1つは、すべてのユーザーがこのツールを実行できるため、Sudo
が必要ないことです。出力が512バイトブロックで表示されるように、-b512
スイッチを使用する必要があります。また、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を取得する3番目の方法は、debugfs
を使用することです。この方法では少し計算が必要になりますが、debugfs
によって報告されたエクステント値からLBAに変換する方法を示すことが重要であると考えました。
それでは、ファイルのiノードから始めましょう。
$ ls -i afile
6560281 afile
注:debugfs
内でファイル名を使用することもできますが、このデモでは代わりにiノードを使用します。
次に、stat
を介してdebugfs
を介してiノードに関する情報を取得します。
$ 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
重要な情報は、エクステントセクションにあります。これらは実際には、このiノードによって使用されているファイルシステムブロックです。それらをLBAに変換する必要があるだけです。これは次の式で実行できます。
注:ファイルシステムが4kのブロックサイズを使用し、基盤となるハードウェアが512バイト単位を使用すると仮定すると、範囲に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です。
(hdparm --fibmap
はパーティション全体やFSを保持する他のblockdevではなく、ディスク全体を基準にしています。ルートも必要です。)
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.
したがって、特定のファイルについて、そのファイルの開始と終了が含まれているディスクブロック番号を知りたいとします。
debugfs(8)はext2/3/4 FSで有望に見える
stat(1)、ls -i、lsof(8)は、iノード番号を提供しますが、ディスクブロックに関するその他の情報は提供しません。
head/tail --bytes = 1024は、ファイルコンテンツには役立ちますが、ディスクブロックには役立ちません。
dd(1)はブロックの内容を検査したいものになります-seek =パラメータとskip =パラメータの違いに注意し、reallyが必要でない限りof =/dev/...は避けてくださいデバイスとなる出力ファイル.
hdparm --fibmap
は、ファイルが占めるブロックをリストします。それらは隣接していない可能性があるため、「開始と終了」は意味をなさないことに注意してください。