summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes1
-rw-r--r--eio.c17
-rw-r--r--eio.h21
-rw-r--r--eio.pod9
-rw-r--r--libeio.m415
5 files changed, 55 insertions, 8 deletions
diff --git a/Changes b/Changes
index 0cd1985..3394544 100644
--- a/Changes
+++ b/Changes
@@ -51,4 +51,5 @@ TODO: fadvise request
- disable sendfile on darwin, broken as everything else.
- add realpath request and implementation.
- cancelled requests will still invoke their request callbacks.
+ - add fallocate.
diff --git a/eio.c b/eio.c
index 2a42802..3f926a0 100644
--- a/eio.c
+++ b/eio.c
@@ -950,6 +950,17 @@ eio__sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags)
return fdatasync (fd);
}
+static int
+eio__fallocate (int fd, int mode, off_t offset, size_t nbytes)
+{
+#if HAVE_FALLOCATE
+ return fallocate (fd, offset, nbytes, flags);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
#if !HAVE_READAHEAD
# undef readahead
# define readahead(fd,offset,count) eio__readahead (fd, offset, count, self)
@@ -1965,6 +1976,7 @@ eio_execute (etp_worker *self, eio_req *req)
case EIO_MLOCK: req->result = eio__mlock (req->ptr2, req->size); break;
case EIO_MLOCKALL: req->result = eio__mlockall (req->int1); break;
case EIO_SYNC_FILE_RANGE: req->result = eio__sync_file_range (req->int1, req->offs, req->size, req->int2); break;
+ case EIO_FALLOCATE: req->result = eio__fallocate (req->int1, req->int2, req->offs, req->size); break;
case EIO_READDIR: eio__scandir (req, self); break;
@@ -2074,6 +2086,11 @@ eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int
REQ (EIO_SYNC_FILE_RANGE); req->int1 = fd; req->offs = offset; req->size = nbytes; req->int2 = flags; SEND;
}
+eio_req *eio_fallocate (int fd, int mode, off_t offset, size_t len, int pri, eio_cb cb, void *data)
+{
+ REQ (EIO_FALLOCATE); req->int1 = fd; req->int2 = mode; req->offs = offset; req->size = len; SEND;
+}
+
eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data)
{
REQ (EIO_FDATASYNC); req->int1 = fd; SEND;
diff --git a/eio.h b/eio.h
index b974d1a..9be7327 100644
--- a/eio.h
+++ b/eio.h
@@ -119,14 +119,12 @@ enum
};
/* eio_mtouch flags */
-
enum
{
EIO_MT_MODIFY = 1
};
/* eio_sync_file_range flags */
-
enum
{
EIO_SYNC_FILE_RANGE_WAIT_BEFORE = 1,
@@ -134,10 +132,16 @@ enum
EIO_SYNC_FILE_RANGE_WAIT_AFTER = 4
};
-typedef double eio_tstamp; /* feel free to use double in your code directly */
+/* eio_fallocate flags */
+enum
+{
+ EIO_FALLOC_FL_KEEP_SIZE = 1 /* MUST match the value in linux/falloc.h */
+};
-/* the eio request structure */
+/* timestamps and differences - feel free to use double in your code directly */
+typedef double eio_tstamp;
+/* the eio request structure */
enum
{
EIO_CUSTOM,
@@ -151,7 +155,7 @@ enum
EIO_CHMOD, EIO_FCHMOD,
EIO_CHOWN, EIO_FCHOWN,
EIO_SYNC, EIO_FSYNC, EIO_FDATASYNC,
- EIO_MSYNC, EIO_MTOUCH, EIO_SYNC_FILE_RANGE,
+ EIO_MSYNC, EIO_MTOUCH, EIO_SYNC_FILE_RANGE, EIO_FALLOCATE,
EIO_MLOCK, EIO_MLOCKALL,
EIO_UNLINK, EIO_RMDIR, EIO_MKDIR, EIO_RENAME,
EIO_MKNOD, EIO_READDIR,
@@ -183,8 +187,8 @@ struct eio_req
eio_req volatile *next; /* private ETP */
ssize_t result; /* result of syscall, e.g. result = read (... */
- off_t offs; /* read, write, truncate, readahead, sync_file_range: file offset, mknod: dev_t */
- size_t size; /* read, write, readahead, sendfile, msync, mlock, sync_file_range: length */
+ off_t offs; /* read, write, truncate, readahead, sync_file_range, fallocate: file offset, mknod: dev_t */
+ size_t size; /* read, write, readahead, sendfile, msync, mlock, sync_file_range, fallocate: length */
void *ptr1; /* all applicable requests: pathname, old name; readdir: optional eio_dirents */
void *ptr2; /* all applicable requests: new name or memory buffer; readdir: name strings */
eio_tstamp nv1; /* utime, futime: atime; busy: sleep time */
@@ -192,7 +196,7 @@ struct eio_req
int type; /* EIO_xxx constant ETP */
int int1; /* all applicable requests: file descriptor; sendfile: output fd; open, msync, mlockall, readdir: flags */
- long int2; /* chown, fchown: uid; sendfile: input fd; open, chmod, mkdir, mknod: file mode, sync_file_range: flags */
+ long int2; /* chown, fchown: uid; sendfile: input fd; open, chmod, mkdir, mknod: file mode, sync_file_range, fallocate: flags */
long int3; /* chown, fchown: gid */
int errorno; /* errno value on syscall return */
@@ -268,6 +272,7 @@ eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb
eio_req *eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data);
eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data);
eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data);
+eio_req *eio_fallocate (int fd, int mode, off_t offset, size_t len, int pri, eio_cb cb, void *data);
eio_req *eio_close (int fd, int pri, eio_cb cb, void *data);
eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data);
eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data);
diff --git a/eio.pod b/eio.pod
index fd5676e..b8152c2 100644
--- a/eio.pod
+++ b/eio.pod
@@ -595,6 +595,15 @@ as calling C<fdatasync>.
Flags can be any combination of C<EIO_SYNC_FILE_RANGE_WAIT_BEFORE>,
C<EIO_SYNC_FILE_RANGE_WRITE> and C<EIO_SYNC_FILE_RANGE_WAIT_AFTER>.
+=item eio_fallocate (int fd, int mode, off_t offset, off_t len, int pri, eio_cb cb, void *data)
+
+Calls C<fallocate> (note: I<NOT> C<posix_fallocate>!). If the syscall is
+missing, then it returns failure and sets C<errno> to C<ENOSYS>.
+
+The C<mode> argument can be C<0> (for behaviour similar to
+C<posix_fallocate>), or C<EIO_FALLOC_FL_KEEP_SIZE>, which keeps the size
+of the file unchanged (but still preallocates space beyond end of file).
+
=back
=head3 LIBEIO-SPECIFIC REQUESTS
diff --git a/libeio.m4 b/libeio.m4
index 32b81c2..08a0422 100644
--- a/libeio.m4
+++ b/libeio.m4
@@ -123,6 +123,21 @@ int main (void)
],ac_cv_sync_file_range=yes,ac_cv_sync_file_range=no)])
test $ac_cv_sync_file_range = yes && AC_DEFINE(HAVE_SYNC_FILE_RANGE, 1, sync_file_range(2) is available)
+AC_CACHE_CHECK(for fallocate, ac_cv_fallocate, [AC_LINK_IFELSE([
+#include <fcntl.h>
+int main (void)
+{
+ int fd = 0;
+ int mode = FALLOC_FL_KEEP_SIZE;
+ off_t offset = 1;
+ off_t len = 1;
+ int res;
+ res = fallocate (fd, mode, offset, len);
+ return 0;
+}
+],ac_cv_fallocate=yes,ac_cv_fallocate=no)])
+test $ac_cv_fallocate = yes && AC_DEFINE(HAVE_FALLOCATE, 1, fallocate(2) is available)
+
dnl #############################################################################
dnl # these checks exist for the benefit of IO::AIO