2009-12-30 19 views
12

Betrachten Sie eine Sparse-Datei mit 1s in einen Teil der Datei geschrieben.Wie erhält man zeroed Blöcke einer Sparse-Datei zurück?

Ich möchte den tatsächlichen Speicherplatz auf der Festplatte für diese 1s zurückfordern, da ich diesen Teil der Sparse-Datei nicht mehr benötige. Der Teil der Datei, der diese 1 enthält, sollte ein "Loch" werden, wie es war, bevor die 1s selbst geschrieben wurden.

Um dies zu tun, löschte ich die Region auf 0s. Dies macht nicht die Blöcke auf der Festplatte zurückfordern.

Wie mache ich die Sparse-Datei, nun, spärlich wieder?

Diese Frage ist ähnlich wie this one, aber es gibt keine akzeptierte Antwort für diese Frage.

Betrachten Sie die folgende Sequenz von Ereignissen auf einem Lager Linux-Server läuft:

$ cat /tmp/test.c 
#include <unistd.h> 
#include <stdio.h> 
#include <fcntl.h> 
#include <string.h> 

int main(int argc, char **argv) { 
    int fd; 
    char c[1024]; 

    memset(c,argc==1,1024); 

    fd = open("test",O_CREAT|O_WRONLY,0777); 
    lseek(fd,10000,SEEK_SET); 
    write(fd,c,1024); 
    close(fd); 

    return 0; 
} 

$ gcc -o /tmp/test /tmp/test.c 

$ /tmp/test 

$ hexdump -C ./test 
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 
* 
00002710 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................| 
* 
00002b10 

$ du -B1 test; du -B1 --apparent-size test 
4096  test 
11024  test 

$ /tmp/test clear 

$ hexdump -C ./test 
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 
* 
00002b10 

$ du -B1 test; du -B1 --apparent-size test 
4096  test 
11024  test 

# NO CHANGE IN SIZE.... HMM.... 

EDIT -

Lassen Sie mich weiter qualifizieren, dass ich nicht will, Dateien neu zu schreiben, Dateien kopieren, etc. Wenn Es ist nicht möglich, zuvor zugewiesene Blöcke in situ zu befreien, so sei es, aber ich würde gerne feststellen, ob das tatsächlich möglich ist oder nicht. An dieser Stelle scheint es "nein, ist es nicht". Ich nehme an, ich suche nach sys_punchhole für Linux (Diskussionen, über die ich gerade gestolpert bin).

+1

Nach was ich von Sparse-Dateien gelesen habe, ist die Schlüsseldeterminante nicht, dass der Block mit Nullen gefüllt ist, sondern dass er nie geschrieben wurde. Haben Sie Hinweise auf das Gegenteil? – kdgregory

+0

Teile einer Sparse-Datei, die nie geschrieben wurde, um keine zugewiesenen Blöcke zu haben. Aber, meine Frage ist, sobald ich einen oder mehrere Blöcke zuteile, wie kann ich sie befreien? Ich brauche keinen Teil der Sparse-Datei mehr und möchte _ vorher zugewiesene Blöcke _ zurückgeben. Aber ich kann nicht. Boo. – z8000

+0

'cp --sparse = immer' ... Sparse-Dateien sind ein Hack, der auf der Art basiert, wie Systeme Speicher verwalten; es ist nie eine gute Idee, sich auf einen Hack zu verlassen. Wenn Sie spärliche Datenstrukturen benötigen, bei denen es wahrscheinlich ist, dass Teile kommen und gehen, würde ich empfehlen, nach einer solchen Struktur zu suchen oder sie selbst zu schreiben. – kdgregory

Antwort

4

Im Moment scheint es, dass nur NTFS Lochen unterstützt. Dies war in der Vergangenheit ein Problem in den meisten Dateisystemen. Soweit ich weiß, definiert POSIX keine OS-Schnittstelle, um Löcher zu stanzen, so dass keines der Linux-Standarddateisysteme dies unterstützt. NetApp unterstützt Lochen durch Windows in seinem WAFL Dateisystem. Es gibt einen netten Blog-Beitrag dazu here.

Für Ihr Problem, wie andere angegeben haben, ist die einzige Lösung, die Datei zu verschieben, Blöcke mit Nullen auslassen. Ja, es wird langsam. Oder schreiben Sie eine Erweiterung für Ihr Dateisystem unter Linux, die dies tut und submit eine patch an die good folks im Linux-Kernel-Team. ;)

Edit: Sieht aus wie XFS Lochen unterstützt. Überprüfen Sie this thread.

