diff options
Diffstat (limited to 'net/9p/client.c')
-rw-r--r-- | net/9p/client.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 9186550d77a6..0004cbaac4a4 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -415,9 +415,17 @@ static void p9_free_req(struct p9_client *c, struct p9_req_t *r) | |||
415 | * req: request received | 415 | * req: request received |
416 | * | 416 | * |
417 | */ | 417 | */ |
418 | void p9_client_cb(struct p9_client *c, struct p9_req_t *req) | 418 | void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status) |
419 | { | 419 | { |
420 | p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc->tag); | 420 | p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc->tag); |
421 | |||
422 | /* | ||
423 | * This barrier is needed to make sure any change made to req before | ||
424 | * the other thread wakes up will indeed be seen by the waiting side. | ||
425 | */ | ||
426 | smp_wmb(); | ||
427 | req->status = status; | ||
428 | |||
421 | wake_up(req->wq); | 429 | wake_up(req->wq); |
422 | p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag); | 430 | p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag); |
423 | } | 431 | } |
@@ -655,16 +663,13 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq) | |||
655 | if (IS_ERR(req)) | 663 | if (IS_ERR(req)) |
656 | return PTR_ERR(req); | 664 | return PTR_ERR(req); |
657 | 665 | ||
658 | |||
659 | /* | 666 | /* |
660 | * if we haven't received a response for oldreq, | 667 | * if we haven't received a response for oldreq, |
661 | * remove it from the list | 668 | * remove it from the list |
662 | */ | 669 | */ |
663 | if (oldreq->status == REQ_STATUS_FLSH) { | 670 | if (oldreq->status == REQ_STATUS_SENT) |
664 | spin_lock(&c->lock); | 671 | if (c->trans_mod->cancelled) |
665 | list_del(&oldreq->req_list); | 672 | c->trans_mod->cancelled(c, oldreq); |
666 | spin_unlock(&c->lock); | ||
667 | } | ||
668 | 673 | ||
669 | p9_free_req(c, req); | 674 | p9_free_req(c, req); |
670 | return 0; | 675 | return 0; |
@@ -751,6 +756,12 @@ again: | |||
751 | err = wait_event_interruptible(*req->wq, | 756 | err = wait_event_interruptible(*req->wq, |
752 | req->status >= REQ_STATUS_RCVD); | 757 | req->status >= REQ_STATUS_RCVD); |
753 | 758 | ||
759 | /* | ||
760 | * Make sure our req is coherent with regard to updates in other | ||
761 | * threads - echoes to wmb() in the callback | ||
762 | */ | ||
763 | smp_rmb(); | ||
764 | |||
754 | if ((err == -ERESTARTSYS) && (c->status == Connected) | 765 | if ((err == -ERESTARTSYS) && (c->status == Connected) |
755 | && (type == P9_TFLUSH)) { | 766 | && (type == P9_TFLUSH)) { |
756 | sigpending = 1; | 767 | sigpending = 1; |