How-to: fcntl + F_PREALLOCATE + F_ALLOCATECONTIG and mmap
site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com [For the archives.] You may need these headers: #include <fcntl.h> #include <sys/stat.h> Create a file with open(): open("/tmp/preallocTest", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); Then setup a fstore_t structure per the fcntl man page: fstore_t fst; So, really, I cannot find any good reason to test the size after this call. Then, how do we know anything happened? Well, look at the sb record: fprintf(stderr, "BLOCKS %d\n", sb.st_blocks ); Yup, lots of disk blocks, awaiting your data! Hope this helps someone out - I could have used it two years ago! David _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... This post will hopefully help some other poor soul struggling with how to use this tantilizing feature, given that a deep google search found nothing more than the fcntl man page. Preallocating disk space on OSX / Darwin using fcntl, possibly for use with mmap(). fst.fst_flags = F_ALLOCATECONTIG; // could add F_ALLOCATEALL fst.fst_posmode = F_PEOFPOSMODE; // allocate from EOF (0) fst.fst_offset = 0; // offset relative to the EOF fst.fst_length = desiredSize; fst.fst_bytesalloc = 0; // why not but is not needed ret = fcntl(fd, F_PREALLOCATE, &fst); if(ret == -1) { // read fcntl docs - must test against -1 fprintf(stderr, "failed to expand temp file to size %d (errno %d - %s).\n", imageSize, errno, strerror(errno)); exit(0); } Now, it gets interesting. Unless "desiredSize" is on a block boundary, what you get back will probably be more than you asked for. You are probably doing this as a potential performance enhancer. But if you do the test, expect that the number will most likely be higher than the request, but could be less too. To test for success, you MUST test for "!= -1" (read the fcntl docs), not "!= 0". Now this was the most confusing aspect to me: ret = fstat(fd, &sb); if(ret != 0) { fprintf(stderr, "failed to write to temp file to establish the size.\n"); exit(0); } assert(sb.st_size == 0); succeeds! Also, seeking to the end of the file also shows the file has a 0 length! If you want the file actually allocated (for use with mmap, my application), you can fill it with zeros now by: ret = ftruncate(fd, desiredSize); // NOT fst.fst_bytesAllocated! if(ret != 0) { fprintf(stderr, "failed to write to temp file to establish the size (%d).\n", errno); exit(); } This email sent to site_archiver@lists.apple.com
participants (1)
-
David Hoerl