Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 92932
b: refs/heads/master
c: 7c1d71c
h: refs/heads/master
v: v3
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Apr 19, 2008
1 parent a52c572 commit ab326a6
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 636ac43318ce6939c1698fb67e714d421314ed71
refs/heads/master: 7c1d71cf56feebfb5b98219b9d11dfc3a2feca62
8 changes: 8 additions & 0 deletions trunk/include/linux/sunrpc/xprt.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ struct rpc_rqst {
unsigned long rq_majortimeo; /* major timeout alarm */
unsigned long rq_timeout; /* Current timeout value */
unsigned int rq_retries; /* # of retries */
unsigned int rq_connect_cookie;
/* A cookie used to track the
state of the transport
connection */

/*
* Partial send handling
Expand Down Expand Up @@ -152,6 +156,9 @@ struct rpc_xprt {
unsigned long connect_timeout,
bind_timeout,
reestablish_timeout;
unsigned int connect_cookie; /* A cookie that gets bumped
every time the transport
is reconnected */

/*
* Disconnection of idle transports
Expand Down Expand Up @@ -241,6 +248,7 @@ void xprt_complete_rqst(struct rpc_task *task, int copied);
void xprt_release_rqst_cong(struct rpc_task *task);
void xprt_disconnect_done(struct rpc_xprt *xprt);
void xprt_force_disconnect(struct rpc_xprt *xprt);
void xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie);

/*
* Reserved bit positions in xprt->state
Expand Down
6 changes: 4 additions & 2 deletions trunk/net/sunrpc/clnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,8 @@ call_status(struct rpc_task *task)
case -ETIMEDOUT:
task->tk_action = call_timeout;
if (task->tk_client->cl_discrtry)
xprt_force_disconnect(task->tk_xprt);
xprt_conditional_disconnect(task->tk_xprt,
req->rq_connect_cookie);
break;
case -ECONNREFUSED:
case -ENOTCONN:
Expand Down Expand Up @@ -1245,7 +1246,8 @@ call_decode(struct rpc_task *task)
if (task->tk_rqstp == req) {
req->rq_received = req->rq_rcv_buf.len = 0;
if (task->tk_client->cl_discrtry)
xprt_force_disconnect(task->tk_xprt);
xprt_conditional_disconnect(task->tk_xprt,
req->rq_connect_cookie);
}
}

Expand Down
29 changes: 29 additions & 0 deletions trunk/net/sunrpc/xprt.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,34 @@ void xprt_force_disconnect(struct rpc_xprt *xprt)
spin_unlock_bh(&xprt->transport_lock);
}

/**
* xprt_conditional_disconnect - force a transport to disconnect
* @xprt: transport to disconnect
* @cookie: 'connection cookie'
*
* This attempts to break the connection if and only if 'cookie' matches
* the current transport 'connection cookie'. It ensures that we don't
* try to break the connection more than once when we need to retransmit
* a batch of RPC requests.
*
*/
void xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie)
{
/* Don't race with the test_bit() in xprt_clear_locked() */
spin_lock_bh(&xprt->transport_lock);
if (cookie != xprt->connect_cookie)
goto out;
if (test_bit(XPRT_CLOSING, &xprt->state) || !xprt_connected(xprt))
goto out;
set_bit(XPRT_CLOSE_WAIT, &xprt->state);
/* Try to schedule an autoclose RPC call */
if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
queue_work(rpciod_workqueue, &xprt->task_cleanup);
xprt_wake_pending_tasks(xprt, -ENOTCONN);
out:
spin_unlock_bh(&xprt->transport_lock);
}

static void
xprt_init_autodisconnect(unsigned long data)
{
Expand Down Expand Up @@ -849,6 +877,7 @@ void xprt_transmit(struct rpc_task *task)
} else if (!req->rq_bytes_sent)
return;

req->rq_connect_cookie = xprt->connect_cookie;
status = xprt->ops->send_request(task);
if (status == 0) {
dprintk("RPC: %5u xmit complete\n", task->tk_pid);
Expand Down
2 changes: 2 additions & 0 deletions trunk/net/sunrpc/xprtsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,7 @@ static void xs_tcp_state_change(struct sock *sk)
break;
case TCP_FIN_WAIT1:
/* The client initiated a shutdown of the socket */
xprt->connect_cookie++;
xprt->reestablish_timeout = 0;
set_bit(XPRT_CLOSING, &xprt->state);
smp_mb__before_clear_bit();
Expand All @@ -1154,6 +1155,7 @@ static void xs_tcp_state_change(struct sock *sk)
set_bit(XPRT_CLOSING, &xprt->state);
xprt_force_disconnect(xprt);
case TCP_SYN_SENT:
xprt->connect_cookie++;
case TCP_CLOSING:
/*
* If the server closed down the connection, make sure that
Expand Down

0 comments on commit ab326a6

Please sign in to comment.