fix
authorMiklos Szeredi <miklos@szeredi.hu>
Sat, 2 Sep 2006 09:51:08 +0000 (09:51 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Sat, 2 Sep 2006 09:51:08 +0000 (09:51 +0000)
ChangeLog
example/fusexmp.c
example/fusexmp_fh.c
include/fuse.h
lib/fuse.c
lib/fuse_lowlevel.c

index 81e0b7f7a4414539893e74e8227526d4c581fa2d..acee04020a4fee73d2dd24f832776d27314defc9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2006-09-01  Miklos Szeredi <miklos@szeredi.hu>
+
+       * Fix recursive lock bug in interrupt handling
+
+       * Add utimes() method to highlevel interface, which supports
+       setting times with nanosecond resolution
+
 2006-08-18  Miklos Szeredi <miklos@szeredi.hu>
 
        * kernel: fix page leak if fuse_readpages() failed in it's
index a30c9fd63e30d84d0f44956a1cb4453ef491728b..5f5466713ba65e932099e172c80f00d221f06fa2 100644 (file)
@@ -20,6 +20,7 @@
 #include <fcntl.h>
 #include <dirent.h>
 #include <errno.h>
+#include <sys/time.h>
 #ifdef HAVE_SETXATTR
 #include <sys/xattr.h>
 #endif
@@ -204,18 +205,23 @@ static int xmp_truncate(const char *path, off_t size)
     return 0;
 }
 
-static int xmp_utime(const char *path, struct utimbuf *buf)
+static int xmp_utimes(const char *path, const struct timespec ts[2])
 {
     int res;
+    struct timeval tv[2];
 
-    res = utime(path, buf);
+    tv[0].tv_sec = ts[0].tv_sec;
+    tv[0].tv_usec = ts[0].tv_nsec / 1000;
+    tv[1].tv_sec = ts[1].tv_sec;
+    tv[1].tv_usec = ts[1].tv_nsec / 1000;
+
+    res = utimes(path, tv);
     if (res == -1)
         return -errno;
 
     return 0;
 }
 
-
 static int xmp_open(const char *path, struct fuse_file_info *fi)
 {
     int res;
@@ -351,7 +357,7 @@ static struct fuse_operations xmp_oper = {
     .chmod     = xmp_chmod,
     .chown     = xmp_chown,
     .truncate  = xmp_truncate,
-    .utime     = xmp_utime,
+    .utimes    = xmp_utimes,
     .open      = xmp_open,
     .read      = xmp_read,
     .write     = xmp_write,
index c82d061c15e6046f55efe864f494213323eb3602..5ede6db83faa123ca1c1d3b1f0bd5e752a5a0f71 100644 (file)
@@ -17,6 +17,7 @@
 #include <fcntl.h>
 #include <dirent.h>
 #include <errno.h>
+#include <sys/time.h>
 #ifdef HAVE_SETXATTR
 #include <sys/xattr.h>
 #endif
@@ -239,11 +240,17 @@ static int xmp_ftruncate(const char *path, off_t size,
     return 0;
 }
 
-static int xmp_utime(const char *path, struct utimbuf *buf)
+static int xmp_utimes(const char *path, const struct timespec ts[2])
 {
     int res;
+    struct timeval tv[2];
 
-    res = utime(path, buf);
+    tv[0].tv_sec = ts[0].tv_sec;
+    tv[0].tv_usec = ts[0].tv_nsec / 1000;
+    tv[1].tv_sec = ts[1].tv_sec;
+    tv[1].tv_usec = ts[1].tv_nsec / 1000;
+
+    res = utimes(path, tv);
     if (res == -1)
         return -errno;
 
@@ -412,7 +419,7 @@ static struct fuse_operations xmp_oper = {
     .chown     = xmp_chown,
     .truncate  = xmp_truncate,
     .ftruncate = xmp_ftruncate,
-    .utime     = xmp_utime,
+    .utimes    = xmp_utimes,
     .create    = xmp_create,
     .open      = xmp_open,
     .read      = xmp_read,
index d9041b279baf348db7bba7f04c2b3d7c9d54f0a9..8a18914c2ea6ebaa2a19176ebdc0af325fe9d576 100644 (file)
@@ -23,6 +23,7 @@
 #include "fuse_common.h"
 
 #include <fcntl.h>
+#include <time.h>
 #include <utime.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -129,7 +130,10 @@ struct fuse_operations {
     /** Change the size of a file */
     int (*truncate) (const char *, off_t);
 
-    /** Change the access and/or modification times of a file */
+    /** Change the access and/or modification times of a file
+     *
+     * Deprecated, use utimes() instead.
+     */
     int (*utime) (const char *, struct utimbuf *);
 
     /** File open operation
@@ -386,6 +390,9 @@ struct fuse_operations {
      */
     int (*lock) (const char *, struct fuse_file_info *, int cmd,
                  struct flock *, uint64_t owner);
+
+    /** Change the access and modification times of a file */
+    int (*utimes) (const char *, const struct timespec tv[2]);
 };
 
 /** Extra context that may be needed by some filesystems
index 48951927513acf175e5ac7bf7647e3219e64f59e..0a3b5551779b990a868f5774003789b2bdd89703 100644 (file)
@@ -753,15 +753,22 @@ static int do_truncate(struct fuse *f, const char *path, struct stat *attr,
     return err;
 }
 
-static int do_utime(struct fuse *f, const char *path, struct stat *attr)
+static int do_utimes(struct fuse *f, const char *path, struct stat *attr)
 {
     int err;
-    struct utimbuf buf;
-    buf.actime = attr->st_atime;
-    buf.modtime = attr->st_mtime;
+
     err = -ENOSYS;
-    if (f->op.utime)
+    if (f->op.utimes) {
+        struct timespec tv[2];
+        tv[0] = attr->st_atim;
+        tv[1] = attr->st_mtim;
+        err = f->op.utimes(path, tv);
+    } else if (f->op.utime) {
+        struct utimbuf buf;
+        buf.actime = attr->st_atime;
+        buf.modtime = attr->st_mtime;
         err = f->op.utime(path, &buf);
+    }
 
     return err;
 }
@@ -788,7 +795,7 @@ static void fuse_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
             if (!err && (valid & FUSE_SET_ATTR_SIZE))
                 err = do_truncate(f, path, attr, fi);
             if (!err && (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) == (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))
-                err = do_utime(f, path, attr);
+                err = do_utimes(f, path, attr);
             if (!err)
                 err = f->op.getattr(path, &buf);
         }
index 677ef7995da42d16282eec995101364175a77b16..cd1e571b4926f6056f336391b4af6f691ea509a6 100644 (file)
@@ -868,20 +868,25 @@ static void do_interrupt(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
     pthread_mutex_unlock(&f->lock);
 }
 
-static void check_interrupt(struct fuse_ll *f, struct fuse_req *req)
+static struct fuse_req *check_interrupt(struct fuse_ll *f, struct fuse_req *req)
 {
     struct fuse_req *curr;
 
     for (curr = f->interrupts.next; curr != &f->interrupts; curr = curr->next) {
         if (curr->u.i.unique == req->unique) {
+            req->interrupted = 1;
             list_del_req(curr);
             free(curr);
-            return;
+            return NULL;
         }
     }
     curr = f->interrupts.next;
-    if (curr != &f->interrupts)
-        fuse_reply_err(curr, EAGAIN);
+    if (curr != &f->interrupts) {
+        list_del_req(curr);
+        list_init_req(curr);
+        return curr;
+    } else
+        return NULL;
 }
 
 static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
@@ -1062,10 +1067,13 @@ static void fuse_ll_process(void *data, const char *buf, size_t len,
         fuse_reply_err(req, ENOSYS);
     else {
         if (in->opcode != FUSE_INTERRUPT) {
+            struct fuse_req *intr;
             pthread_mutex_lock(&f->lock);
-            check_interrupt(f, req);
+            intr = check_interrupt(f, req);
             list_add_req(req, &f->list);
             pthread_mutex_unlock(&f->lock);
+            if (intr)
+                fuse_reply_err(intr, EAGAIN);
         }
         fuse_ll_ops[in->opcode].func(req, in->nodeid, inarg);
     }