Skip to content

Commit

Permalink
[PATCH] fuse: fix request_end()
Browse files Browse the repository at this point in the history
This function used the request object after decrementing its reference count
and releasing the lock.  This could in theory lead to all sorts of problems.

Fix and simplify at the same time.

Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Miklos Szeredi authored and Linus Torvalds committed Jan 17, 2006
1 parent 222f1d6 commit f43b155
Showing 1 changed file with 7 additions and 11 deletions.
18 changes: 7 additions & 11 deletions fs/fuse/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,19 +171,17 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
/*
* This function is called when a request is finished. Either a reply
* has arrived or it was interrupted (and not yet sent) or some error
* occurred during communication with userspace, or the device file was
* closed. It decreases the reference count for the request. In case
* of a background request the reference to the stored objects are
* released. The requester thread is woken up (if still waiting), and
* finally the request is either freed or put on the unused_list
* occurred during communication with userspace, or the device file
* was closed. In case of a background request the reference to the
* stored objects are released. The requester thread is woken up (if
* still waiting), and finally the reference to the request is
* released
*
* Called with fuse_lock, unlocks it
*/
static void request_end(struct fuse_conn *fc, struct fuse_req *req)
{
int putback;
req->finished = 1;
putback = atomic_dec_and_test(&req->count);
spin_unlock(&fuse_lock);
if (req->background) {
down_read(&fc->sbput_sem);
Expand All @@ -197,13 +195,11 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
else if (req->in.h.opcode == FUSE_RELEASE && req->inode == NULL) {
/* Special case for failed iget in CREATE */
u64 nodeid = req->in.h.nodeid;
__fuse_get_request(req);
fuse_reset_request(req);
fuse_send_forget(fc, req, nodeid, 1);
putback = 0;
return;
}
if (putback)
fuse_putback_request(fc, req);
fuse_put_request(fc, req);
}

/*
Expand Down

0 comments on commit f43b155

Please sign in to comment.