2009-12-30 10 views
12

Rozpatrzmy rzadki plik z 1s zapisanym w części pliku.W jaki sposób jeden odzyskuje wyzerowane bloki z pliku rzadkiego?

Chcę odzyskać rzeczywistą przestrzeń na dysku dla tych 1, ponieważ nie potrzebuję już tej części pliku rozrzedzonego. Część pliku zawierająca te 1 powinna stać się "dziurą", tak jak to było przed napisaniem samych liter.

Aby to zrobić, wyczyściłem region na 0s. To robi nie odzyskać bloków na dysku.

Jak właściwie utworzyć rzadki plik, cóż, rozrzedzony ponownie?

To pytanie jest podobne do this one, ale nie ma akceptowanej odpowiedzi na to pytanie.

Rozważmy następującą sekwencję zdarzeń w stanie uruchomić na serwerze 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 -

Pozwól mi dalej zakwalifikować, że nie chcą przepisać plików, kopiowanie plików, itd. Jeśli nie jest możliwe, aby w jakiś sposób zwolnić wcześniej przydzielone bloki in situ, niech tak będzie, ale chciałbym sprawdzić, czy jest to rzeczywiście możliwe, czy nie. Wygląda na to, że "nie, nie jest" w tym momencie. Przypuszczam, że szukam dla Linuksa sys_punchhole (dyskusje, o których się natknąłem).

+1

Z tego co przeczytałem o rzadkich plikach, kluczową determinantą nie jest to, że blok jest wypełniony zerami, ale że nigdy nie został napisany. Czy masz jakieś odniesienia do czegoś przeciwnego? – kdgregory

+0

Fragmenty pliku rozrzedzonego nigdy nie zostały napisane, aby nie zostały przydzielone bloki. Ale moje pytanie brzmi, gdy przydzielę jeden lub więcej bloków, w jaki sposób mogę je uwolnić? Nie potrzebuję już części rozrzedzonego pliku i chcę odzyskać poprzednio przydzielone bloki. Ale nie mogę. Gwizd. – z8000

+0

'cp --sparse = always' ... rzadkie pliki są hackami w zależności od sposobu zarządzania pamięcią przez systemy; nigdy nie warto polegać na hackach. Jeśli potrzebujesz rzadkich struktur danych, które mogą mieć fragmenty przychodzące i odchodzą, polecam poszukiwanie takiej struktury lub samodzielne napisanie. – kdgregory

Odpowiedz

4

Teraz wydaje się, że tylko NTFS obsługuje dziurkowanie. To był historycznie problem w większości systemów plików. POSIX, o ile mi wiadomo, nie definiuje interfejsu systemu operacyjnego do dziurkowania, więc żaden ze standardowych systemów plików Linux nie obsługuje go. NetApp obsługuje dziurkowanie w systemie Windows w systemie plików WAFL. Jest ładny wpis na blogu o tym here.

Dla twojego problemu, jak wskazali inni, jedynym rozwiązaniem jest przeniesienie pliku, pomijając bloki zawierające zera. Tak, będzie wolno. Lub napisz rozszerzenie dla systemu plików na Linuksie, który to robi i a patch do good folks w zespole jądra Linux. ;)

Edytuj: Wygląda na to, że XFS obsługuje dziurkowanie. Sprawdź this thread.

Inną naprawdę twisted opcji można użyć filesystem debugger iść i dziurkowanie wszystkich bloków pośrednich, które wskazują na wyzerowany bloków w pliku (być może można skrypt). Następnie uruchom fsck, który skoryguje wszystkie powiązane liczby bloków, zbierz wszystkie osierocone bloki (wyzerowane) i umieść je w katalogu lost + found (możesz je usunąć, aby odzyskać miejsce) i popraw inne właściwości w systemie plików. Przerażające, co?


Zastrzeżenie: Czyńcie to na własne ryzyko. Nie ponoszę odpowiedzialności za utratę danych, którą ponosisz.;)

