aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/fuse/file.c7
-rw-r--r--fs/fuse/fuse_i.h6
-rw-r--r--fs/fuse/inode.c2
3 files changed, 15 insertions, 0 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 471ea70be48d..c4c59c7d0038 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -56,6 +56,7 @@ struct fuse_file *fuse_file_alloc(void)
56 kfree(ff); 56 kfree(ff);
57 ff = NULL; 57 ff = NULL;
58 } 58 }
59 INIT_LIST_HEAD(&ff->write_entry);
59 atomic_set(&ff->count, 0); 60 atomic_set(&ff->count, 0);
60 } 61 }
61 return ff; 62 return ff;
@@ -150,12 +151,18 @@ int fuse_release_common(struct inode *inode, struct file *file, int isdir)
150{ 151{
151 struct fuse_file *ff = file->private_data; 152 struct fuse_file *ff = file->private_data;
152 if (ff) { 153 if (ff) {
154 struct fuse_conn *fc = get_fuse_conn(inode);
155
153 fuse_release_fill(ff, get_node_id(inode), file->f_flags, 156 fuse_release_fill(ff, get_node_id(inode), file->f_flags,
154 isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); 157 isdir ? FUSE_RELEASEDIR : FUSE_RELEASE);
155 158
156 /* Hold vfsmount and dentry until release is finished */ 159 /* Hold vfsmount and dentry until release is finished */
157 ff->reserved_req->vfsmount = mntget(file->f_path.mnt); 160 ff->reserved_req->vfsmount = mntget(file->f_path.mnt);
158 ff->reserved_req->dentry = dget(file->f_path.dentry); 161 ff->reserved_req->dentry = dget(file->f_path.dentry);
162
163 spin_lock(&fc->lock);
164 list_del(&ff->write_entry);
165 spin_unlock(&fc->lock);
159 /* 166 /*
160 * Normally this will send the RELEASE request, 167 * Normally this will send the RELEASE request,
161 * however if some asynchronous READ or WRITE requests 168 * however if some asynchronous READ or WRITE requests
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index b24fc9b386f8..5657cca0d0cb 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -70,6 +70,9 @@ struct fuse_inode {
70 70
71 /** Version of last attribute change */ 71 /** Version of last attribute change */
72 u64 attr_version; 72 u64 attr_version;
73
74 /** Files usable in writepage. Protected by fc->lock */
75 struct list_head write_files;
73}; 76};
74 77
75/** FUSE specific file data */ 78/** FUSE specific file data */
@@ -82,6 +85,9 @@ struct fuse_file {
82 85
83 /** Refcount */ 86 /** Refcount */
84 atomic_t count; 87 atomic_t count;
88
89 /** Entry on inode's write_files list */
90 struct list_head write_entry;
85}; 91};
86 92
87/** One input argument of a request */ 93/** One input argument of a request */
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 3c13981f48e2..49d716036ea7 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -56,6 +56,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
56 fi->i_time = 0; 56 fi->i_time = 0;
57 fi->nodeid = 0; 57 fi->nodeid = 0;
58 fi->nlookup = 0; 58 fi->nlookup = 0;
59 INIT_LIST_HEAD(&fi->write_files);
59 fi->forget_req = fuse_request_alloc(); 60 fi->forget_req = fuse_request_alloc();
60 if (!fi->forget_req) { 61 if (!fi->forget_req) {
61 kmem_cache_free(fuse_inode_cachep, inode); 62 kmem_cache_free(fuse_inode_cachep, inode);
@@ -68,6 +69,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
68static void fuse_destroy_inode(struct inode *inode) 69static void fuse_destroy_inode(struct inode *inode)
69{ 70{
70 struct fuse_inode *fi = get_fuse_inode(inode); 71 struct fuse_inode *fi = get_fuse_inode(inode);
72 BUG_ON(!list_empty(&fi->write_files));
71 if (fi->forget_req) 73 if (fi->forget_req)
72 fuse_request_free(fi->forget_req); 74 fuse_request_free(fi->forget_req);
73 kmem_cache_free(fuse_inode_cachep, inode); 75 kmem_cache_free(fuse_inode_cachep, inode);