Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 501c4cae authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Greg Kroah-Hartman
Browse files

fuse: fix double request_end()



commit 87114373ea507895a62afb10d2910bd9adac35a8 upstream.

Refcounting of request is broken when fuse_abort_conn() is called and
request is on the fpq->io list:

 - ref is taken too late
 - then it is not dropped

Fixes: 0d8e84b0 ("fuse: simplify request abort")
Cc: <stable@vger.kernel.org> # v4.2
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 68fbfcb7
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -363,7 +363,7 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
	struct fuse_iqueue *fiq = &fc->iq;

	if (test_and_set_bit(FR_FINISHED, &req->flags))
		return;
		goto out_put_req;

	spin_lock(&fiq->waitq.lock);
	list_del_init(&req->intr_entry);
@@ -393,6 +393,7 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
	wake_up(&req->waitq);
	if (req->end)
		req->end(fc, req);
out_put_req:
	fuse_put_request(fc, req);
}

@@ -2097,6 +2098,7 @@ void fuse_abort_conn(struct fuse_conn *fc)
				set_bit(FR_ABORTED, &req->flags);
				if (!test_bit(FR_LOCKED, &req->flags)) {
					set_bit(FR_PRIVATE, &req->flags);
					__fuse_get_request(req);
					list_move(&req->list, &to_end1);
				}
				spin_unlock(&req->waitq.lock);
@@ -2123,7 +2125,6 @@ void fuse_abort_conn(struct fuse_conn *fc)

		while (!list_empty(&to_end1)) {
			req = list_first_entry(&to_end1, struct fuse_req, list);
			__fuse_get_request(req);
			list_del_init(&req->list);
			request_end(fc, req);
		}