[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>
This commit is contained in:
committed by
Linus Torvalds
parent
a8534adb74
commit
77e7f250f8
@@ -66,6 +66,12 @@ static void restore_sigs(sigset_t *oldset)
|
|||||||
sigprocmask(SIG_SETMASK, oldset, NULL);
|
sigprocmask(SIG_SETMASK, oldset, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset request, so that it can be reused
|
||||||
|
*
|
||||||
|
* The caller must be _very_ careful to make sure, that it is holding
|
||||||
|
* the only reference to req
|
||||||
|
*/
|
||||||
void fuse_reset_request(struct fuse_req *req)
|
void fuse_reset_request(struct fuse_req *req)
|
||||||
{
|
{
|
||||||
int preallocated = req->preallocated;
|
int preallocated = req->preallocated;
|
||||||
|
@@ -116,9 +116,14 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
|
|||||||
/* Special case for failed iget in CREATE */
|
/* Special case for failed iget in CREATE */
|
||||||
static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req)
|
static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req)
|
||||||
{
|
{
|
||||||
|
/* If called from end_io_requests(), req has more than one
|
||||||
|
reference and fuse_reset_request() cannot work */
|
||||||
|
if (fc->connected) {
|
||||||
u64 nodeid = req->in.h.nodeid;
|
u64 nodeid = req->in.h.nodeid;
|
||||||
fuse_reset_request(req);
|
fuse_reset_request(req);
|
||||||
fuse_send_forget(fc, req, nodeid, 1);
|
fuse_send_forget(fc, req, nodeid, 1);
|
||||||
|
} else
|
||||||
|
fuse_put_request(fc, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
|
void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
|
||||||
|
Reference in New Issue
Block a user