]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
fuse: add file kernel handle
authorTejun Heo <tj@kernel.org>
Wed, 26 Nov 2008 11:03:55 +0000 (12:03 +0100)
committerMiklos Szeredi <miklos@szeredi.hu>
Wed, 26 Nov 2008 11:03:55 +0000 (12:03 +0100)
The file handle, fuse_file->fh, is opaque value supplied by userland
FUSE server and uniqueness is not guaranteed.  Add file kernel handle,
fuse_file->kh, which is allocated by the kernel on file allocation and
guaranteed to be unique.

This will be used by poll to match notification to the respective file
but can be used for other purposes where unique file handle is
necessary.

Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c

index 9e7c5385699f410e69c16a95a5bf86e1f30818ee..16ae55d347bb5d394b597ad82edf04a05cade37f 100644 (file)
@@ -408,7 +408,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
                goto out_put_forget_req;
 
        err = -ENOMEM;
-       ff = fuse_file_alloc();
+       ff = fuse_file_alloc(fc);
        if (!ff)
                goto out_put_request;
 
index baed06ea76227324b1778433b08e7f2675dfa0c2..a28ced678d38d96c8fc4e1276be1b529d829af60 100644 (file)
@@ -46,7 +46,7 @@ static int fuse_send_open(struct inode *inode, struct file *file, int isdir,
        return err;
 }
 
-struct fuse_file *fuse_file_alloc(void)
+struct fuse_file *fuse_file_alloc(struct fuse_conn *fc)
 {
        struct fuse_file *ff;
        ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
@@ -58,6 +58,9 @@ struct fuse_file *fuse_file_alloc(void)
                } else {
                        INIT_LIST_HEAD(&ff->write_entry);
                        atomic_set(&ff->count, 0);
+                       spin_lock(&fc->lock);
+                       ff->kh = ++fc->khctr;
+                       spin_unlock(&fc->lock);
                }
        }
        return ff;
@@ -108,6 +111,7 @@ void fuse_finish_open(struct inode *inode, struct file *file,
 
 int fuse_open_common(struct inode *inode, struct file *file, int isdir)
 {
+       struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_open_out outarg;
        struct fuse_file *ff;
        int err;
@@ -120,7 +124,7 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
        if (err)
                return err;
 
-       ff = fuse_file_alloc();
+       ff = fuse_file_alloc(fc);
        if (!ff)
                return -ENOMEM;
 
index 4fc5131f5c9d266132d72faa254d9b21e5aae5ef..86f0133038289e9ae4bf08cb9caabf7d7ff22413 100644 (file)
@@ -100,6 +100,9 @@ struct fuse_file {
        /** Request reserved for flush and release */
        struct fuse_req *reserved_req;
 
+       /** Kernel file handle guaranteed to be unique */
+       u64 kh;
+
        /** File handle used by userspace */
        u64 fh;
 
@@ -322,6 +325,9 @@ struct fuse_conn {
        /** The list of requests under I/O */
        struct list_head io;
 
+       /** The next unique kernel file handle */
+       u64 khctr;
+
        /** Number of requests currently in the background */
        unsigned num_background;
 
@@ -499,7 +505,7 @@ void fuse_read_fill(struct fuse_req *req, struct file *file,
  */
 int fuse_open_common(struct inode *inode, struct file *file, int isdir);
 
-struct fuse_file *fuse_file_alloc(void);
+struct fuse_file *fuse_file_alloc(struct fuse_conn *fc);
 void fuse_file_free(struct fuse_file *ff);
 void fuse_finish_open(struct inode *inode, struct file *file,
                      struct fuse_file *ff, struct fuse_open_out *outarg);
index fa474989ec7618440fd2f47aa9c99045368a9ff2..0e15bc221d230ee740edaa4ccc50b2d7c4015db4 100644 (file)
@@ -485,6 +485,7 @@ static struct fuse_conn *new_conn(struct super_block *sb)
                fc->bdi.unplug_io_fn = default_unplug_io_fn;
                /* fuse does it's own writeback accounting */
                fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB;
+               fc->khctr = 0;
                fc->dev = sb->s_dev;
                err = bdi_init(&fc->bdi);
                if (err)