Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Резервирование места под файл.  (Прочитано 12002 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« : 26-02-2017 18:29 » 

Добрый вечер.

Вопрос вот такой, предположим мне необходимо создать файл большого размера под обработку, например, 20Гб, а свободного места на диске к началу процесса заполнения моего файла 40Гб - как бы хватает. Однако, другие процессы заполняют пространство быстрее моего, и получается ситуация, когда место на диске исчерпывается, и процесс прерывает расчёт в аварийном порядке.
Так вот, можно ли создать файл и быстро зарезервировать под него место, например, эти 20Гб, но так, чтобы не тратить время на запись, например, нулями всего его пространства?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 26-02-2017 19:34 » 

1. ftruncate. Не уверен, что будет физическое занятие места.
2. Тупо заполнить нулями.
3. Воспользоваться специфичными для ОС вызовами для резервирования места (напр., ext4 поддерживает резервирование без фактической записи). Сам не пользовался, подозреваю это будет ioctl.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 26-02-2017 20:00 » 

в винде в консоли (стало интересно, нагуглил)
fsutil file createnew <filename> <length>
работает)

PS а вообще почему нельзя тупо переместить указатель на конец файла и записать туда допустим ноль?
« Последнее редактирование: 26-02-2017 20:03 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 26-02-2017 20:37 » 

PS а вообще почему нельзя тупо переместить указатель на конец файла и записать туда допустим ноль?
Если речь о fseek, то предполагаю он вернёт ошибку - EINVAL, скорее всего, и всё, но попробую завтра. Я думаю, указатель позиции может существовать только в пределах уже имеющегося текущего габарита файла.

3. Воспользоваться специфичными для ОС вызовами для резервирования места (напр., ext4 поддерживает резервирование без фактической записи). Сам не пользовался, подозреваю это будет ioctl.
в винде в консоли (стало интересно, нагуглил)
fsutil file createnew <filename> <length>
работает)
То есть для NTFS может быть решение?
Записан
zubr
Гость
« Ответ #4 : 26-02-2017 22:31 » 

Для  Windows SetEndOfFile, SetFileValidData
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 26-02-2017 23:37 » 

ftruncate под Linux не занимает место на диске.

$ df -m
Filesystem        1M-blocks  Used Available Use% Mounted on
/dev/ploop34549p1     25069  1486     22287   7% /
$ ./create_big_file
$ ls -l
total 16
-rwxr-xr-x 1 root root       8624 Feb 26 18:35 create_big_file
-rw-r--r-- 1 root root        258 Feb 26 18:35 create_big_file.c
-rwx--x--T 1 root root 1073741824 Feb 26 18:35 test.bin
$ df -m
Filesystem        1M-blocks  Used Available Use% Mounted on
/dev/ploop34549p1     25069  1486     22287   7% /

Выполнение мгновенное.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
darkelf
Молодой специалист

no
Offline Offline

« Ответ #6 : 27-02-2017 06:51 » 

Для того, чтобы место точно выделилось, имхо, в UNIX-подобных ОС необходимо использовать posix_fallocate(). Правда как у него со скоростью не знаю.
Записан
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 27-02-2017 10:11 » 

Буду знать, но, как понял ftruncate является частью unistd.h, а не stdio.h. Кстати, бегло прочёл, но вроде рекомендовано аккуратно её использовать ввиду того, что функция может быть не в курсе состояния буфера ввода-вывода. Я так понимаю, если обрезается файл с уже имеющимися данными, то необходимо перед её вызовом делать fflush.

fseek выдаёт ошибку при попытке задать указатель, превышающий действительный размер файла.

Для Windows SetEndOfFile, SetFileValidData
Похоже это оно, но читаю следующее:
https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa365544(v=vs.85).aspx
Цитата
Код: (C)
BOOL WINAPI SetFileValidData(
  _In_ HANDLE   hFile,
  _In_ LONGLONG ValidDataLength
);
...
ValidDataLength [in]
The new valid data length.
This parameter must be a positive value that is greater than the current valid data length, but less than the current file size.
...
То есть логически установить размер больший, чем есть нельзя.
https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa365531(v=vs.85).aspx
Цитата
The physical file size is also referred to as the end of the file. The SetEndOfFile function can be used to truncate or extend a file. To set the logical end of a file, use the SetFileValidData function.
...
Код: (C)
BOOL WINAPI SetEndOfFile(
  _In_ HANDLE hFile
);
...
The SetEndOfFile function sets the file size. Use SetFileValidData to set the valid data length.
...
Записан
zubr
Гость
« Ответ #8 : 27-02-2017 13:40 » 

Да можно и без SetEndOfFile, SetFileValidData - CreateFile, CreateFileMapping
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 27-02-2017 22:02 » 

$ df -m /
Filesystem        1M-blocks  Used Available Use% Mounted on
/dev/ploop34549p1     25069  1487     22287   7% /
$ time ./create_big_file_posix

real    0m0.005s
user    0m0.000s
sys     0m0.004s
$ df -m /
Filesystem        1M-blocks  Used Available Use% Mounted on
/dev/ploop34549p1     25069  2511     21262  11% /
$ ls -l test.bin
-rw-r--r-- 1 root root 1073741824 Feb 27 16:59 test.bin
Гиг мгновенно. Это 5 мс в виртуалке, а на хосте всего 1 мс.

Вариант для 64 бита выделил 32 ГБ за 79 мс. Подтверждаю, что записи в блоки данных нет.
« Последнее редактирование: 27-02-2017 22:32 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
darkelf
Молодой специалист

no
Offline Offline

« Ответ #10 : 28-02-2017 08:24 » 

Гиг мгновенно. Это 5 мс в виртуалке, а на хосте всего 1 мс.
Вариант для 64 бита выделил 32 ГБ за 79 мс. Подтверждаю, что записи в блоки данных нет.
Судя по man-ам, как я понимаю, это зависит от файловой системы. Если поддерживается, то всё будет работать довольно быстро и без ситуаций "гонок". Если не поддерживается, то будет включена эмуляция, которая может работать медленно и с "гонками".
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 28-02-2017 20:31 » new

ext4 - я еще парой постов выше написал. Еще поддерживается, как минимум, xfs и btrfs.

Интересный аспект: в Linux оно поддержано в ядре и по возможности поддерживается железом. Место не просто аллоцируется, но и заполняется нулями.
« Последнее редактирование: 28-02-2017 21:12 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
darkelf
Молодой специалист

no
Offline Offline

« Ответ #12 : 01-03-2017 07:58 » 

ext4 - я еще парой постов выше написал. Еще поддерживается, как минимум, xfs и btrfs.
Я это больше не Вам, а топикстартеру, что-бы он понимал, что могут быть определённые ньюансы при использовании этой функции.
Записан
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 01-03-2017 09:29 » 

Интересный аспект: в Linux оно поддержано в ядре и по возможности поддерживается железом. Место не просто аллоцируется, но и заполняется нулями.
Если учесть сколько времени шла запись гигабайтов, то записи этих данных не происходило, значит, место, полагаю, нулями физически не заполняется, просто попытка прочесть из зарезервированного пространства будет возвращать нуль. Интересно также: резервируя место система выделяет конкретные блоки, или просто из "счётчика свободного пространства" вычитает наш размер, и заранее остаётся неизвестным где будут лежать блоки файла при его наполнении?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #14 : 01-03-2017 19:58 » 

Все верно. iostat показал менее 1.5 МБ записанного. Значит зануление региона поддерживается файловой системой.
Но есть еще операция FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, вызывающая аппаратный ATA TRIM и SCSI DISCARD.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines