Mit welchem ​​Befehl kann ich den Start- und Endblock einer Datei im Dateisystem anzeigen?

10

Gibt es einen Befehl, der die Anfangs- und Endblöcke einer Datei ausgibt?

präzise
quelle
1
welcher Dateisystemtyp: ext2,3,4; btrfs; xfs; zfs, etc ...?
BeowulfNode42
@ BeowulfNode42: ext4, ntfs, fat32 sind diejenigen, mit denen ich mich oft beschäftige ... also am besten für diese drei ...
präzise
Die Frage sollte verbessert werden (genauer gesagt): Meine erste Antwort wäre ein Programm gewesen, das die Datei öffnet, den ersten Block liest, dann zum letzten Block sucht und auch diesen liest. Was ist also "Ausgabe" eines Blocks? Der Inhalt des Blocks, die logische Adresse des Blocks (innerhalb der Datei, innerhalb des Dateisystems, innerhalb der Partition oder innerhalb des Blockgeräts) oder die physische Adresse des Blocks (wird interessant, wenn die Festplatte Teil eines RAID oder LVM ist). Die Antworten scheinen viel besser als die Frage.
U. Windl

Antworten:

16

hdparm

Ich bin mir nicht hundertprozentig sicher, wonach Sie suchen, aber ich glaube, Sie können dies mit dem Befehl tun hdparm, insbesondere mit seinem --fibmapSchalter.

Auszug

   --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.

Beispiel

Angenommen, wir haben eine Beispieldatei.

$ echo "this is a test file" > afile

Jetzt wenn wir rennen 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

Eine andere gute Methode, um die Anfangs- und Endblöcke einer Datei herauszufinden, ist filefrag. Sie müssen jedoch geeignete Schalter verwenden, um die gewünschte Ausgabe zu erhalten. Ein Vorteil dieses Tools hdparmist, dass jeder Benutzer es ausführen kann, sodass kein Tool sudoerforderlich ist. Sie müssen den -b512Schalter verwenden, damit die Ausgänge in 512-Byte-Blöcken angezeigt werden. Wir müssen auch sagen filefrag, dass wir ausführlich sind.

Beispiel

$ 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

Eine dritte Methode zum Abrufen der LBAs einer Datei ist die Verwendung von debugfs. Diese Methode erfordert ein wenig Mathematik, aber ich fand es wichtig zu zeigen, wie man den von debugfsLBAs gemeldeten Extents-Wert für diejenigen konvertieren kann, die neugierig sein könnten.

Beginnen wir also mit dem Inode der Datei.

$ ls -i afile
6560281 afile

HINWEIS: Wir könnten auch den Dateinamen verwenden, debugfsaber für diese Demonstration werde ich stattdessen den Inode verwenden.

Lassen Sie uns nun die statInformationen über debugfsunsere Inode erhalten.

$ 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

Die wichtigen Informationen finden Sie im Abschnitt Extents. Dies sind tatsächlich Dateisystemblöcke, die von diesem Inode verwendet werden. Wir müssen sie nur in LBA konvertieren. Wir können dies durch die folgende Gleichung tun.

ANMERKUNG: Angenommen, unser Dateisystem verwendet 4k-Blockgrößen und die zugrunde liegende Hardware 512-Byte-Einheiten, müssen wir die Exents mit 8 multiplizieren.

beginning LBA = (BEGIN EXTENT) * 8
ending LBA    = (((ENDING EXTENT) + 1) * 8) - 1

Beispiel

In unserem Beispiel ist unser Anfangs- und Endbereich derselbe, da unsere Datei in einen einzelnen Bereich passt.

beginning LBA = 35304898 * 8             = 282439184
ending LBA    = ((35304898 + 1) * 8) - 1 = 282439191

Unsere LBAs sind also 282439184..282439191.

Verweise

slm
quelle
Dies sind einige Links ... danke für die Antwort und Links ...
genau
2
@hash - sie sind die Überreste von mir, die versuchen, zwei andere Methoden zur Bestimmung der LBAs zu finden. 8-). Ich schreibe es jetzt als mein eigenes Q auf der Seite.
slm
@hash - Ich habe eine andere Technik hinzugefügt filefrag.
slm
@hash - Ich habe eine andere Technik hinzugefügt debugfs.
slm
Ich habe versucht , filefragmit dem verfügbaren Blockgrößen von 1024 und 2048 .. debugfsmit einer größeren Datei Ausdehnungen: 0-12187 .. Ich werde meine Zeit in Anspruch nehmen und verstehen .. das eine große Hilfe ist, dank ...
präzise
4

