From 66af1e558538137080615e7ad6d1f2f80862de01 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 6 Nov 2007 10:18:36 -0500 Subject: SUNRPC: Fix a race in xs_tcp_state_change() When scheduling the autoclose RPC call, we want to ensure that we don't race against the test_bit() call in xprt_clear_locked(). Signed-off-by: Trond Myklebust --- net/sunrpc/xprt.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'net/sunrpc/xprt.c') diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index fb92f51405c..a3af02168af 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -570,6 +570,7 @@ static void xprt_autoclose(struct work_struct *work) xprt_disconnect(xprt); xprt->ops->close(xprt); + clear_bit(XPRT_CLOSE_WAIT, &xprt->state); xprt_release_write(xprt, NULL); } @@ -588,6 +589,25 @@ void xprt_disconnect(struct rpc_xprt *xprt) } EXPORT_SYMBOL_GPL(xprt_disconnect); +/** + * xprt_force_disconnect - force a transport to disconnect + * @xprt: transport to disconnect + * + */ +void xprt_force_disconnect(struct rpc_xprt *xprt) +{ + /* Don't race with the test_bit() in xprt_clear_locked() */ + spin_lock_bh(&xprt->transport_lock); + 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); + else if (xprt->snd_task != NULL) + rpc_wake_up_task(xprt->snd_task); + spin_unlock_bh(&xprt->transport_lock); +} +EXPORT_SYMBOL_GPL(xprt_force_disconnect); + static void xprt_init_autodisconnect(unsigned long data) { -- cgit From 7272dcd31d56580dee7693c21e369fd167e137fe Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 6 Nov 2007 18:28:53 -0500 Subject: SUNRPC: xprt_autoclose() should not call xprt_disconnect() The transport layer should do that itself whenever appropriate. Note that the RDMA transport already assumes that it needs to call xprt_disconnect in xprt_rdma_close(). For TCP sockets, we want to call xprt_disconnect() only after the connection has been closed by both ends. Signed-off-by: Trond Myklebust --- net/sunrpc/xprt.c | 1 - 1 file changed, 1 deletion(-) (limited to 'net/sunrpc/xprt.c') diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index a3af02168af..80742995e02 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -568,7 +568,6 @@ static void xprt_autoclose(struct work_struct *work) struct rpc_xprt *xprt = container_of(work, struct rpc_xprt, task_cleanup); - xprt_disconnect(xprt); xprt->ops->close(xprt); clear_bit(XPRT_CLOSE_WAIT, &xprt->state); xprt_release_write(xprt, NULL); -- cgit From 62da3b24880bccd4ffc32cf8d9a7e23fab475bdd Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 6 Nov 2007 18:44:20 -0500 Subject: SUNRPC: Rename xprt_disconnect() xprt_disconnect() should really only be called when the transport shutdown is completed, and it is time to wake up any pending tasks. Rename it to xprt_disconnect_done() in order to reflect the semantical change. Signed-off-by: Trond Myklebust --- net/sunrpc/xprt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'net/sunrpc/xprt.c') diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 80742995e02..592c2ee63e0 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -574,11 +574,11 @@ static void xprt_autoclose(struct work_struct *work) } /** - * xprt_disconnect - mark a transport as disconnected + * xprt_disconnect_done - mark a transport as disconnected * @xprt: transport to flag for disconnect * */ -void xprt_disconnect(struct rpc_xprt *xprt) +void xprt_disconnect_done(struct rpc_xprt *xprt) { dprintk("RPC: disconnected transport %p\n", xprt); spin_lock_bh(&xprt->transport_lock); @@ -586,7 +586,7 @@ void xprt_disconnect(struct rpc_xprt *xprt) xprt_wake_pending_tasks(xprt, -ENOTCONN); spin_unlock_bh(&xprt->transport_lock); } -EXPORT_SYMBOL_GPL(xprt_disconnect); +EXPORT_SYMBOL_GPL(xprt_disconnect_done); /** * xprt_force_disconnect - force a transport to disconnect -- cgit From a6eaf8bdf9308b51ec84e358915fc65400029519 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 14 Jul 2007 15:39:58 -0400 Subject: SUNRPC: Move exported declarations to the function declarations Do this for all RPC client related functions and XDR functions. Signed-off-by: Trond Myklebust --- net/sunrpc/xprt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net/sunrpc/xprt.c') diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 592c2ee63e0..1fd47f918bb 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -992,6 +992,7 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long i to->to_retries = retr; to->to_exponential = 0; } +EXPORT_SYMBOL(xprt_set_timeout); /** * xprt_create_transport - create an RPC transport -- cgit From e8914c65f7f8d4e8701b8e78a12b714872ea0402 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 14 Jul 2007 15:39:59 -0400 Subject: SUNRPC: Restrict sunrpc client exports The sunrpc client exports are not meant to be part of any official kernel API: they can change at the drop of a hat. Mark them as internal functions using EXPORT_SYMBOL_GPL. Signed-off-by: Trond Myklebust --- net/sunrpc/xprt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/sunrpc/xprt.c') diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 1fd47f918bb..7520c6623c4 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -992,7 +992,7 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long i to->to_retries = retr; to->to_exponential = 0; } -EXPORT_SYMBOL(xprt_set_timeout); +EXPORT_SYMBOL_GPL(xprt_set_timeout); /** * xprt_create_transport - create an RPC transport -- cgit From 2881ae74e68ecfe3b32a90936e5d93a9ba598c3a Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 20 Dec 2007 16:03:54 -0500 Subject: SUNRPC: Clean up the transport timeout initialisation Signed-off-by: Trond Myklebust --- net/sunrpc/xprt.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'net/sunrpc/xprt.c') diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 7520c6623c4..2bc99569c58 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -977,23 +977,6 @@ void xprt_release(struct rpc_task *task) spin_unlock(&xprt->reserve_lock); } -/** - * xprt_set_timeout - set constant RPC timeout - * @to: RPC timeout parameters to set up - * @retr: number of retries - * @incr: amount of increase after each retry - * - */ -void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr) -{ - to->to_initval = - to->to_increment = incr; - to->to_maxval = to->to_initval + (incr * retr); - to->to_retries = retr; - to->to_exponential = 0; -} -EXPORT_SYMBOL_GPL(xprt_set_timeout); - /** * xprt_create_transport - create an RPC transport * @args: rpc transport creation arguments -- cgit From ba7392bb37cb12781890f45d7ddee1618e33a036 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 20 Dec 2007 16:03:55 -0500 Subject: SUNRPC: Add support for per-client timeout values In order to be able to support setting the timeo and retrans parameters on a per-mountpoint basis, we move the rpc_timeout structure into the rpc_clnt. Signed-off-by: Trond Myklebust --- net/sunrpc/xprt.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'net/sunrpc/xprt.c') diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 2bc99569c58..cfcade906a5 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -501,9 +501,10 @@ EXPORT_SYMBOL_GPL(xprt_set_retrans_timeout_def); void xprt_set_retrans_timeout_rtt(struct rpc_task *task) { int timer = task->tk_msg.rpc_proc->p_timer; - struct rpc_rtt *rtt = task->tk_client->cl_rtt; + struct rpc_clnt *clnt = task->tk_client; + struct rpc_rtt *rtt = clnt->cl_rtt; struct rpc_rqst *req = task->tk_rqstp; - unsigned long max_timeout = req->rq_xprt->timeout.to_maxval; + unsigned long max_timeout = clnt->cl_timeout->to_maxval; task->tk_timeout = rpc_calc_rto(rtt, timer); task->tk_timeout <<= rpc_ntimeo(rtt, timer) + req->rq_retries; @@ -514,7 +515,7 @@ EXPORT_SYMBOL_GPL(xprt_set_retrans_timeout_rtt); static void xprt_reset_majortimeo(struct rpc_rqst *req) { - struct rpc_timeout *to = &req->rq_xprt->timeout; + const struct rpc_timeout *to = req->rq_task->tk_client->cl_timeout; req->rq_majortimeo = req->rq_timeout; if (to->to_exponential) @@ -534,7 +535,7 @@ static void xprt_reset_majortimeo(struct rpc_rqst *req) int xprt_adjust_timeout(struct rpc_rqst *req) { struct rpc_xprt *xprt = req->rq_xprt; - struct rpc_timeout *to = &xprt->timeout; + const struct rpc_timeout *to = req->rq_task->tk_client->cl_timeout; int status = 0; if (time_before(jiffies, req->rq_majortimeo)) { @@ -928,7 +929,7 @@ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt) { struct rpc_rqst *req = task->tk_rqstp; - req->rq_timeout = xprt->timeout.to_initval; + req->rq_timeout = task->tk_client->cl_timeout->to_initval; req->rq_task = task; req->rq_xprt = xprt; req->rq_buffer = NULL; -- cgit