-1

Wygląda na to, że wpisywanie zer (jak w zadanym pytaniu) do części, którą wykonałeś, jest logiczne. Tutaj link do pytania MSDN dla plików sparse NTFS, który robi tak, aby "zwolnić" część "nieużywaną". YMMV.

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

+0

Zrobiłem to tak, jak zaznaczono w wyjściu "skryptu". – z8000

+0

Przeczytaj artykuł. System Windows ma specjalne wywołanie do zwolnienia bloków. Linux prawdopodobnie też. –

+0

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

1

ten sposób jest tani, ale to działa. :-P

  1. Odczytaj wszystkie dane poza wybraną dziurą, do pamięci (lub innego pliku lub czegoś podobnego).
  2. Skróć plik do początku otworu (ftruncate jest twoim przyjacielem).
  3. Poszukaj do końca otworu.
  4. Wpisz dane z powrotem w
+0

Ouch. Więc pozwól mi dalej kwalifikować się, że szukam czegoś, co "dobrze" skaluje. :) Nie chcę przepisywać plików, kopiować plików itp. Jeśli nie można w jakiś sposób zwolnić wcześniej przydzielonych bloków in situ, to niech tak będzie, ale chciałbym sprawdzić, czy jest to prawda czy fałsz. – z8000

+1

To zależy od twojego systemu plików. Widzieliśmy już, że NTFS to obsługuje.Wyobrażam sobie, że jakikolwiek inny system plików [Wikipedia list] [1] jako obsługujący przezroczystą kompresję zrobiłby dokładnie to samo - jest to przecież równoznaczne z przezroczystym kompresowaniem pliku. [1] http://en.wikipedia.org/wiki/Comparison_of_file_systems#Alocation_and_layout_policies –

+0

Działa, ale w O (n). – dmeister

2

Ron Yorston oferuje kilka rozwiązań.; ale wszystkie one obejmują montowanie FS-tylko-do-odczytu (lub odmontowanie go) podczas przeprowadzania spryfikacji; lub tworzenie nowego, rzadkiego pliku, a następnie kopiowanie po tych fragmentach oryginału, które nie są tylko zerami, a następnie zastąpienie oryginalnego pliku nowo sparsowanym plikiem.

To naprawdę zależy od systemu plików. Widzieliśmy już, że NTFS to obsługuje. Wyobrażam sobie, że jakikolwiek inny system plików, obsługujący przezroczystą kompresję, robiłby dokładnie to samo - jest to przecież równoznaczne z przezroczystym kompresowaniem pliku.

0

umontuj swój system plików i edytuj system plików bezpośrednio w sposób podobny do debugfs lub fsck. zwykle potrzebujesz sterownika dla każdego używanego fs.

2

Po "wyzerowaniu" jakiegoś regionu pliku należy poinformować system plików, że ten nowy region ma być regionem rzadkim. W przypadku NTFS musisz ponownie wywołać DeviceIoControl() dla tego regionu. Przynajmniej robię to w moim narzędziu: "sparse_checker"

Dla mnie większym problemem jest rozbrojenie rzadkiego regionu z powrotem :).

Pozdrowienia

8

Wydaje się, jak gdyby został dodany linux syscall nazwie fallocate dla „DZIURKOWANIE” w plikach. Implementacje w poszczególnych systemach plików wydają się koncentrować na możliwości wykorzystania tego do wstępnego przydzielania większej liczby ciągłych bloków.

Istnieje również wywołanie posix_fallocate, które koncentruje się tylko na tym ostatnim i nie nadaje się do dziurkowania.

+1

[Jim Paris from UNIX stackexchange napisał skrypt] (http://unix.stackexchange.com/a/52029/4830) w celu przekształcenia pliku w miejscu za pomocą tej funkcji. Oto ona: https://gist.github.com/jimparis/3901942 –

Powiązane problemy