Подтвердить что ты не робот

Как восстановить нулевые блоки разреженного файла?

Рассмотрим разреженный файл с 1-м, записанным на часть файла.

Я хочу вернуть фактическое пространство на диске для этих 1s, поскольку мне больше не нужна эта часть разреженного файла. Часть файла, содержащего эти 1s, должна стать "дырой", как это было до того, как сами были записаны.

Чтобы сделать это, я очистил область до 0s. Это делает не восстановление блоков на диске.

Как я могу сделать разреженный файл, ну, реже?

Этот вопрос похож на на этот, но ответа на этот вопрос нет.

Рассмотрим следующую последовательность событий, запущенных на 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 -

Позвольте мне еще раз уточнить, что я не хочу переписывать файлы, копировать файлы и т.д. Если невозможно каким-то образом освободить ранее выделенные блоки in situ, пусть будет так, d хотел бы определить, действительно ли это возможно или нет. Похоже, "нет, это не так" на данный момент. Я полагаю, что я ищу sys_punchhole для Linux (дискуссии, о которых я только что наткнулся).

4b9b3361

Ответ 1

В настоящее время кажется, что только NTFS поддерживает дырочную штамповку. Это исторически было проблемой для большинства файловых систем. POSIX, насколько я знаю, не определяет интерфейс ОС для пробивания отверстий, поэтому ни одна из стандартных файловых систем Linux не поддерживает его. NetApp поддерживает перфорирование отверстий через Windows в файловой системе WAFL. Существует хорошая запись в блоге об этом здесь.

Для вашей проблемы, как указывали другие, единственным решением является перемещение файла, оставляющего блоки, содержащие нули. Да, это будет медленно. Или напишите расширение для вашей файловой системы в Linux, которое делает это, и отправить patch в хорошие люди в команде ядра Linux.;)

Изменить: Похоже, XFS поддерживает дырочную штамповку. Проверьте этот поток.

Другим действительно искаженным вариантом может быть использование отладчика файловой системы, чтобы идти и пробивать отверстия во всех непрямых блоках, которые указывают на обнуленные блоки в ваш файл (возможно, вы можете script). Затем запустите fsck, который исправит все связанные блокировки блоков, соберет все осиротевшие блоки (обнуленные) и поместит их в каталог lost + found (вы можете удалить их, чтобы освободить место) и исправить другие свойства в файловой системе. Страшно, да?


Отказ от ответственности: сделайте это на свой страх и риск. Я не несу ответственность за потерю данных, которые вы понесли.;)

Ответ 2

Кажется, что linux добавил в syscall под названием fallocate для "пробивания отверстий" в файлах. Реализации в отдельных файловых системах, по-видимому, сосредоточены на возможности использовать это для предварительного выделения большего количества блоков.

Существует также вызов posix_fallocate, который фокусируется только на последнем и не может использоваться для перфорации отверстий.

Ответ 3

Ron Yorston предлагает несколько решений; но все они включают либо установку FS только для чтения (или размонтирование), в то время как разложение происходит; или создавая новый разреженный файл, а затем копируя эти фрагменты оригинала, которые не равны 0, а затем заменяют исходный файл новым разреженным файлом.

Это действительно зависит от вашей файловой системы. Мы уже видели, что NTFS справляется с этим. Я полагаю, что любая из других файловых систем Википедические списки, поскольку обработка прозрачного сжатия будет делать точно то же самое - это, в конце концов, эквивалентно прозрачному сжатию файл.

Ответ 4

После того, как вы обнулили какой-либо регион файла, вы должны сообщить файловой системе, что этот новый регион предназначен для разреженной области. Поэтому в случае NTFS вам нужно снова вызвать DeviceIoControl() для этого региона. По крайней мере, я делаю это в своей утилите: "sparse_checker"

Для меня большая проблема заключается в том, как отменить разреженную область назад:).

Привет

Ответ 5

Этот способ дешев, но он работает.:-P

  • Прочитайте все данные за нужным отверстием, в память (или другой файл или что-то еще).
  • Усечь файл до начала отверстия (ftruncate - ваш друг).
  • Ищите конец отверстия.
  • Введите данные обратно.

Ответ 6

umount вашу файловую систему и редактировать файловую систему прямо так же, как и debugfs или fsck. обычно вам нужен драйвер для каждого используемого fs.

Ответ 7

Кажется, что писать нули (как в ссылочном вопросе) той части, с которой вы закончили, - это логично. Здесь ссылка на вопрос MSDN для разреженных файлов NTFS, который делает это только для "освобождения" "неиспользуемой" части. YMMV.

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