APFS failure to preallocate file space
Originator: | jamesandrewstone | ||
Number: | rdar://38939209 | Date Originated: | 27 March 2018 |
Status: | open | Resolved: | |
Product: | MacOS + SDK | Product Version: | |
Classification: | Serious | Reproducible: | Always |
Summary: Preallocating file space on APFS fails with error "Invalid Arguments" Steps to Reproduce: Compile the attached code using "clang++ --std=c++14 radar.cpp -o radar" Run the binary produced on an APFS file system. I used MacOS 10.13.3, and can also reproduce on a APFS ramdisk. However, the code attached works correctly on a HSF+ file system. On APFS, the program outputs: "Failed to preallocate space! Invalid argument" On HSF+, the program outputs: "successfully preallocated file" Expected Results: I expect the call to fcntl to succeed on APFS as it does on HSF+. Actual Results: Calling fcntl to preallocate file space immediately after the file is created fails. Note that adding a sufficient delay between file creation and calling fcntl can cause the call to succeed so the issue seems to be timing related. We tried syncing the file before the preallocation, but this doesn't help. Version/Build: MacBook Pro (Retina, 13-inch, Early 2015) Processor: 3.1 GHz Intel Core i7 Memory: 16 GB 1867 MHz DDR3 Clang version: Apple LLVM version 9.0.0 (clang-900.0.39.2) Target: x86_64-apple-darwin17.4.0 Thread model: posix Source Code of "radar.cpp": #include <fcntl.h> #include <iostream> #include <unistd.h> int main() { const char* file_name = "test.txt"; if (access(file_name, F_OK) == 0) { int rm_status = unlink(file_name); if (rm_status == -1) { std::cout << "could not remove the existing file: " << file_name << std::endl; } } int fd = ::open(file_name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) { std::cout << "could not open file" << std::endl; return 1; } const size_t bytes_to_write = 5; ssize_t written_bytes = ::write(fd, "hello", bytes_to_write); if (written_bytes == bytes_to_write) { const off_t space_to_allocate = 100; fstore_t store = { F_ALLOCATEALL, F_PEOFPOSMODE, 0, space_to_allocate, 0 }; int ret = ::fcntl(fd, F_PREALLOCATE, &store); if (ret == -1) { int err = errno; const size_t error_buffer_size = 256; char error_buffer[error_buffer_size + 1]; const int result = ::strerror_r(err, error_buffer, error_buffer_size); error_buffer[error_buffer_size] = '\0'; std::cout << "Failed to preallocate space! " << error_buffer << std::endl; } else { std::cout << "successfully preallocated file" << std::endl; } } else { std::cout << "could not write to file, exiting" << std::endl; } ::close(fd); }
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!