提交 034b91a3 编写于 作者: L Latchesar Ionkov 提交者: Linus Torvalds

[PATCH] v9fs: fix corner cases when flushing request

When v9fs_mux_rpc sends a 9P message, it may be put in the queue of unsent
request.  If the user process receives a signal, v9fs_mux_rpc sets the
request error to ERREQFLUSH and assigns NULL to request's send message.  If
the message was still in the unsent queue, v9fs_write_work would produce an
oops while processing it.

The patch makes sure that requests that are being flushed are moved to the
pending requests queue safely.

If a request is being flushed, don't remove it from the list of pending
requests even if it receives a reply before the flush is acknoledged.  The
request will be removed during from the Rflush handler (v9fs_mux_flush_cb).
Signed-off-by: NLatchesar Ionkov <lucho@ionkov.net>
Cc: Eric Van Hensbergen <ericvh@ericvh.myip.org>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 05818a00
...@@ -471,10 +471,13 @@ static void v9fs_write_work(void *a) ...@@ -471,10 +471,13 @@ static void v9fs_write_work(void *a)
} }
spin_lock(&m->lock); spin_lock(&m->lock);
req = again:
list_entry(m->unsent_req_list.next, struct v9fs_req, req = list_entry(m->unsent_req_list.next, struct v9fs_req,
req_list); req_list);
list_move_tail(&req->req_list, &m->req_list); list_move_tail(&req->req_list, &m->req_list);
if (req->err == ERREQFLUSH)
goto again;
m->wbuf = req->tcall->sdata; m->wbuf = req->tcall->sdata;
m->wsize = req->tcall->size; m->wsize = req->tcall->size;
m->wpos = 0; m->wpos = 0;
...@@ -525,7 +528,7 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) ...@@ -525,7 +528,7 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req)
struct v9fs_str *ename; struct v9fs_str *ename;
tag = req->tag; tag = req->tag;
if (req->rcall->id == RERROR && !req->err) { if (!req->err && req->rcall->id == RERROR) {
ecode = req->rcall->params.rerror.errno; ecode = req->rcall->params.rerror.errno;
ename = &req->rcall->params.rerror.error; ename = &req->rcall->params.rerror.error;
...@@ -551,7 +554,10 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) ...@@ -551,7 +554,10 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req)
req->err = -EIO; req->err = -EIO;
} }
if (req->cb && req->err != ERREQFLUSH) { if (req->err == ERREQFLUSH)
return;
if (req->cb) {
dprintk(DEBUG_MUX, "calling callback tcall %p rcall %p\n", dprintk(DEBUG_MUX, "calling callback tcall %p rcall %p\n",
req->tcall, req->rcall); req->tcall, req->rcall);
...@@ -812,6 +818,7 @@ v9fs_mux_rpc_cb(void *a, struct v9fs_fcall *tc, struct v9fs_fcall *rc, int err) ...@@ -812,6 +818,7 @@ v9fs_mux_rpc_cb(void *a, struct v9fs_fcall *tc, struct v9fs_fcall *rc, int err)
struct v9fs_mux_rpc *r; struct v9fs_mux_rpc *r;
if (err == ERREQFLUSH) { if (err == ERREQFLUSH) {
kfree(rc);
dprintk(DEBUG_MUX, "err req flush\n"); dprintk(DEBUG_MUX, "err req flush\n");
return; return;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册