Skip to content

Commit

Permalink
[PATCH] v9fs: fix corner cases when flushing request
Browse files Browse the repository at this point in the history
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: Latchesar Ionkov <lucho@ionkov.net>
Cc: Eric Van Hensbergen <ericvh@ericvh.myip.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Latchesar Ionkov authored and Linus Torvalds committed Feb 3, 2006
1 parent 05818a0 commit 034b91a
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions fs/9p/mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,10 +471,13 @@ static void v9fs_write_work(void *a)
}

spin_lock(&m->lock);
req =
list_entry(m->unsent_req_list.next, struct v9fs_req,
again:
req = list_entry(m->unsent_req_list.next, struct v9fs_req,
req_list);
list_move_tail(&req->req_list, &m->req_list);
if (req->err == ERREQFLUSH)
goto again;

m->wbuf = req->tcall->sdata;
m->wsize = req->tcall->size;
m->wpos = 0;
Expand Down Expand Up @@ -525,7 +528,7 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req)
struct v9fs_str *ename;

tag = req->tag;
if (req->rcall->id == RERROR && !req->err) {
if (!req->err && req->rcall->id == RERROR) {
ecode = req->rcall->params.rerror.errno;
ename = &req->rcall->params.rerror.error;

Expand All @@ -551,7 +554,10 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req)
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",
req->tcall, req->rcall);

Expand Down Expand Up @@ -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;

if (err == ERREQFLUSH) {
kfree(rc);
dprintk(DEBUG_MUX, "err req flush\n");
return;
}
Expand Down

0 comments on commit 034b91a

Please sign in to comment.