Правильный формат fstore для fcntl под Python

Я хочу предварительно выделить хранилище для файлов с помощью python. С помощью fcntl я могу предварительно выделить хранилище под C:

  int fd = myFileHandle;
  fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, aLength};
  int ret = fcntl(fd, F_PREALLOCATE, &store);
    if(-1 == ret){
    store.fst_flags = F_ALLOCATEALL;
    ret = fcntl(fd, F_PREALLOCATE, &store);
    if (-1 == ret)
      return false;

Когда я пытаюсь выполнить что-то подобное под Python, я получаю ошибку 22:

    F_ALLOCATECONTIG = 2
    F_PEOFPOSMODE = 3
    F_PREALLOCATE = 42

    f = open(source, 'r')
    f.seek(0, os.SEEK_END)
    size = f.tell()
    f.seek(0, os.SEEK_SET)

    my_fstore = struct.pack('lllll', F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, size, 0)
    d = open(destination, 'w')
    fcntl.fcntl(d.fileno(), F_PREALLOCATE, my_fstore)

Я передаю вызов структуры my_fstore, которая должна быть такой же, как структура c, которую требует вызов fcntl при выполнении F_PREALLOCATE.

/*  fstore_t type used by F_DEALLOCATE and F_PREALLOCATE commands */

typedef struct fstore {
    unsigned int fst_flags; /* IN: flags word */
    int     fst_posmode;    /* IN: indicates use of offset field */
    off_t   fst_offset; /* IN: start of the region */
    off_t   fst_length; /* IN: size of the region */
    off_t   fst_bytesalloc; /* OUT: number of bytes allocated */
} fstore_t;

Все элементы в структуре должны иметь длину 64 бита, следовательно, модуль форматирования «l» в структуре python. Любые рекомендации о том, что я мог бы сделать по-другому?


person blackirishman    schedule 25.09.2017    source источник


Ответы (1)


Оказывается, вы можете легко сделать это, используя библиотеку python fallocate, которая импортирует вызов fallocate в Linux и OSX: https://pypi.python.org/pypi/fallocate/1.6.1

При этом я смог добиться этого, используя следующую конфигурацию fcntl в OSX:

F_ALLOCATECONTIG = 2
F_PEOFPOSMODE = 3
F_PREALLOCATE = 42            
f = open(source, 'r')

f.seek(0, os.SEEK_END)
size = f.tell()
f.seek(0, os.SEEK_SET)

d = open(destination, 'w')

params = struct.pack('Iiqq', F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, size)
fcntl.fcntl(d.fileno(), F_PREALLOCATE, params)
person blackirishman    schedule 29.09.2017