파일 시스템에서 파일의 시작 및 끝 블록을 보려면 어떤 명령을 사용합니까?


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있지만이 데모에서는 대신 inode를 사용하겠습니다.

이제 inode에 대한 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 바이트 단위를 사용한다고 가정하면 Exent에 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-그들은 LBA를 결정하기위한 두 가지 다른 방법을 찾으려고 노력하는 저의 잔재입니다. 8-). 나는 지금 사이트에서 내 자신의 Q로 작성하고 있습니다.
slm

@hash-을 사용하여 다른 기술을 추가했습니다 filefrag.
slm

@hash-을 사용하여 다른 기술을 추가했습니다 debugfs.
slm

내가 시도 filefrag... 1024 2048 사용할 수 blocksizes으로 debugfs큰 파일로 12187-0 : 확장 .. 난 큰 도움이, 감사 ...의 그 .. 내 시간을 가지고 이해하게 될 것입니다
정확한

4

FS를 보유한 블록 장치에 대한 섹터 번호 (전체 디스크 아님)

( hdparm --fibmap파티션이나 다른 blockdev가 FS를 보유하는 것이 아니라 전체 디스크에 상대적입니다. 루트도 필요합니다.)

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

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

-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

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 FS에 유망한 것으로 보입니다.

stat (1), ls -i, lsof (8)는 inode 번호를 제공하지만 디스크 블록에 대해서는 그다지 많지 않습니다.

head / tail --bytes = 1024는 파일 내용에는 유용하지만 디스크 블록에는 유용하지 않습니다.

dd (1)은 블록 내용을 검사 하려는 것입니다. 실제로 출력 파일을 장치로 사용 하지 않으려는 경우 seek =와 skip = 매개 변수의 차이점에주의하고 of = / dev / ...를 피 하십시오. .


아니, 그건 내가 의미 한 바가 아니야. 내가 관심있는 디스크의 블록 번호.
정확한

0

hdparm --fibmap파일이 차지하는 블록을 나열합니다. 연속되지 않을 수도 있으므로 "시작 및 종료"는 의미가 없습니다.


당신이 말하는 스위치는 --fibmap입니다. 또한 파일 이름을 지정해야합니다. 예 : hdparm --fibmap afile.
slm

@slm, oops, yes, typo ... 그리고 문제의 파일 이름을 지정해야한다는 것이 분명하다고 생각했습니다.
psusi

나는 그것을 실행하려고 할 때까지 나에게 없었다. 오늘까지의 과거 경험 hdparm은 전체 드라이브 수준에 있었기 때문에 이전에는 파일에 사용하지 않았습니다.
slm
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.