Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[PATCH] fuse: fix bug in aborted fuse_release_end()

There's a rather theoretical case of the BUG triggering in
fuse_reset_request():

- iget() fails because of OOM after a successful CREATE_OPEN request
- during IO on the resulting RELEASE request the connection is aborted

Fix and add warning to fuse_reset_request().

Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Miklos Szeredi and committed by
Linus Torvalds
77e7f250 a8534adb

+14 -3
+6
fs/fuse/dev.c
··· 66 66 sigprocmask(SIG_SETMASK, oldset, NULL); 67 67 } 68 68 69 + /* 70 + * Reset request, so that it can be reused 71 + * 72 + * The caller must be _very_ careful to make sure, that it is holding 73 + * the only reference to req 74 + */ 69 75 void fuse_reset_request(struct fuse_req *req) 70 76 { 71 77 int preallocated = req->preallocated;
+8 -3
fs/fuse/file.c
··· 116 116 /* Special case for failed iget in CREATE */ 117 117 static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req) 118 118 { 119 - u64 nodeid = req->in.h.nodeid; 120 - fuse_reset_request(req); 121 - fuse_send_forget(fc, req, nodeid, 1); 119 + /* If called from end_io_requests(), req has more than one 120 + reference and fuse_reset_request() cannot work */ 121 + if (fc->connected) { 122 + u64 nodeid = req->in.h.nodeid; 123 + fuse_reset_request(req); 124 + fuse_send_forget(fc, req, nodeid, 1); 125 + } else 126 + fuse_put_request(fc, req); 122 127 } 123 128 124 129 void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,