Eine andere wirklich verdrehte Option kann sein, eine filesystem debugger zu verwenden, um Löcher in alle indirekten Blöcke zu stanzen, die auf genullt Blöcke in Ihrer Datei zeigen (vielleicht können Sie das Skript). Führen Sie dann fsck aus, das alle zugehörigen Blockzählungen korrigiert, alle verwaisten Blöcke (die nullten) sammelt und sie in das Verzeichnis lost + found stellt (Sie können sie löschen, um Speicherplatz freizugeben) und andere Eigenschaften im Dateisystem korrigieren. Gruselig, nicht wahr?


Haftungsausschluss: Tun Sie dies auf eigene Gefahr. Ich bin nicht verantwortlich für Datenverlust, den Sie erleiden.;)

-1

Es scheint so, als ob das Schreiben von Nullen (wie in der referenzierten Frage) auf den Teil, mit dem Sie fertig sind, logisch ist. Hier ein Link zu einer MSDN-Frage für NTFS-Sparse-Dateien, die genau das tun, um den "unbenutzten" Teil "freizugeben". YMMV.

http://msdn.microsoft.com/en-us/library/ms810500.aspx

+0

Ich tat das wie in der 'Skript' Ausgabe erwähnt. – z8000

+0

Lesen Sie den Artikel. Windows hat einen speziellen Aufruf, um die Blöcke freizugeben. Linux macht das wahrscheinlich auch. –

+0

http://lists.linuxcoding.com/kernel/2005-q4/msg10956.html – z8000

1

Auf diese Weise ist billig, aber es funktioniert. :

  1. Lesen Sie alle Daten nach dem Loch, das Sie wollen, in den Speicher (oder eine andere Datei oder was auch immer).
  2. Kürzen Sie die Datei an den Anfang des Lochs (ftruncate ist Ihr Freund).
  3. Suchen Sie nach dem Ende des Lochs.
  4. Schreiben Sie die Daten zurück in
+0

Autsch. Lasst mich weiter qualifizieren, dass ich nach etwas suche, das gut "skaliert". :) Ich möchte keine Dateien neu schreiben, Dateien kopieren usw. Wenn es nicht möglich ist, zuvor zugewiesene Blöcke in situ freizugeben, so sei es, aber ich möchte herausfinden, ob dies richtig oder falsch ist. – z8000

+1

Es hängt von Ihrem Dateisystem ab. Wir haben bereits gesehen, dass NTFS dies handhabt.Ich stelle mir vor, dass jedes der anderen Dateisysteme [Wikipedia-Listen] [1] die Verarbeitung der transparenten Komprimierung genau so machen würde - das ist schließlich gleichbedeutend mit der transparenten Komprimierung der Datei. [1] http://en.wikipedia.org/wiki/Comparison_of_file_systems#Allocation_and_layout_policies –

+0

Es funktioniert, aber in O (n). – dmeister

2

Ron Yorston mehrere Lösungen bietet. aber sie alle beinhalten entweder das FS-Nur-Lesen (oder Unmounten) des FS, während das Sparsifizieren stattfindet; oder erstellen Sie eine neue Sparse-Datei, kopieren Sie dann über die Teile des Originals, die nicht nur 0 sind, und ersetzen Sie dann die ursprüngliche Datei durch die neugespeicherte Datei.

Es hängt aber wirklich von Ihrem Dateisystem ab. Wir haben bereits gesehen, dass NTFS dies handhabt. Ich stelle mir vor, dass jedes der anderen Dateisysteme Wikipedia lists im Umgang mit transparenter Komprimierung genau das gleiche tun würde - das ist immerhin gleichbedeutend mit einer transparenten Komprimierung der Datei.

0

umounten Sie Ihr Dateisystem und bearbeiten Sie das Dateisystem direkt in ähnlicher Debugfs oder fsck. Normalerweise benötigen Sie Treiber für jedes verwendete fs.

2

Nachdem Sie einige Bereiche der Datei "auf Null gesetzt" haben, müssen Sie dem Dateisystem mitteilen, dass diese neue Region eine dünn besiedelte Region sein soll. Im Fall von NTFS müssen Sie DeviceIoControl() für diese Region erneut aufrufen. Zumindest tue ich so in meinem Dienstprogramm: "sparse_checker"

Für mich ist das größere Problem, wie die Sparse-Region wieder zu deaktivieren :).

Grüße

8

Es scheint, als ob Linux eine syscall genannt fallocate für „Lochen“ in Dateien hinzugefügt haben. Die Implementierungen in einzelnen Dateisystemen scheinen sich auf die Fähigkeit zu konzentrieren, dies für die Vorbelegung einer größeren kontinuierlichen Anzahl von Blöcken zu verwenden.

Es gibt auch die posix_fallocate Anruf, die nur auf Letzteren konzentrieren, und ist nicht für Lochung verwendbar.

+1

[Jim Paris von UNIX staplexchange schrieb ein Skript] (http://unix.stackexchange.com/a/52029/4830), um eine Datei direkt mit diesem syscall neu zu parsen. Hier ist es: https://gist.github.com/jimparis/3901942 –