add fuse_invalidate() to library API
authorMiklos Szeredi <miklos@szeredi.hu>
Thu, 29 Jul 2004 09:27:49 +0000 (09:27 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Thu, 29 Jul 2004 09:27:49 +0000 (09:27 +0000)
ChangeLog
example/hello.c
include/fuse.h
kernel/dev.c
lib/fuse.c

index e64b898ee137b0d56e0cc1edb98a153334e73b6d..085a01fe22170439a85e1c3324ae1009fe8d09ea 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2004-07-29  Miklos Szeredi <miklos@szeredi.hu>
+
+       * Add fuse_invalidate() to library API
+
 2004-07-26  Miklos Szeredi <miklos@szeredi.hu>
 
        * Check permissions in setattr if 'default_permissions' flag is
index da2a9ee62c1c9d735abe54d3f8d59d51f5e8b579..040c835ced3abda1d1f947b3134c36f881c2f1f2 100644 (file)
@@ -60,10 +60,18 @@ static int hello_open(const char *path, int flags)
 
 static int hello_read(const char *path, char *buf, size_t size, off_t offset)
 {
+    size_t len;
     if(strcmp(path, hello_path) != 0)
         return -ENOENT;
     
-    memcpy(buf, hello_str + offset, size);
+    len = strlen(hello_str);
+    if (offset < len) {
+        if (offset + size > len)
+            size = len - offset;
+        memcpy(buf, hello_str + offset, size);
+    } else
+        size = 0;
+
     return size;
 }
 
index 726b681a132b3cecae619ec4ce58c54bd3aa17c8..845e64580ac352eac269c7c0dd3d9eb4a19f391d 100644 (file)
@@ -171,6 +171,16 @@ void fuse_main(int argc, char *argv[], const struct fuse_operations *op);
  */
 struct fuse *fuse_get(void);
 
+/**
+ * Invalidate cached data of a file.
+ *
+ * Useful if the 'kernel_cache' mount option is given, since in that
+ * case the cache is not invalidated on file open.
+ *
+ * @return 0 on success or -errno on failure
+ */
+int fuse_invalidate(struct fuse *f, const char *path);
+
 /* ----------------------------------------------------------- *
  * More detailed API                                           *
  * ----------------------------------------------------------- */
index a12820d57217ea0ed3dba2277a168118f9faa233..07c19ee72dca170fe1d3a7b1bbeaa17059cab36b 100644 (file)
@@ -422,6 +422,7 @@ static int fuse_invalidate(struct fuse_conn *fc, struct fuse_user_header *uh)
        struct inode *inode = ilookup(fc->sb, uh->ino);
        if (!inode)
                return -ENOENT;
+       fuse_sync_inode(inode);
        invalidate_inode_pages(inode->i_mapping);
        iput(inode);
        return 0;
@@ -433,6 +434,7 @@ static int fuse_invalidate(struct fuse_conn *fc, struct fuse_user_header *uh)
        int err = -ENOENT;
        if (inode) {
                if (INO_FI(inode)) {
+                       fuse_sync_inode(inode);
                        invalidate_inode_pages(inode);
                        err = 0;
                }
@@ -453,7 +455,7 @@ static int fuse_user_request(struct fuse_conn *fc, const char *buf,
                return -EINVAL;
        }
 
-       if (copy_from_user(&uh, buf, sizeof(struct fuse_out_header)))
+       if (copy_from_user(&uh, buf, sizeof(struct fuse_user_header)))
                return -EFAULT;
        
        switch (uh.opcode) {
index 80c14883d024bcb2f31f3e5ca192b75a233d40de..671fbcc2bcbdf82e1698d9b0c89b7ba70fabcc62 100644 (file)
@@ -225,6 +225,37 @@ static struct node *find_node(struct fuse *f, fino_t parent, char *name,
     return node;
 }
 
+static int path_lookup(struct fuse *f, const char *path, fino_t *inop)
+{
+    fino_t ino;
+    int err;
+    char *s;
+    char *name;
+    char *tmp = strdup(path);
+    if (!tmp)
+        return -ENOMEM;
+
+    pthread_mutex_lock(&f->lock);
+    ino = FUSE_ROOT_INO;
+    err = 0;
+    for  (s = tmp; (name = strsep(&s, "/")) != NULL; ) {
+        if (name[0]) {
+            struct node *node = __lookup_node(f, ino, name);
+            if (node == NULL) {
+                err = -ENOENT;
+                break;
+            }
+            ino = node->ino;
+        }
+    }
+    pthread_mutex_unlock(&f->lock);
+    free(tmp);
+    if (!err)
+        *inop = ino;
+    
+    return err;
+}
+
 static char *add_name(char *buf, char *s, const char *name)
 {
     size_t len = strlen(name);
@@ -1544,6 +1575,40 @@ void fuse_loop(struct fuse *f)
     }
 }
 
+int fuse_invalidate(struct fuse *f, const char *path)
+{
+    int res;
+    int err;
+    fino_t ino;
+    struct fuse_user_header h;
+
+    err = path_lookup(f, path, &ino);
+    if (err) {
+        if (err == -ENOENT)
+            return 0;
+        else
+            return err;
+    }
+
+    memset(&h, 0, sizeof(struct fuse_user_header));
+    h.opcode = FUSE_INVALIDATE;
+    h.ino = ino;
+    
+    if ((f->flags & FUSE_DEBUG)) {
+        printf("INVALIDATE ino: %li\n", ino);
+        fflush(stdout);
+    }
+
+    res = write(f->fd, &h, sizeof(struct fuse_user_header));
+    if (res == -1) {
+        if (errno != ENOENT) {
+            perror("fuse: writing device");
+            return -errno;
+        }
+    }
+    return 0;
+}
+
 void fuse_exit(struct fuse *f)
 {
     f->exited = 1;