diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-03-11 14:38:01 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-03-11 14:38:01 -0400 |
commit | 5e3771ce2d6a69e10fcc870cdf226d121d868491 (patch) | |
tree | 3c20ee45ae8b87621ae95cedb6b385bf0e6d7a2f | |
parent | 8a2cec295f4499cc9d4452e9b02d4ed071bb42d3 (diff) |
SUNRPC: Ensure that xs_nospace return values are propagated
If xs_nospace() finds that the socket has disconnected, it attempts to
return ENOTCONN, however that value is then squashed by the callers.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | net/sunrpc/xprtsock.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 9f3e615d3e09..2e070679ab4a 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -521,11 +521,12 @@ static void xs_nospace_callback(struct rpc_task *task) | |||
521 | * @task: task to put to sleep | 521 | * @task: task to put to sleep |
522 | * | 522 | * |
523 | */ | 523 | */ |
524 | static void xs_nospace(struct rpc_task *task) | 524 | static int xs_nospace(struct rpc_task *task) |
525 | { | 525 | { |
526 | struct rpc_rqst *req = task->tk_rqstp; | 526 | struct rpc_rqst *req = task->tk_rqstp; |
527 | struct rpc_xprt *xprt = req->rq_xprt; | 527 | struct rpc_xprt *xprt = req->rq_xprt; |
528 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 528 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
529 | int ret = 0; | ||
529 | 530 | ||
530 | dprintk("RPC: %5u xmit incomplete (%u left of %u)\n", | 531 | dprintk("RPC: %5u xmit incomplete (%u left of %u)\n", |
531 | task->tk_pid, req->rq_slen - req->rq_bytes_sent, | 532 | task->tk_pid, req->rq_slen - req->rq_bytes_sent, |
@@ -537,6 +538,7 @@ static void xs_nospace(struct rpc_task *task) | |||
537 | /* Don't race with disconnect */ | 538 | /* Don't race with disconnect */ |
538 | if (xprt_connected(xprt)) { | 539 | if (xprt_connected(xprt)) { |
539 | if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) { | 540 | if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) { |
541 | ret = -EAGAIN; | ||
540 | /* | 542 | /* |
541 | * Notify TCP that we're limited by the application | 543 | * Notify TCP that we're limited by the application |
542 | * window size | 544 | * window size |
@@ -548,10 +550,11 @@ static void xs_nospace(struct rpc_task *task) | |||
548 | } | 550 | } |
549 | } else { | 551 | } else { |
550 | clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); | 552 | clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); |
551 | task->tk_status = -ENOTCONN; | 553 | ret = -ENOTCONN; |
552 | } | 554 | } |
553 | 555 | ||
554 | spin_unlock_bh(&xprt->transport_lock); | 556 | spin_unlock_bh(&xprt->transport_lock); |
557 | return ret; | ||
555 | } | 558 | } |
556 | 559 | ||
557 | /** | 560 | /** |
@@ -603,7 +606,7 @@ static int xs_udp_send_request(struct rpc_task *task) | |||
603 | /* Should we call xs_close() here? */ | 606 | /* Should we call xs_close() here? */ |
604 | break; | 607 | break; |
605 | case -EAGAIN: | 608 | case -EAGAIN: |
606 | xs_nospace(task); | 609 | status = xs_nospace(task); |
607 | break; | 610 | break; |
608 | default: | 611 | default: |
609 | dprintk("RPC: sendmsg returned unrecognized error %d\n", | 612 | dprintk("RPC: sendmsg returned unrecognized error %d\n", |
@@ -706,7 +709,7 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
706 | /* Should we call xs_close() here? */ | 709 | /* Should we call xs_close() here? */ |
707 | break; | 710 | break; |
708 | case -EAGAIN: | 711 | case -EAGAIN: |
709 | xs_nospace(task); | 712 | status = xs_nospace(task); |
710 | break; | 713 | break; |
711 | default: | 714 | default: |
712 | dprintk("RPC: sendmsg returned unrecognized error %d\n", | 715 | dprintk("RPC: sendmsg returned unrecognized error %d\n", |