aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/file.c
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2006-06-25 08:48:52 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-25 13:01:19 -0400
commit33649c91a3df57c1090a657637d44b896de367e7 (patch)
tree1ee4871a65f2b37a931c796463eb39737a32cbaa /fs/fuse/file.c
parent7142125937e1482ad3ae4366594c6586153dfc86 (diff)
[PATCH] fuse: ensure FLUSH reaches userspace
All POSIX locks owned by the current task are removed on close(). If the FLUSH request resulting initiated by close() fails to reach userspace, there might be locks remaining, which cannot be removed. The only reason it could fail, is if allocating the request fails. In this case use the request reserved for RELEASE, or if that is currently used by another FLUSH, wait for it to become available. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/fuse/file.c')
-rw-r--r--fs/fuse/file.c13
1 files changed, 5 insertions, 8 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index d9a8289297c0..ce759414cff9 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -48,8 +48,8 @@ struct fuse_file *fuse_file_alloc(void)
48 struct fuse_file *ff; 48 struct fuse_file *ff;
49 ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL); 49 ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
50 if (ff) { 50 if (ff) {
51 ff->release_req = fuse_request_alloc(); 51 ff->reserved_req = fuse_request_alloc();
52 if (!ff->release_req) { 52 if (!ff->reserved_req) {
53 kfree(ff); 53 kfree(ff);
54 ff = NULL; 54 ff = NULL;
55 } 55 }
@@ -59,7 +59,7 @@ struct fuse_file *fuse_file_alloc(void)
59 59
60void fuse_file_free(struct fuse_file *ff) 60void fuse_file_free(struct fuse_file *ff)
61{ 61{
62 fuse_request_free(ff->release_req); 62 fuse_request_free(ff->reserved_req);
63 kfree(ff); 63 kfree(ff);
64} 64}
65 65
@@ -115,7 +115,7 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
115struct fuse_req *fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, 115struct fuse_req *fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags,
116 int opcode) 116 int opcode)
117{ 117{
118 struct fuse_req *req = ff->release_req; 118 struct fuse_req *req = ff->reserved_req;
119 struct fuse_release_in *inarg = &req->misc.release_in; 119 struct fuse_release_in *inarg = &req->misc.release_in;
120 120
121 inarg->fh = ff->fh; 121 inarg->fh = ff->fh;
@@ -187,10 +187,7 @@ static int fuse_flush(struct file *file, fl_owner_t id)
187 if (fc->no_flush) 187 if (fc->no_flush)
188 return 0; 188 return 0;
189 189
190 req = fuse_get_req(fc); 190 req = fuse_get_req_nofail(fc, file);
191 if (IS_ERR(req))
192 return PTR_ERR(req);
193
194 memset(&inarg, 0, sizeof(inarg)); 191 memset(&inarg, 0, sizeof(inarg));
195 inarg.fh = ff->fh; 192 inarg.fh = ff->fh;
196 inarg.lock_owner = fuse_lock_owner_id(id); 193 inarg.lock_owner = fuse_lock_owner_id(id);