2009-12-30 17 views
12

Si consideri un file sparse con 1s scritto in una porzione del file.Come si recuperano i blocchi azzerati di un file sparse?

Desidero recuperare lo spazio effettivo sul disco per questi 1 in quanto non ho più bisogno di quella parte del file sparse. La parte del file che contiene questi 1 dovrebbe diventare un "buco" com'era prima che gli 1 fossero scritti da soli.

Per fare ciò, ho azzerato la regione a 0 secondi. Questo è non reclamare i blocchi su disco.

Come si effettua effettivamente il file sparse, bene, sparse di nuovo?

Questa domanda è simile a ma non esiste una risposta accettata per tale domanda.

Si consideri la seguente sequenza di eventi eseguito su un server Linux magazzino:

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

Permettetemi di qualificare ulteriormente che io non voglio riscrivere i file, copiare i file, ecc Se non è possibile liberare in qualche modo blocchi precedentemente assegnati in situ, così sia, ma mi piacerebbe determinare se tale è effettivamente possibile o meno. Sembra "no, non lo è" a questo punto. Suppongo che sto cercando sys_punchhole per Linux (discussioni di cui mi sono appena imbattuto).

+1

Da ciò che ho letto di file sparsi, il determinante chiave non è che il blocco sia riempito con 0, ma che non sia mai stato scritto. Hai qualche riferimento al contrario? – kdgregory

+0

Parti di un file sparse mai scritte per non avere blocchi allocati. Ma la mia domanda è una volta che alloco uno o più blocchi, come posso liberarli? Non ho più bisogno di una parte del file sparse e voglio _dare indietro_ blocchi precedentemente assegnati. Ma non posso. Boo. – z8000

+0

'cp --sparse = always' ... i file sparsi sono un hack basato sul modo in cui i sistemi gestiscono lo storage; non è mai una buona idea affidarsi a un hack. Se hai bisogno di strutture di dati sparse che probabilmente hanno pezzi andare e venire, ti consiglio di cercare una tale struttura o di scriverla tu stesso. – kdgregory

risposta

4

In questo momento sembra che solo NTFS supporti la perforatura. Questo è stato storicamente un problema nella maggior parte dei file system. POSIX, per quanto ne so, non definisce un'interfaccia OS per i buchi, quindi nessuno dei filesystem Linux standard ha il supporto per farlo. NetApp supporta la perforatura attraverso Windows nel suo file system WAFL. C'è un bel post sul blog su questo here.

Per il tuo problema, come altri hanno indicato, l'unica soluzione è spostare il file escludendo blocchi contenenti zeri. Sì, sarà lento. Oppure scrivi un'estensione per il tuo filesystem su Linux che fa questo e submit a patch per il good folks nel team del kernel di Linux. ;)

Modifica: Sembra che XFS supporti la perforatura. Controllare this thread.

Un'altra opzione davvero contorto può essere quella di utilizzare un filesystem debugger per andare a perforare tutti i blocchi indiretti che indicano azzerato blocchi nel file (forse si può script che). Quindi esegui fsck che correggerà tutti i conteggi dei blocchi associati, raccogli tutti i blocchi orfani (quelli eliminati) e inserirli nella directory lost + found (puoi eliminarli per recuperare spazio) e correggere altre proprietà nel filesystem. Spaventoso, eh?


responsabilità: Fate questo a proprio rischio. Non sono responsabile per eventuali perdite di dati.;)

-1

Sembra scrivere zero (come nella domanda di riferimento) alla parte che hai finito è una cosa logica da provare. Qui un link a una domanda MSDN per file sparse NTFS che fa proprio questo per "rilasciare" la parte "non usata". YMMV.

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

+0

L'ho fatto come indicato nell'output 'script'. – z8000

+0

Leggi l'articolo. Windows ha una chiamata speciale per rilasciare i blocchi. Probabilmente anche Linux lo fa. –

+0

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

1

In questo modo è a buon mercato, ma funziona. :-P

  1. Leggere in tutti i dati il ​​buco che si desidera, in memoria (o un altro file, o qualsiasi altra cosa).
  2. Tronca il file all'inizio del foro (ftruncate è il tuo amico).
  3. Cercare fino alla fine del foro.
  4. scrivere i dati nel
+0

Ouch. Quindi permettimi di qualificare ulteriormente che sto cercando qualcosa che "scala" bene. :) Non voglio riscrivere file, copiare file, ecc. Se non è possibile in qualche modo liberare blocchi allocati in precedenza, così sia, ma mi piacerebbe determinare se questo è vero o falso. – z8000

+1

Dipende dal tuo filesystem. Abbiamo già visto che NTFS gestisce questo.Immagino che qualunque altro filesystem [Wikipedia list] [1] come gestendo la compressione trasparente farebbe esattamente la stessa cosa - dopotutto, equivale a comprimere il file in modo trasparente. [1] http://en.wikipedia.org/wiki/Comparison_of_file_systems#Allocation_and_layout_policies –

+0

Funziona, ma in O (n). – dmeister

2

Ron Yorston offre diverse soluzioni.; ma coinvolgono tutti o il montaggio della lettura in sola lettura (o lo smontaggio) mentre avviene la sparsifica; oppure creando un nuovo file sparse, quindi copiando tutti i blocchi dell'originale che non sono solo 0, e quindi sostituendo il file originale con il file appena scarsamente modificato.

Tuttavia dipende molto dal tuo filesystem. Abbiamo già visto che NTFS gestisce questo. Immagino che qualunque altro filesystem Wikipedia lists maneggiando la compressione trasparente faccia esattamente lo stesso, dopotutto equivale a comprimere il file in modo trasparente.

0

umount il file system e modifica il filesystem direttamente in modo simile a debugfs o fsck. di solito ti serve un driver per ogni fs usato.

2

Dopo aver "azzerato" alcune regioni del file, è necessario indicare al file system che questa nuova area deve essere una regione sparsa. Quindi, nel caso di NTFS, devi chiamare DeviceIoControl() per quella regione di nuovo. Almeno faccio così nella mia utilità: "sparse_checker"

Per me il problema più grande è come rimuovere la regione sparsa indietro :).

saluti

8

Sembra come se Linux hanno aggiunto una chiamata di sistema chiamato fallocate per "buchi" punzonatura nei file. Le implementazioni nei singoli filesystem sembrano concentrarsi sulla possibilità di utilizzare questo per la pre-allocazione di un numero sempre più grande di blocchi.

C'è anche la chiamata posix_fallocate che si concentra solo su quest'ultimo e non è utilizzabile per la perforatura.

+1

[Jim Paris di UNIX stackexchange ha scritto uno script] (http://unix.stackexchange.com/a/52029/4830) per rispeminare un file sul posto usando questo syscall. Eccolo: https://gist.github.com/jimparis/3901942 –

Problemi correlati