简体   繁体   中英

Preallocate storage with fcntl doesn't work as expected

I want to preallocate storage with the system call fcntl . Here is my code to do so:

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);
}

The variable ret is not -1 after executing that code. When I get the file size by calling fstat on the same file handle, I get stat.st_size = 0 . But the value store.fst_bytesalloc equals the value of length .
What do I have to do? When I call

ftruncate(fd, length);

do I get a file with a hole or is it a 'real' file without holes? The second one is my goal.

If your goal is a contiguous space only you should should call fcntl with F_ALLOCATECONTIG flag and fail if ret == -1 .

The second call to fcntl in your code (without F_ALLOCATECONTIG flag set) will try to preallocate non-contiguous space (as contiguous allocation failed).

ftruncate call is needed on darwin to have file size reported correctly. Without the call space is being reserved, but file size reported is still zero. Read this article that states that:

It appears that the posix_fallocate equivalent [on OS X] is to the fnctl followed by a truncate() call (which actually forces data to be written to the file)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM