2015-04-16 1 views
0

Je souhaite préallouer le stockage avec l'appel système fcntl. Voici mon code pour le faire:Preallocate de stockage avec fcntl ne fonctionne pas comme prévu

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

La ret variable n'est pas -1 après l'exécution de ce code. Lorsque je reçois la taille du fichier en appelant fstat sur le même handle de fichier, j'obtiens stat.st_size = 0. Mais la valeur store.fst_bytesalloc est égale à la valeur de length.
Que dois-je faire? Quand j'appelle

ftruncate(fd, length); 

-je obtenir un fichier avec un trou ou est un fichier « réel » sans trous? Le deuxième est mon objectif.

Répondre

1

Si votre objectif est un espace contigu que vous devez devez appeler fcntl avec F_ALLOCATECONTIG drapeau et échouer si ret == -1.

Le deuxième appel à fcntl dans votre code (sans F_ALLOCATECONTIG ensemble d'indicateurs) va essayer de préallouer un espace non contigu (lorsque l'allocation contiguë a échoué).

ftruncate Il est nécessaire d'effectuer un appel sur darwin pour que la taille du fichier soit correctement indiquée. Sans l'espace d'appel est réservé, mais la taille du fichier signalé est toujours zéro. Lisez ce article qui stipule que:

Il semble que l'équivalent posix_fallocate [sur OS X] est la fnctl suivie d'une troncature() appel (qui oblige effectivement les données à être écrites dans le fichier)

+0

Merci beaucoup! Ce code fonctionne-t-il comme prévu avec chaque système de fichiers, par ex. ext4 où les fichiers fragmentés sont supportés? Alors, est-ce que je reçois sur ces systèmes de fichiers également un fichier sans trous? –

+0

Cela devrait fonctionner avec les systèmes de fichiers natifs OS X. La prise en charge des systèmes de fichiers non natifs dépend probablement d'outils tiers, comme le fusible pour ext4. – baf