summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes2
-rw-r--r--ecb.h4
-rw-r--r--eio.c50
-rw-r--r--eio.h3
-rw-r--r--eio.pod7
-rw-r--r--libeio.m412
6 files changed, 63 insertions, 15 deletions
diff --git a/Changes b/Changes
index fb2ad19..8ba9d31 100644
--- a/Changes
+++ b/Changes
@@ -56,4 +56,6 @@ TODO: fadvise request
- cancelled requests will still invoke their request callbacks.
- add fallocate.
- do not acquire any locks when forking.
+ - incorporated some mingw32 changes by traviscline.
+ - added syncfs support, using direct syscall.
diff --git a/ecb.h b/ecb.h
index 8414e6e..36f04fd 100644
--- a/ecb.h
+++ b/ecb.h
@@ -68,7 +68,7 @@
#ifndef ECB_MEMORY_FENCE
#if ECB_GCC_VERSION(2,5)
#if __x86
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; or.b $0, -1(%%esp)" : : : "memory")
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory")
#define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
#define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE /* better be safe than sorry */
#elif __amd64
@@ -84,7 +84,7 @@
#define ECB_MEMORY_FENCE __sync_synchronize ()
#define ECB_MEMORY_FENCE_ACQUIRE ({ char dummy = 0; __sync_lock_test_and_set (&dummy, 1); })
#define ECB_MEMORY_FENCE_RELEASE ({ char dummy = 1; __sync_lock_release (&dummy ); })
- #elif _MSC_VER >= 1400
+ #elif _MSC_VER >= 1400 && 0 /* TODO: only true when using volatiles */
#define ECB_MEMORY_FENCE do { } while (0)
#define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
#define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
diff --git a/eio.c b/eio.c
index ecf6f61..04985e1 100644
--- a/eio.c
+++ b/eio.c
@@ -218,6 +218,10 @@ static void eio_destroy (eio_req *req);
# endif
#endif
+#if HAVE_SYS_SYSCALL_H
+# include <sys/syscall.h>
+#endif
+
#ifndef D_TYPE
# define D_TYPE(de) 0
#endif
@@ -939,6 +943,24 @@ eio__futimes (int fd, const struct timeval tv[2])
# define fdatasync(fd) fsync (fd)
#endif
+static int
+eio__syncfs (int fd)
+{
+ int res;
+
+#if HAVE_SYS_SYNCFS
+ res = (int)syscall (__NR_syncfs, (int)(fd));
+#else
+ res = -1;
+ errno = ENOSYS;
+#endif
+
+ if (res < 0 && errno == ENOSYS && fd >= 0)
+ sync ();
+
+ return res;
+}
+
/* sync_file_range always needs emulation */
static int
eio__sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags)
@@ -2069,11 +2091,12 @@ eio_execute (etp_worker *self, eio_req *req)
case EIO_SYNC: req->result = 0; sync (); break;
case EIO_FSYNC: req->result = fsync (req->int1); break;
case EIO_FDATASYNC: req->result = fdatasync (req->int1); break;
+ case EIO_SYNCFS: req->result = eio__syncfs (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_MSYNC: req->result = eio__msync (req->ptr2, req->size, req->int1); break;
case EIO_MTOUCH: req->result = eio__mtouch (req); break;
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;
@@ -2164,6 +2187,21 @@ eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, vo
REQ (EIO_MSYNC); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND;
}
+eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data)
+{
+ REQ (EIO_FDATASYNC); req->int1 = fd; SEND;
+}
+
+eio_req *eio_syncfs (int fd, int pri, eio_cb cb, void *data)
+{
+ REQ (EIO_SYNCFS); req->int1 = fd; SEND;
+}
+
+eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data)
+{
+ REQ (EIO_SYNC_FILE_RANGE); req->int1 = fd; req->offs = offset; req->size = nbytes; req->int2 = flags; SEND;
+}
+
eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data)
{
REQ (EIO_MTOUCH); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND;
@@ -2179,21 +2217,11 @@ eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data)
REQ (EIO_MLOCKALL); req->int1 = flags; SEND;
}
-eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data)
-{
- 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;
-}
-
eio_req *eio_close (int fd, int pri, eio_cb cb, void *data)
{
REQ (EIO_CLOSE); req->int1 = fd; SEND;
diff --git a/eio.h b/eio.h
index d2c0612..bade4e7 100644
--- a/eio.h
+++ b/eio.h
@@ -179,7 +179,7 @@ enum
EIO_UTIME, EIO_FUTIME,
EIO_CHMOD, EIO_FCHMOD,
EIO_CHOWN, EIO_FCHOWN,
- EIO_SYNC, EIO_FSYNC, EIO_FDATASYNC,
+ EIO_SYNC, EIO_FSYNC, EIO_FDATASYNC, EIO_SYNCFS,
EIO_MSYNC, EIO_MTOUCH, EIO_SYNC_FILE_RANGE, EIO_FALLOCATE,
EIO_MLOCK, EIO_MLOCKALL,
EIO_UNLINK, EIO_RMDIR, EIO_MKDIR, EIO_RENAME,
@@ -292,6 +292,7 @@ eio_req *eio_busy (eio_tstamp delay, int pri, eio_cb cb, void *data); /* ti
eio_req *eio_sync (int pri, eio_cb cb, void *data);
eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data);
eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data);
+eio_req *eio_syncfs (int fd, int pri, eio_cb cb, void *data);
eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
eio_req *eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data);
diff --git a/eio.pod b/eio.pod
index 5c81d4b..da5f33c 100644
--- a/eio.pod
+++ b/eio.pod
@@ -594,6 +594,13 @@ use.
Calls C<readahead(2)>. If the syscall is missing, then the call is
emulated by simply reading the data (currently in 64kiB chunks).
+=item eio_syncfs (int fd, int pri, eio_cb cb, void *data)
+
+Calls Linux' C<syncfs> syscall, if available. Returns C<-1> and sets
+C<errno> to C<ENOSYS> if the call is missing I<but still calls sync()>,
+if the C<fd> is C<< >= 0 >>, so you can probe for the availability of the
+syscall with a negative C<fd> argument and checking for C<-1/ENOSYS>.
+
=item eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data)
Calls C<sync_file_range>. If the syscall is missing, then this is the same
diff --git a/libeio.m4 b/libeio.m4
index f6c7078..fb6591b 100644
--- a/libeio.m4
+++ b/libeio.m4
@@ -1,6 +1,6 @@
dnl openbsd in it's neverending brokenness requires stdint.h for intptr_t,
dnl but that header isn't very portable...
-AC_CHECK_HEADERS([stdint.h])
+AC_CHECK_HEADERS([stdint.h sys/syscall.h])
AC_SEARCH_LIBS(
pthread_create,
@@ -138,6 +138,16 @@ int main (void)
],ac_cv_fallocate=yes,ac_cv_fallocate=no)])
test $ac_cv_fallocate = yes && AC_DEFINE(HAVE_FALLOCATE, 1, fallocate(2) is available)
+AC_CACHE_CHECK(for sys_syncfs, ac_cv_sys_syncfs, [AC_LINK_IFELSE([
+#include <unistd.h>
+#include <sys/syscall.h>
+int main (void)
+{
+ int res = syscall (__NR_syncfs, (int)0);
+}
+],ac_cv_sys_syncfs=yes,ac_cv_sys_syncfs=no)])
+test $ac_cv_sys_syncfs = yes && AC_DEFINE(HAVE_SYS_SYNCFS, 1, syscall(__NR_syncfs) is available)
+
dnl #############################################################################
dnl # these checks exist for the benefit of IO::AIO