release() changes
authorMiklos Szeredi <miklos@szeredi.hu>
Wed, 11 Dec 2002 09:50:26 +0000 (09:50 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Wed, 11 Dec 2002 09:50:26 +0000 (09:50 +0000)
include/fuse.h
kernel/file.c
lib/fuse.c

index f92914fbb22dc48e170e6f70f5f4febc850b462d..30d5f80a982207e0979f9aa6b6644c991c637962 100644 (file)
@@ -102,7 +102,7 @@ struct fuse_operations {
     int (*read)     (const char *, char *, size_t, off_t);
     int (*write)    (const char *, const char *, size_t, off_t);
     int (*statfs)   (struct fuse_statfs *);
-    int (*release)  (const char *);
+    int (*release)  (const char *, int);
 };
 
 /** Extra context that may be needed by some filesystems */
index 0ba489244d940372de5ef8c1024e3fe6dd404b53..f4688f7ebc993fad55ae6a71d324e9c209f50c70 100644 (file)
@@ -44,18 +44,30 @@ static int fuse_release(struct inode *inode, struct file *file)
 {
        struct fuse_conn *fc = INO_FC(inode);
        struct fuse_in *in = NULL;
+       struct fuse_open_in *inarg = NULL;
 
        in = kmalloc(sizeof(struct fuse_in), GFP_NOFS);
        if(!in)
                return -ENOMEM;
-
        memset(in, 0, sizeof(struct fuse_in));
+       
+       inarg = kmalloc(sizeof(struct fuse_open_in), GFP_NOFS);
+       if(!inarg) 
+               goto out_free;
+       memset(inarg, 0, sizeof(struct fuse_open_in));
+
+       inarg->flags = file->f_flags & ~O_EXCL;
 
        in->h.opcode = FUSE_RELEASE;
        in->h.ino = inode->i_ino;
+       in->numargs = 1;
+       in->args[0].size = sizeof(struct fuse_open_in);
+       in->args[0].value = inarg;
        if(!request_send_noreply(fc, in))
                return 0;
 
+ out_free:
+       kfree(inarg);
        kfree(in);
        return 0;
 }
index 49199659d60577a560741a2cdf54960d520fc4c0..efe9e9706a4766b889f53176fd04ce040e357f3a 100644 (file)
@@ -758,19 +758,20 @@ static void do_open(struct fuse *f, struct fuse_in_header *in,
     if(path != NULL) {
         /* The open syscall was interrupted, so it must be cancelled */
         if(res == 0 && res2 == -ENOENT && f->op.release)
-            f->op.release(path);
+            f->op.release(path, arg->flags);
         free(path);
     }
 }
 
-static void do_release(struct fuse *f, struct fuse_in_header *in)
+static void do_release(struct fuse *f, struct fuse_in_header *in,
+                       struct fuse_open_in *arg)
 {
     char *path;
 
     path = get_path(f, in->ino);
     if(path != NULL) {
         if(f->op.release)
-            f->op.release(path);
+            f->op.release(path, arg->flags);
         free(path);
     }
 }
@@ -943,6 +944,10 @@ void __fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd)
         do_open(f, in, (struct fuse_open_in *) inarg);
         break;
 
+    case FUSE_RELEASE:
+        do_release(f, in, (struct fuse_open_in *) inarg);
+        break;
+
     case FUSE_READ:
         do_read(f, in, (struct fuse_read_in *) inarg);
         break;
@@ -955,12 +960,7 @@ void __fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd)
         do_statfs(f, in);
         break;
 
-    case FUSE_RELEASE:
-        do_release(f, in);
-        break;
-
     default:
-        fprintf(stderr, "Operation %i not implemented\n", in->opcode);
         send_reply(f, in, -ENOSYS, NULL, 0);
     }