ฉันใช้คำสั่งอะไรเพื่อดูจุดเริ่มต้นและจุดสิ้นสุดบล็อกของไฟล์ในระบบไฟล์


10

มีคำสั่งใดที่จะส่งออกบล็อกจุดเริ่มต้นและจุดสิ้นสุดของไฟล์ใด ๆ ?


1
ประเภทของระบบไฟล์: ext2,3,4; btrfs; XFS; zfs ฯลฯ ...
BeowulfNode42

@ BeowulfNode42: ext4, ntfs, fat32 เป็นสิ่งที่ฉันมักจะจัดการกับ ... ดังนั้นยิ่งสำหรับทั้งสาม ...
แม่นยำ

คำถามควรได้รับการปรับปรุง (แม่นยำยิ่งขึ้น): คำตอบแรกของฉันอาจเป็นโปรแกรมที่เปิดไฟล์อ่านบล็อกแรกจากนั้นจึงไปที่บล็อกสุดท้ายและอ่านมันด้วย แล้ว "เอาท์พุท" ของบล็อกคืออะไร? เนื้อหาของบล็อก, โลจิคัลแอดเดรสของบล็อก (ภายในไฟล์, ภายในระบบไฟล์, ภายในพาร์ติชั่น, หรือในอุปกรณ์บล็อก) หรือที่อยู่จริงของบล็อก (น่าสนใจถ้าดิสก์เป็นส่วนหนึ่งของ RAID หรือ LVM บางส่วน) คำตอบดูเหมือนดีกว่าคำถาม
U. Windl

คำตอบ:


16

hdparm

ฉันไม่แน่ใจ 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

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

debugfs

วิธีที่สามสำหรับการ LBA debugfsของไฟล์ที่จะทำให้การใช้งานของ วิธีนี้จะต้องใช้คณิตศาสตร์เพียงเล็กน้อย แต่ฉันคิดว่ามันสำคัญที่จะต้องแสดงให้เห็นว่าเราสามารถแปลงค่าจากขอบเขตที่รายงานโดยdebugfsเป็น LBA สำหรับผู้ที่อาจอยากรู้อยากเห็น

ดังนั้นเรามาเริ่มด้วย inode ของไฟล์กัน

$ ls -i afile
6560281 afile

หมายเหตุ:เราสามารถใช้ชื่อไฟล์ภายในdebugfsแต่สำหรับการสาธิตนี้ฉันจะใช้ไอโหนดแทน

ตอนนี้เรามารับstatข้อมูลdebugfsเกี่ยวกับไอโหนดของเรา

$ 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

ข้อมูลที่สำคัญอยู่ในส่วนของขอบเขต แท้จริงแล้วเป็นบล็อกระบบไฟล์ที่ใช้โดย inode นี้ เราแค่ต้องแปลงมันเป็น 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

อ้างอิง


เหล่านี้มีความเชื่อมโยงบางอย่าง ... ขอบคุณสำหรับคำตอบและการเชื่อมโยง ...
แม่นยำ

2
@hash - เป็นส่วนที่เหลือของฉันที่พยายามหาวิธีอื่นอีก 2 วิธีในการพิจารณา LBA 8-) ตอนนี้ฉันเขียนมันเป็น Q ของตัวเองในเว็บไซต์
slm

@hash - filefragฉันได้เพิ่มเทคนิคอื่นโดยใช้
slm

@hash - debugfsฉันได้เพิ่มเทคนิคอื่นโดยใช้
slm

ฉันพยายามfilefragกับ blocksizes ที่มีอยู่ของ 1024 และ 2048 .. debugfsด้วยextentsไฟล์ขนาดใหญ่: 0 - 12187 .. ฉันจะใช้เวลาของฉันและเข้าใจ .. นั่นเป็นความช่วยเหลือที่ดีขอบคุณ ...
แม่นยำ

4

หมายเลขเซ็กเตอร์ที่สัมพันธ์กับอุปกรณ์บล็อกที่ถือ FS (ไม่ใช่ดิสก์ทั้งหมด)

