summaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 09:23:01 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 09:23:01 -0800
commit2171ee8f43968e8d6a2b4712d495e352e881c446 (patch)
tree354078e804c9d721b246c99f1c272d85b92acfb1 /net/sunrpc/xprt.c
parent9b9a72a8a370a1397fbb153d107e0d9fa8affb48 (diff)
parent666b3d803a511fbc9bc5e5ea8ce66010cf03ea13 (diff)
downloadlinux-stable-2171ee8f43968e8d6a2b4712d495e352e881c446.tar.gz
linux-stable-2171ee8f43968e8d6a2b4712d495e352e881c446.tar.bz2
linux-stable-2171ee8f43968e8d6a2b4712d495e352e881c446.zip
Merge tag 'nfs-for-3.9-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfixes from Trond Myklebust: - Fix an Oops in the pNFS layoutget code - Fix a number of NFSv4 and v4.1 state recovery deadlocks and hangs due to the interaction of the session drain lock and state management locks. - Remove task->tk_xprt, which was hiding a lot of RCU dereferencing bugs - Fix a long standing NFSv3 posix lock recovery bug. - Revert commit 324d003b0cd8 ("NFS: add nfs_sb_deactive_async to avoid deadlock"). It turned out that the root cause of the deadlock was due to interactions with the workqueues that have now been resolved. * tag 'nfs-for-3.9-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (22 commits) NLM: Ensure that we resend all pending blocking locks after a reclaim umount oops when remove blocklayoutdriver first sunrpc: silence build warning in gss_fill_context nfs: remove kfree() redundant null checks NFSv4.1: Don't decode skipped layoutgets NFSv4.1: Fix bulk recall and destroy of layouts NFSv4.1: Fix an ABBA locking issue with session and state serialisation NFSv4: Fix a reboot recovery race when opening a file NFSv4: Ensure delegation recall and byte range lock removal don't conflict NFSv4: Fix up the return values of nfs4_open_delegation_recall NFSv4.1: Don't lose locks when a server reboots during delegation return NFSv4.1: Prevent deadlocks between state recovery and file locking NFSv4: Allow the state manager to mark an open_owner as being recovered SUNRPC: Add missing static declaration to _gss_mech_get_by_name Revert "NFS: add nfs_sb_deactive_async to avoid deadlock" SUNRPC: Nuke the tk_xprt macro SUNRPC: Avoid RCU dereferences in the transport bind and connect code SUNRPC: Fix an RCU dereference in xprt_reserve SUNRPC: Pass pointers to struct rpc_xprt to the congestion window SUNRPC: Fix an RCU dereference in xs_local_rpcbind ...
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r--net/sunrpc/xprt.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 33811db8788a..846c34fdee9f 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -430,21 +430,23 @@ __xprt_put_cong(struct rpc_xprt *xprt, struct rpc_rqst *req)
*/
void xprt_release_rqst_cong(struct rpc_task *task)
{
- __xprt_put_cong(task->tk_xprt, task->tk_rqstp);
+ struct rpc_rqst *req = task->tk_rqstp;
+
+ __xprt_put_cong(req->rq_xprt, req);
}
EXPORT_SYMBOL_GPL(xprt_release_rqst_cong);
/**
* xprt_adjust_cwnd - adjust transport congestion window
+ * @xprt: pointer to xprt
* @task: recently completed RPC request used to adjust window
* @result: result code of completed RPC request
*
* We use a time-smoothed congestion estimator to avoid heavy oscillation.
*/
-void xprt_adjust_cwnd(struct rpc_task *task, int result)
+void xprt_adjust_cwnd(struct rpc_xprt *xprt, struct rpc_task *task, int result)
{
struct rpc_rqst *req = task->tk_rqstp;
- struct rpc_xprt *xprt = task->tk_xprt;
unsigned long cwnd = xprt->cwnd;
if (result >= 0 && cwnd <= xprt->cong) {
@@ -695,7 +697,7 @@ out_abort:
*/
void xprt_connect(struct rpc_task *task)
{
- struct rpc_xprt *xprt = task->tk_xprt;
+ struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt;
dprintk("RPC: %5u xprt_connect xprt %p %s connected\n", task->tk_pid,
xprt, (xprt_connected(xprt) ? "is" : "is not"));
@@ -722,13 +724,13 @@ void xprt_connect(struct rpc_task *task)
if (xprt_test_and_set_connecting(xprt))
return;
xprt->stat.connect_start = jiffies;
- xprt->ops->connect(task);
+ xprt->ops->connect(xprt, task);
}
}
static void xprt_connect_status(struct rpc_task *task)
{
- struct rpc_xprt *xprt = task->tk_xprt;
+ struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt;
if (task->tk_status == 0) {
xprt->stat.connect_count++;
@@ -832,7 +834,7 @@ static void xprt_timer(struct rpc_task *task)
spin_lock_bh(&xprt->transport_lock);
if (!req->rq_reply_bytes_recvd) {
if (xprt->ops->timer)
- xprt->ops->timer(task);
+ xprt->ops->timer(xprt, task);
} else
task->tk_status = 0;
spin_unlock_bh(&xprt->transport_lock);
@@ -1091,7 +1093,7 @@ EXPORT_SYMBOL_GPL(xprt_free);
*/
void xprt_reserve(struct rpc_task *task)
{
- struct rpc_xprt *xprt = task->tk_xprt;
+ struct rpc_xprt *xprt;
task->tk_status = 0;
if (task->tk_rqstp != NULL)
@@ -1099,7 +1101,10 @@ void xprt_reserve(struct rpc_task *task)
task->tk_timeout = 0;
task->tk_status = -EAGAIN;
+ rcu_read_lock();
+ xprt = rcu_dereference(task->tk_client->cl_xprt);
xprt->ops->alloc_slot(xprt, task);
+ rcu_read_unlock();
}
static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt)