diff options
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r-- | net/sunrpc/xprt.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index a0646a3b4a39..75d748eee0eb 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -606,6 +606,34 @@ void xprt_force_disconnect(struct rpc_xprt *xprt) | |||
606 | spin_unlock_bh(&xprt->transport_lock); | 606 | spin_unlock_bh(&xprt->transport_lock); |
607 | } | 607 | } |
608 | 608 | ||
609 | /** | ||
610 | * xprt_conditional_disconnect - force a transport to disconnect | ||
611 | * @xprt: transport to disconnect | ||
612 | * @cookie: 'connection cookie' | ||
613 | * | ||
614 | * This attempts to break the connection if and only if 'cookie' matches | ||
615 | * the current transport 'connection cookie'. It ensures that we don't | ||
616 | * try to break the connection more than once when we need to retransmit | ||
617 | * a batch of RPC requests. | ||
618 | * | ||
619 | */ | ||
620 | void xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie) | ||
621 | { | ||
622 | /* Don't race with the test_bit() in xprt_clear_locked() */ | ||
623 | spin_lock_bh(&xprt->transport_lock); | ||
624 | if (cookie != xprt->connect_cookie) | ||
625 | goto out; | ||
626 | if (test_bit(XPRT_CLOSING, &xprt->state) || !xprt_connected(xprt)) | ||
627 | goto out; | ||
628 | set_bit(XPRT_CLOSE_WAIT, &xprt->state); | ||
629 | /* Try to schedule an autoclose RPC call */ | ||
630 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) | ||
631 | queue_work(rpciod_workqueue, &xprt->task_cleanup); | ||
632 | xprt_wake_pending_tasks(xprt, -ENOTCONN); | ||
633 | out: | ||
634 | spin_unlock_bh(&xprt->transport_lock); | ||
635 | } | ||
636 | |||
609 | static void | 637 | static void |
610 | xprt_init_autodisconnect(unsigned long data) | 638 | xprt_init_autodisconnect(unsigned long data) |
611 | { | 639 | { |
@@ -849,6 +877,7 @@ void xprt_transmit(struct rpc_task *task) | |||
849 | } else if (!req->rq_bytes_sent) | 877 | } else if (!req->rq_bytes_sent) |
850 | return; | 878 | return; |
851 | 879 | ||
880 | req->rq_connect_cookie = xprt->connect_cookie; | ||
852 | status = xprt->ops->send_request(task); | 881 | status = xprt->ops->send_request(task); |
853 | if (status == 0) { | 882 | if (status == 0) { |
854 | dprintk("RPC: %5u xmit complete\n", task->tk_pid); | 883 | dprintk("RPC: %5u xmit complete\n", task->tk_pid); |