Commit 7e6d869f authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'fuse-fixes-5.6-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse

Pull fuse fix from Miklos Szeredi:
 "Fix an Oops introduced in v5.4"

* tag 'fuse-fixes-5.6-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
  fuse: fix stack use after return
parents 2af82177 3e8cb8b2
...@@ -276,12 +276,10 @@ static void flush_bg_queue(struct fuse_conn *fc) ...@@ -276,12 +276,10 @@ static void flush_bg_queue(struct fuse_conn *fc)
void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req) void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req)
{ {
struct fuse_iqueue *fiq = &fc->iq; struct fuse_iqueue *fiq = &fc->iq;
bool async;
if (test_and_set_bit(FR_FINISHED, &req->flags)) if (test_and_set_bit(FR_FINISHED, &req->flags))
goto put_request; goto put_request;
async = req->args->end;
/* /*
* test_and_set_bit() implies smp_mb() between bit * test_and_set_bit() implies smp_mb() between bit
* changing and below intr_entry check. Pairs with * changing and below intr_entry check. Pairs with
...@@ -324,7 +322,7 @@ void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req) ...@@ -324,7 +322,7 @@ void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req)
wake_up(&req->waitq); wake_up(&req->waitq);
} }
if (async) if (test_bit(FR_ASYNC, &req->flags))
req->args->end(fc, req->args, req->out.h.error); req->args->end(fc, req->args, req->out.h.error);
put_request: put_request:
fuse_put_request(fc, req); fuse_put_request(fc, req);
...@@ -471,6 +469,8 @@ static void fuse_args_to_req(struct fuse_req *req, struct fuse_args *args) ...@@ -471,6 +469,8 @@ static void fuse_args_to_req(struct fuse_req *req, struct fuse_args *args)
req->in.h.opcode = args->opcode; req->in.h.opcode = args->opcode;
req->in.h.nodeid = args->nodeid; req->in.h.nodeid = args->nodeid;
req->args = args; req->args = args;
if (args->end)
__set_bit(FR_ASYNC, &req->flags);
} }
ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args)
......
...@@ -301,6 +301,7 @@ struct fuse_io_priv { ...@@ -301,6 +301,7 @@ struct fuse_io_priv {
* FR_SENT: request is in userspace, waiting for an answer * FR_SENT: request is in userspace, waiting for an answer
* FR_FINISHED: request is finished * FR_FINISHED: request is finished
* FR_PRIVATE: request is on private list * FR_PRIVATE: request is on private list
* FR_ASYNC: request is asynchronous
*/ */
enum fuse_req_flag { enum fuse_req_flag {
FR_ISREPLY, FR_ISREPLY,
...@@ -314,6 +315,7 @@ enum fuse_req_flag { ...@@ -314,6 +315,7 @@ enum fuse_req_flag {
FR_SENT, FR_SENT,
FR_FINISHED, FR_FINISHED,
FR_PRIVATE, FR_PRIVATE,
FR_ASYNC,
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment