+#ifdef HAVE_FALLOCATE
+# define USE_LINUX_PREALLOCATE
+enum linux_opno {
+ FREESP = 0,
+ ALLOCSP,
+ UNRESVSP,
+ RESVSP,
+};
+
+/* emulate the irix preallocation functions with linux vfs calls */
+static int
+linux_preallocate(
+ int fd,
+ enum linux_opno opno,
+ const struct flock64 *f)
+{
+ struct stat sbuf;
+ int ret;
+
+ assert(f->l_whence == SEEK_SET);
+
+ switch (opno) {
+ case FREESP:
+ return ftruncate(fd, f->l_start);
+ case ALLOCSP:
+ ret = fstat(fd, &sbuf);
+ if (ret)
+ return ret;
+
+ return fallocate(fd, 0, sbuf.st_size,
+ f->l_start - sbuf.st_size);
+ case UNRESVSP:
+ return fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
+ f->l_start, f->l_len);
+ case RESVSP:
+ return fallocate(fd, FALLOC_FL_KEEP_SIZE, f->l_start, f->l_len);
+ }
+
+ /* should never get here */
+ errno = EINVAL;
+ return -1;
+}
+#endif
+