我使用什么命令来查看文件系统中文件的开始和结束块?

pre*_*ise 13 command-line filesystems files

是否有任何命令可以输出文件系统中任何文件的开始和结束块号?

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。

参考


Pet*_*des 6

相对于保存 FS 的块设备(不是整个磁盘)的扇区号

(请注意,这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,那么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是更紧凑的输出。


双方filefragxfs_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)