(โปรดทราบว่าhdparm --fibmapเกี่ยวข้องกับดิสก์ทั้งหมดไม่ใช่พาร์ทิชันหรือสิ่งอื่นใดที่ blockdev เก็บ FS นอกจากนี้ยังต้องใช้รูทด้วย)

filefrag -eทำงานได้ดีและใช้ioctl ทั่วไปและมีประสิทธิภาพFIEMAPดังนั้นจึงควรทำงานกับระบบไฟล์ใด ๆ (รวมถึง BTRFS ที่มักจะแปลกแม้กระทั่งไฟล์บีบอัด BTRFS) มันจะย้อนกลับไปที่ FIBMAP สำหรับระบบไฟล์ / เมล็ดโดยไม่รองรับ FIEMAP

$ 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 แสดงว่าxfs_bmapมีเอาต์พุตที่ดีกว่า: จะแสดงตำแหน่งที่มีรูขณะfilefragที่ขอบเขตถัดไปเริ่มต้นที่เซกเตอร์ในภายหลัง มันใช้บล็อก 512B ไม่ใช่สิ่งที่ระบบไฟล์บล็อกเป็นจริง (โดยทั่วไปคือ 4k บน Linux) มันแสดงให้คุณเห็นว่ากลุ่มการจัดสรรแต่ละขอบเขตนั้นอยู่ในลักษณะใดและมีการจัดแนวอย่างไรในขอบเขตแถบ 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 (หรืออาจเป็นอย่างอื่นระหว่างระบบไฟล์และฮาร์ดไดรฟ์) นอกจากนี้ยังต้องใช้ราก แม้จะมีชื่อของตัวเลือก แต่ก็ใช้งานได้จริงFIEMAPเมื่อพร้อมใช้งาน (ioctl แผนที่รุ่นใหม่กว่าไม่ใช่ของบล็อกแผนที่ช้า ioctl)

# hdparm --fibmap ..../xpsp3.vdi
Unable to determine start offset LBA for device, aborting.

0

ดังนั้นสำหรับไฟล์ที่กำหนดคุณต้องการทราบว่าหมายเลขบล็อกดิสก์ใดที่มีจุดเริ่มต้นและจุดสิ้นสุดของไฟล์นั้น

debugfs (8) ดูมีแนวโน้มสำหรับ ext2 / 3/4 FSes

stat (1), ls -i, lsof (8) ให้หมายเลขไอโหนด แต่ไม่มากนักเกี่ยวกับดิสก์บล็อก

head / tail --bytes = 1024 มีประโยชน์สำหรับเนื้อหาไฟล์ แต่ไม่ใช่บล็อกดิสก์

DD (1) จะเป็นสิ่งที่คุณต้องการในการตรวจสอบเนื้อหาบล็อก - จะแจ้งเตือนไปยังความแตกต่างระหว่างแสวงหา = และข้าม = พารามิเตอร์และหลีกเลี่ยงของ = / dev / ... ถ้าคุณจริงๆต้องการไฟล์ที่ส่งออกจะต้องมีอุปกรณ์ .


ไม่นั่นไม่ใช่สิ่งที่ฉันหมายถึง ... คือหมายเลขบล็อกของดิสก์ที่ฉันกังวล
แม่นยำ

0

hdparm --fibmapจะแสดงรายการบล็อกไฟล์ที่ใช้งาน โปรดทราบว่าอาจไม่ต่อเนื่องกันดังนั้น "เริ่มต้นและสิ้นสุด" จึงไม่สมเหตุสมผล


--fibmapผมคิดว่าสวิทช์ที่คุณกำลังหมายถึงการมี นอกจากนี้คุณต้องระบุชื่อไฟล์ด้วย / ตัวอย่าง: hdparm --fibmap afile.
slm

@slm, oops, ใช่, พิมพ์ผิด ... และฉันคิดว่ามันชัดเจนว่าคุณต้องตั้งชื่อไฟล์ที่เป็นปัญหา
psusi

ไม่ใช่ฉันจนกว่าฉันจะพยายามเรียกใช้ จนถึงวันนี้ประสบการณ์ที่ผ่านมาของฉันกับhdparmอยู่ในระดับไดรฟ์ทั้งหมดไม่เคยใช้มันสำหรับไฟล์มาก่อน
slm
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.