Sektornummer relativ zum Blockgerät mit dem FS (nicht ganze Platte)

(Beachten Sie, dass dies hdparm --fibmaprelativ zur gesamten Festplatte ist, nicht zur Partition oder zu einem anderen Block, der den FS enthält. Außerdem ist root erforderlich.)

filefrag -efunktioniert gut und verwendet das generische und effiziente FIEMAPioctl , so dass es auf so ziemlich jedem Dateisystem funktionieren sollte (einschließlich des oft seltsamen BTRFS, selbst für BTRFS-komprimierte Dateien). Für Dateisysteme / Kernel ohne FIEMAP-Unterstützung wird auf FIBMAP zurückgegriffen.

$ 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

Nur XFS

Wenn Sie xfs verwenden, xfs_bmaphat es eine schönere Ausgabe: Es zeigt Ihnen, wo es Löcher gibt, während filefragdas nächste Ausmaß nur bei einem späteren Sektor beginnt. Es werden 512B-Blöcke verwendet, unabhängig von der tatsächlichen Blockgröße des Dateisystems. (normalerweise 4k unter Linux). Es zeigt Ihnen, in welcher Zuordnungsgruppe sich die einzelnen Bereiche befinden und wie sie an den RAID-Streifengrenzen ausgerichtet sind.

$ 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

-list redundant, wenn -ves verwendet wird, aber aus irgendeinem Grund tippe ich immer -vpl. -plist kompakter Ausgabe.


Beides filefragund xfs_bmapzeigen Ihnen vorab zugewiesene Ausmaße.

$ 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 --fibmapist nur nützlich, wenn Sie eine Sektornummer relativ zur gesamten Festplatte wünschen , nicht innerhalb der Partition, auf der sich das Dateisystem befindet. Es funktioniert nicht über Software-RAID (oder vermutlich irgendetwas anderes zwischen dem Dateisystem und einer Festplatte). Es erfordert auch root. Trotz des Namens der Option wird sie tatsächlich verwendet, FIEMAPwenn sie verfügbar ist (das neuere Extent-Map-Ioctl, nicht das alte Slow-Block-Map-Ioctl).

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

Für eine bestimmte Datei möchten Sie also wissen, welche Plattenblocknummern den Anfang und das Ende dieser Datei enthalten.

debugfs (8) sieht für ext2 / 3/4 FSes vielversprechend aus

stat (1), ls -i, lsof (8) geben die Inode-Nummer an, aber sonst nicht viel über Plattenblöcke.

head / tail --bytes = 1024 ist nützlich für Dateiinhalte, jedoch nicht für Festplattenblöcke.

Mit dd (1) möchten Sie den Blockinhalt überprüfen. Achten Sie auf den Unterschied zwischen den Parametern seek = und skip = und vermeiden Sie = / dev / ..., es sei denn, Sie möchten wirklich, dass die Ausgabedatei ein Gerät ist .

D McKeon
quelle
Nein, das habe ich nicht gemeint ... es sind die Blocknummern der Festplatte, um die es mir geht.
genaue
0

hdparm --fibmaplistet die Blöcke auf, die eine Datei belegt. Beachten Sie, dass sie möglicherweise nicht zusammenhängend sind, sodass "Start und Ende" keinen Sinn ergibt.

psusi
quelle
Ich denke, der Schalter, auf den Sie sich beziehen, ist --fibmap. Außerdem müssen Sie einen Dateinamen angeben. Beispiel : hdparm --fibmap afile.
slm
@slm, oops, ja, Tippfehler ... und ich dachte, es wäre offensichtlich, dass Sie die betreffende Datei benennen müssen.
Psusi
Es war nicht für mich, bis ich versuchte, es auszuführen. Bis heute war meine bisherige Erfahrung mit hdparmeinem ganzen Laufwerk, das ich noch nie für Dateien verwendet habe.
slm