From d94cbd62828958bc2eff4815b2dcf0d4a52e19b4 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 7 Jul 2011 22:36:18 +0000 Subject: fallocate --- Changes | 1 + eio.c | 17 +++++++++++++++++ eio.h | 21 +++++++++++++-------- eio.pod | 9 +++++++++ libeio.m4 | 15 +++++++++++++++ 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. Flags can be any combination of C, C and C. +=item eio_fallocate (int fd, int mode, off_t offset, off_t len, int pri, eio_cb cb, void *data) + +Calls C (note: I C!). If the syscall is +missing, then it returns failure and sets C to C. + +The C argument can be C<0> (for behaviour similar to +C), or C, 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 +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 -- cgit v1.2.3