Detaillierte Informationen zu Dateien mit geringer Dichte unter Linux

11

Ich habe eine spärliche Datei, in der nur einige Blöcke zugeordnet sind:

~% du -h --apparent-size example
100K    example
~% du -h example
52K     example

Ich möchte wissen, welche Blöcke der Datei tatsächlich zugeordnet sind. Gibt es einen Systemaufruf oder eine Kernel-Schnittstelle, über die eine Liste der Zuordnungen oder der Dateilöcher abgerufen werden kann?

Das einfache Suchen nach einer ausreichend langen Folge von Nullen (der von GNU cp, rsync usw. verwendete Ansatz) funktioniert nicht richtig:

~% cp example example1  
~% du -h example1 
32K     example1

Es wurden andere Folgen von Nullen erkannt, die tatsächlich zugewiesen wurden.

Juliano
quelle

Antworten:

7

Es gibt eine ähnliche Frage zu SO . Die aktuell akzeptierte Antwort von @ephemient schlägt vor, einen Anruf zu verwenden ioctl, fiemapder in dokumentiert ist linux/Documentation/filesystems/fiemap.txt. Zitat aus dieser Datei:

Das fiemap ioctl ist eine effiziente Methode für den Benutzerbereich, um Dateibereichszuordnungen abzurufen. Anstelle einer blockweisen Zuordnung (z. B. bmap) gibt fiemap eine Liste der Extents zurück.

Klingt so, als ob dies die Art von Informationen ist, nach denen Sie suchen. Die Unterstützung durch Dateisysteme ist wieder optional:

Dateisysteme, die fiemap unterstützen möchten, müssen einen ->fiemap Rückruf in ihrer inode_operationsStruktur implementieren .

Unterstützung für die SEEK_DATAund SEEK_HOLEArgumente zu lseekIhnen von Solaris erwähnt wurde in Linux 3.1 nach hinzugefügt der Manpage , so dass Sie das auch nutzen könnten. Das fiemap ioctlscheint älter zu sein, daher ist es derzeit möglicherweise für verschiedene Linux-Versionen portabler, wohingegen lseekes für Betriebssysteme möglicherweise portabler ist, wenn Solaris dasselbe hat.

MvG
quelle
2
Sie können mit der diese FIEMAP Informationen erhalten , von--fibmap der hdparmNützlichkeit. Siehe das Handbuch.
Totor
2

Es gibt eine Sammlung von Python-Programmen namens sparseutils , die verwenden SEEK_HOLEund SEEK_DATAbestimmen, welche Abschnitte der Datei als Löcher dargestellt werden und welche Daten sind. Die Verwendung ist recht einfach. mksparsekann verwendet werden, um eine Sparse-Datei gemäß einem bestimmten Layout zu generieren.

 $ echo hole,data,hole | mksparse --hole-size 4096 --data-size 4096 example
 $ du -sh example
 4.0K   example

Das sparsemapProgramm kann verwendet werden, um das Layout auf stdout zu drucken:

 $ sparsemap example
 HOLE 4096
 DATA 4096
 HOLE 4096
Richard
quelle
1

Das hängt vom Dateisystem ab. Ich glaube nicht, dass dies ein Aufruf ist, weshalb viele Tools das Kopieren von Dateien mit geringer Dichte möglicherweise nicht gut handhaben. Die GNU-Toolkette sucht nach großen Nullenblöcken, um nicht verwendete zugewiesene Blöcke zu entfernen. Viele Kopiertools konvertieren eine Datei mit geringer Dichte in eine Datei, der alle Blöcke zugewiesen sind.

Sie müssen wahrscheinlich den Inode öffnen und das Ergebnis analysieren. Das Inode-Format ist dateisystemabhängig. Einige Dateisysteme haben möglicherweise einen Teil Ihrer Daten im Inode selbst.

BillThor
quelle
1
Es muss einen FS-agnostischen Weg geben, um diese Informationen zu erhalten. Das Lesen direkt vom Inode ist definitiv keine Option. Ich suchte nach etwas wie SEEK_DATAund SEEK_HOLEParametern für lseek(), wie es sie in Solaris gibt: opensolarisforum.org/man/man2/lseek.html
Juliano
@ Juliano Ein Blick auf die Linux lseek Option hat diese Optionen nicht. Solaris unterstützt nur sehr wenige Dateisysteme, daher wäre die Unterstützung relativ einfach. Linux unterstützt eine Vielzahl von Dateisystemen, von denen einige keine Dateien mit geringer Dichte unterstützen. Die Unterstützung von SEEK_DATA / SEEK_HOLE würde die Unterstützung des Codes für alle Dateisysteme auferlegen. Diese Methoden können möglicherweise nicht das tun, was Sie erwarten. Weitere Daten von der Sonnenseite finden Sie unter blogs.sun.com/bonwick/entry/seek_hole_and_seek_data .
BillThor
1
Dateisysteme müssen mit der lseek () -Schnittstelle nichts unterstützen. Der Kernel listet die Dateisystemmodule, die SEEK_DATA / SEEK_HOLE unterstützen, über eine Moduleigenschaft auf. Dies befindet sich in der Manpage selbst und im verlinkten Blog: "Bei Dateisystemen, die keine Informationen zu Löchern liefern, wird die Datei als ein ganzer Datenbereich dargestellt."
Juliano
@ Juliano Benötigt weiterhin Kernel-Mods sowie Änderungen an lseek. Laut Blogeintrag ist dies eine ziemlich neue Funktionalität bei Sun. Damit es funktioniert, muss auch der Dateisystemcode geändert werden. Es würde sicherlich Änderungen an allen Dateisystemen erfordern, die Sparse-Dateien unterstützen, um die Kernel-Hooks bereitzustellen.
BillThor