Question

Considérons un fichier fragmenté avec 1s par écrit à une partie du fichier.

Je veux récupérer l'espace réel sur le disque pour ces 1s que je ne dois plus la partie du fichier clairsemé. La partie du fichier contenant ces 1s doit devenir un « trou » comme il était avant les 1 étaient eux-mêmes écrits.

Pour ce faire, je franchis la région à 0s. Cela ne pas récupérer les blocs sur le disque.

Comment puis-je réellement le fichier clairsemé, bien, encore une fois clairsemée?

Cette question est similaire à celui-ci mais il n'y a pas de réponse acceptée pour cette question.

Considérons la séquence suivante d'événements exécutés sur un stock serveur Linux:

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

Permettez-moi encore nuancer je ne veux pas réécrire les fichiers, copier des fichiers, etc. S'il est impossible d'en quelque sorte des blocs libres précédemment alloués in situ , donc que ce soit, mais je souhaitez déterminer si tel est effectivement possible ou non. Il semble que « non, ce n'est pas » à ce stade. Je suppose que je suis à la recherche sys_punchhole pour Linux (discussions dont je viens de tombé sur).

Était-ce utile?

La solution

À l'heure actuelle, il semble que seul NTFS prend en charge la perforation. Cela a été historiquement un problème dans la plupart des systèmes de fichiers. POSIX autant que je sache, ne définit pas une interface OS pour percer des trous, de sorte qu'aucun des systèmes de fichiers Linux standard ont soutien. NetApp prend en charge la perforation via Windows dans son WAFL . Il y a un poste de blog sympa sur ce .

Pour votre problème, comme d'autres ont indiqué, la seule solution est de déplacer le fichier contenant des blocs laissant des zéros. Ouais ça va être lent. Ou écrire une extension pour votre système de fichiers sur Linux qui fait cela et soumettre a Patch à noreferrer bonnes gens dans l'équipe du noyau Linux. ;)

Modifier Ressemble XFS soutient la perforation. Consultez ce fil .

Une autre option vraiment tordue peut être d'utiliser un système de fichiers débogueur pour aller poinçon des trous dans tous les blocs indirects qui pointent vers des blocs mis à zéro dans votre fichier (script peut-être vous pouvez cela). Ensuite, exécutez fsck qui corrigera tous les chefs de blocs associés, recueillir tous les blocs orphelins (remis à zéro les ones) et les mettre dans le répertoire perdu + trouvé (vous pouvez les supprimer pour récupérer l'espace) et de corriger d'autres propriétés dans le système de fichiers. Effrayant, hein?


Disclaimer: Faites ceci à vos propres risques. Je ne suis pas responsable de toute perte de données que vous encourez ;.)

Autres conseils

Il semble que Linux a ajouté un syscall appelé fallocate pour « percer des trous » dans les fichiers. Les mises en œuvre dans différents systèmes de fichiers semblent se concentrer sur la possibilité d'utiliser cette pré-attribution d'un nombre plus grand de blocs Continuous.

Il y a aussi l'appel posix_fallocate qui se concentrent uniquement sur ce dernier, et n'est pas utilisable pour la perforation.

Ron Yorston offre plusieurs solutions; mais elles impliquent toutes soit le montage des FS en lecture seule (ou le démonter) tandis que le sparsifying a lieu; ou de faire un nouveau fichier clairsemé, puis de copier à travers ces morceaux de l'original qui ne sont pas seulement 0s, puis remplacer le fichier original avec le fichier nouvellement sparsified.

Cela dépend vraiment de votre système de fichiers bien. Nous avons déjà vu que NTFS gère cela. Je suppose que l'un des autres systèmes de fichiers Wikipedia listes que la manipulation compression transparente ferait exactement la même - cela est, après tout, ce qui équivaut à compressant de façon transparente le fichier.

Après avoir « remis à zéro » une région du fichier que vous devez indiquer au système de fichiers que cette nouvelle région est destinée à être une région clairsemée. Ainsi, en cas de NTFS, vous devez appeler DeviceIoControl () pour cette région encore. Au moins, je fais de cette façon dans mon utilitaire: "sparse_checker"

Pour moi, le plus gros problème est de savoir comment la région UNSET retour clairsemée.)

Cordialement

De cette façon, ne coûte pas cher, mais cela fonctionne. :-P

  1. Lire dans toutes les données du passé le trou que vous voulez, dans la mémoire (ou un autre fichier, ou autre).
  2. tronquer le fichier au début du trou (ftruncate est votre ami).
  3. Cherchez à la fin du trou.
  4. Écrivez les données avant.

umount votre système de fichiers et système de fichiers modifier directement dans debugfs manière similaire ou fsck. habituellement vous avez besoin pour chaque pilote fs utilisé.

On dirait que des zéros à écrire (comme dans la question de référence) à la partie que vous avez terminé est une chose logique d'essayer. Voici un lien vers une question MSDN pour les fichiers NTFS clairsemés qui fait juste que la partie « libérer » le « inutilisé ». YMMV.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top