Pergunta

Considere um arquivo esparso com 1s escrito em uma parte do arquivo.

Quero recuperar o espaço real no disco para esses 1s, pois não preciso mais dessa parte do arquivo esparso. A parte do arquivo que contém esses 1s deve se tornar um "buraco" como era antes que os 1s fossem escritos.

Para fazer isso, limpei a região para 0s. Isso faz não Recupere os blocos no disco.

Como eu realmente faço o arquivo esparso, bem, escasso de novo?

Esta questão é semelhante a Este Mas não há resposta aceita para essa pergunta.

Considere a seguinte sequência de eventos executados em um servidor Linux de Stock:

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

Editar -

Deixe -me qualificar ainda mais que não quero reescrever arquivos, copiar arquivos etc. Se não for possível de alguma forma, de alguma forma grátis alocados anteriormente blocos no local, assim seja, mas eu gostaria de determinar se isso é realmente possível ou não. Parece que "não, não é" neste momento. Suponho que estou procurando sys_punchhole para Linux (discussões sobre as quais eu acabei de me deparar).

Foi útil?

Solução

Right now it appears that only NTFS supports hole-punching. This has been historically a problem across most filesystems. POSIX as far as I know, does not define an OS interface to punch holes, so none of the standard Linux filesystems have support for it. NetApp supports hole punching through Windows in its WAFL filesystem. There is a nice blog post about this here.

For your problem, as others have indicated, the only solution is to move the file leaving out blocks containing zeroes. Yeah its going to be slow. Or write an extension for your filesystem on Linux that does this and submit a patch to the good folks in the Linux kernel team. ;)

Edit: Looks like XFS supports hole-punching. Check this thread.

Another really twisted option can be to use a filesystem debugger to go and punch holes in all indirect blocks which point to zeroed out blocks in your file (maybe you can script that). Then run fsck which will correct all associated block counts, collect all orphaned blocks (the zeroed out ones) and put them in the lost+found directory (you can delete them to reclaim space) and correct other properties in the filesystem. Scary, huh?


Disclaimer: Do this at your own risk. I am not responsible for any data loss you incur. ;)

Outras dicas

Parece que o Linux adicionou um syscall chamado fallocate Para "furos de perfuração" em arquivos. As implementações em sistemas de arquivos individuais parecem se concentrar na capacidade de usá-lo para pré-alocar um número contínuo maior de blocos.

Há também o posix_fallocate Chame isso apenas se concentre neste último e não é utilizável para perfurar orifícios.

Ron Yorston oferece várias soluções; Mas todos envolvem montar o FS somente leitura (ou desmontá-lo) enquanto a escarsificação ocorre; Ou fabricando um novo arquivo esparso, copiando os pedaços do original que não são apenas 0s e substituindo o arquivo original pelo arquivo recém-separado.

Mas realmente depende do seu sistema de arquivos. Já vimos que o NTFS lida com isso. Eu imagino que algum dos outros sistemas de arquivos Listas da Wikipedia Como o manuseio de compactação transparente faria exatamente o mesmo - isso é, afinal, equivalente a comprimir transparentemente o arquivo.

Depois de "zero", alguma região do arquivo, você deve dizer ao sistema de arquivos que esta nova região pretende ser uma região esparsa. Portanto, no caso de NTFs, você deve chamar de dispositivo de dispositivo () para essa região novamente. Pelo menos eu faço desta maneira em meu utilitário: "Sparse_checker"

Para mim, o maior problema é como despertar a região esparsa de volta :).

Cumprimentos

Dessa forma, é barato, mas funciona. :-P

  1. Leia todos os dados após o buraco que você deseja, na memória (ou em outro arquivo, ou o que for).
  2. Truncar o arquivo para o início do buraco (ftruncate é seu amigo).
  3. Procure para o fim do buraco.
  4. Escreva os dados de volta.

Oount Your FileSystem e Edit FileSystem diretamente de maneira semelhante a debugfs ou FSCK. Geralmente você precisa de driver para cada FS usado.

Parece escrever zeros (como na pergunta referenciada) para a parte que você terminou, é uma coisa lógica a tentar. Aqui, um link para uma pergunta do MSDN para arquivos esparsos do NTFS que fazem exatamente isso para "liberar" a parte "não utilizada". Ymmv.

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top