All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] SUNRPC: Clean up xprt_release()
@ 2010-04-16 20:47 Trond Myklebust
  2010-04-16 20:47 ` [PATCH] SUNRPC: Cleanup - make rpc_new_task() call rpc_release_calldata on failure Trond Myklebust
  0 siblings, 1 reply; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 20:47 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
 net/sunrpc/xprt.c |   32 ++++++++++++++++----------------
 1 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 42f09ad..18415cc 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -62,7 +62,6 @@
  * Local functions
  */
 static void	xprt_request_init(struct rpc_task *, struct rpc_xprt *);
-static inline void	do_xprt_reserve(struct rpc_task *);
 static void	xprt_connect_status(struct rpc_task *task);
 static int      __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);
 
@@ -935,7 +934,7 @@ void xprt_transmit(struct rpc_task *task)
 	spin_unlock_bh(&xprt->transport_lock);
 }
 
-static inline void do_xprt_reserve(struct rpc_task *task)
+static void xprt_alloc_slot(struct rpc_task *task)
 {
 	struct rpc_xprt	*xprt = task->tk_xprt;
 
@@ -955,6 +954,16 @@ static inline void do_xprt_reserve(struct rpc_task *task)
 	rpc_sleep_on(&xprt->backlog, task, NULL);
 }
 
+static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
+{
+	memset(req, 0, sizeof(*req));	/* mark unused */
+
+	spin_lock(&xprt->reserve_lock);
+	list_add(&req->rq_list, &xprt->free);
+	rpc_wake_up_next(&xprt->backlog);
+	spin_unlock(&xprt->reserve_lock);
+}
+
 /**
  * xprt_reserve - allocate an RPC request slot
  * @task: RPC task requesting a slot allocation
@@ -968,7 +977,7 @@ void xprt_reserve(struct rpc_task *task)
 
 	task->tk_status = -EIO;
 	spin_lock(&xprt->reserve_lock);
-	do_xprt_reserve(task);
+	xprt_alloc_slot(task);
 	spin_unlock(&xprt->reserve_lock);
 }
 
@@ -1006,14 +1015,10 @@ void xprt_release(struct rpc_task *task)
 {
 	struct rpc_xprt	*xprt;
 	struct rpc_rqst	*req;
-	int is_bc_request;
 
 	if (!(req = task->tk_rqstp))
 		return;
 
-	/* Preallocated backchannel request? */
-	is_bc_request = bc_prealloc(req);
-
 	xprt = req->rq_xprt;
 	rpc_count_iostats(task);
 	spin_lock_bh(&xprt->transport_lock);
@@ -1027,21 +1032,16 @@ void xprt_release(struct rpc_task *task)
 		mod_timer(&xprt->timer,
 				xprt->last_used + xprt->idle_timeout);
 	spin_unlock_bh(&xprt->transport_lock);
-	if (!bc_prealloc(req))
+	if (req->rq_buffer)
 		xprt->ops->buf_free(req->rq_buffer);
 	task->tk_rqstp = NULL;
 	if (req->rq_release_snd_buf)
 		req->rq_release_snd_buf(req);
 
 	dprintk("RPC: %5u release request %p\n", task->tk_pid, req);
-	if (likely(!is_bc_request)) {
-		memset(req, 0, sizeof(*req));	/* mark unused */
-
-		spin_lock(&xprt->reserve_lock);
-		list_add(&req->rq_list, &xprt->free);
-		rpc_wake_up_next(&xprt->backlog);
-		spin_unlock(&xprt->reserve_lock);
-	} else
+	if (likely(!bc_prealloc(req)))
+		xprt_free_slot(xprt, req);
+	else
 		xprt_free_bc_request(req);
 }
 
-- 
1.6.6.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH] SUNRPC: Cleanup - make rpc_new_task() call rpc_release_calldata on failure
  2010-04-16 20:47 [PATCH] SUNRPC: Clean up xprt_release() Trond Myklebust
@ 2010-04-16 20:47 ` Trond Myklebust
  2010-04-16 20:47   ` [PATCH] SUNRPC: Move the test for XPRT_CONNECTING into xprt_connect() Trond Myklebust
  0 siblings, 1 reply; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 20:47 UTC (permalink / raw)
  To: linux-nfs

Also have it return an ERR_PTR(-ENOMEM) instead of a null pointer.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
 net/sunrpc/clnt.c  |   19 ++++---------------
 net/sunrpc/sched.c |   13 ++++++++++---
 2 files changed, 14 insertions(+), 18 deletions(-)

diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 19c9983..8c7b543 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -556,26 +556,16 @@ static const struct rpc_call_ops rpc_default_ops = {
  */
 struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
 {
-	struct rpc_task *task, *ret;
+	struct rpc_task *task;
 
 	task = rpc_new_task(task_setup_data);
-	if (task == NULL) {
-		rpc_release_calldata(task_setup_data->callback_ops,
-				task_setup_data->callback_data);
-		ret = ERR_PTR(-ENOMEM);
+	if (IS_ERR(task))
 		goto out;
-	}
 
-	if (task->tk_status != 0) {
-		ret = ERR_PTR(task->tk_status);
-		rpc_put_task(task);
-		goto out;
-	}
 	atomic_inc(&task->tk_count);
 	rpc_execute(task);
-	ret = task;
 out:
-	return ret;
+	return task;
 }
 EXPORT_SYMBOL_GPL(rpc_run_task);
 
@@ -657,9 +647,8 @@ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req,
 	 * Create an rpc_task to send the data
 	 */
 	task = rpc_new_task(&task_setup_data);
-	if (!task) {
+	if (IS_ERR(task)) {
 		xprt_free_bc_request(req);
-		task = ERR_PTR(-ENOMEM);
 		goto out;
 	}
 	task->tk_rqstp = req;
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index aae6907..c8979ce 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -856,16 +856,23 @@ struct rpc_task *rpc_new_task(const struct rpc_task_setup *setup_data)
 
 	if (task == NULL) {
 		task = rpc_alloc_task();
-		if (task == NULL)
-			goto out;
+		if (task == NULL) {
+			rpc_release_calldata(setup_data->callback_ops,
+					setup_data->callback_data);
+			return ERR_PTR(-ENOMEM);
+		}
 		flags = RPC_TASK_DYNAMIC;
 	}
 
 	rpc_init_task(task, setup_data);
+	if (task->tk_status < 0) {
+		int err = task->tk_status;
+		rpc_put_task(task);
+		return ERR_PTR(err);
+	}
 
 	task->tk_flags |= flags;
 	dprintk("RPC:       allocated task %p\n", task);
-out:
 	return task;
 }
 
-- 
1.6.6.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH] SUNRPC: Move the test for XPRT_CONNECTING into xprt_connect()
  2010-04-16 20:47 ` [PATCH] SUNRPC: Cleanup - make rpc_new_task() call rpc_release_calldata on failure Trond Myklebust
@ 2010-04-16 20:47   ` Trond Myklebust
  2010-04-16 20:47     ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
  0 siblings, 1 reply; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 20:47 UTC (permalink / raw)
  To: linux-nfs

This fixes a bug with setting xprt->stat.connect_start.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
 net/sunrpc/xprt.c               |    6 +++++-
 net/sunrpc/xprtrdma/transport.c |   28 +++++++++++++---------------
 net/sunrpc/xprtsock.c           |   15 +--------------
 3 files changed, 19 insertions(+), 30 deletions(-)

diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 18415cc..c71d835 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -712,10 +712,14 @@ void xprt_connect(struct rpc_task *task)
 
 		task->tk_timeout = xprt->connect_timeout;
 		rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
+
+		if (test_bit(XPRT_CLOSING, &xprt->state))
+			return;
+		if (xprt_test_and_set_connecting(xprt))
+			return;
 		xprt->stat.connect_start = jiffies;
 		xprt->ops->connect(task);
 	}
-	return;
 }
 
 static void xprt_connect_status(struct rpc_task *task)
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 187257b..0607b9a 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -449,21 +449,19 @@ xprt_rdma_connect(struct rpc_task *task)
 	struct rpc_xprt *xprt = (struct rpc_xprt *)task->tk_xprt;
 	struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
 
-	if (!xprt_test_and_set_connecting(xprt)) {
-		if (r_xprt->rx_ep.rep_connected != 0) {
-			/* Reconnect */
-			schedule_delayed_work(&r_xprt->rdma_connect,
-				xprt->reestablish_timeout);
-			xprt->reestablish_timeout <<= 1;
-			if (xprt->reestablish_timeout > (30 * HZ))
-				xprt->reestablish_timeout = (30 * HZ);
-			else if (xprt->reestablish_timeout < (5 * HZ))
-				xprt->reestablish_timeout = (5 * HZ);
-		} else {
-			schedule_delayed_work(&r_xprt->rdma_connect, 0);
-			if (!RPC_IS_ASYNC(task))
-				flush_scheduled_work();
-		}
+	if (r_xprt->rx_ep.rep_connected != 0) {
+		/* Reconnect */
+		schedule_delayed_work(&r_xprt->rdma_connect,
+			xprt->reestablish_timeout);
+		xprt->reestablish_timeout <<= 1;
+		if (xprt->reestablish_timeout > (30 * HZ))
+			xprt->reestablish_timeout = (30 * HZ);
+		else if (xprt->reestablish_timeout < (5 * HZ))
+			xprt->reestablish_timeout = (5 * HZ);
+	} else {
+		schedule_delayed_work(&r_xprt->rdma_connect, 0);
+		if (!RPC_IS_ASYNC(task))
+			flush_scheduled_work();
 	}
 }
 
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 9847c30..d138afa 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2016,9 +2016,6 @@ static void xs_connect(struct rpc_task *task)
 	struct rpc_xprt *xprt = task->tk_xprt;
 	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
 
-	if (xprt_test_and_set_connecting(xprt))
-		return;
-
 	if (transport->sock != NULL && !RPC_IS_SOFTCONN(task)) {
 		dprintk("RPC:       xs_connect delayed xprt %p for %lu "
 				"seconds\n",
@@ -2038,16 +2035,6 @@ static void xs_connect(struct rpc_task *task)
 	}
 }
 
-static void xs_tcp_connect(struct rpc_task *task)
-{
-	struct rpc_xprt *xprt = task->tk_xprt;
-
-	/* Exit if we need to wait for socket shutdown to complete */
-	if (test_bit(XPRT_CLOSING, &xprt->state))
-		return;
-	xs_connect(task);
-}
-
 /**
  * xs_udp_print_stats - display UDP socket-specifc stats
  * @xprt: rpc_xprt struct containing statistics
@@ -2246,7 +2233,7 @@ static struct rpc_xprt_ops xs_tcp_ops = {
 	.release_xprt		= xs_tcp_release_xprt,
 	.rpcbind		= rpcb_getport_async,
 	.set_port		= xs_set_port,
-	.connect		= xs_tcp_connect,
+	.connect		= xs_connect,
 	.buf_alloc		= rpc_malloc,
 	.buf_free		= rpc_free,
 	.send_request		= xs_tcp_send_request,
-- 
1.6.6.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH] SUNRPC: Fail over more quickly on connect errors
  2010-04-16 20:47   ` [PATCH] SUNRPC: Move the test for XPRT_CONNECTING into xprt_connect() Trond Myklebust
@ 2010-04-16 20:47     ` Trond Myklebust
  2010-04-16 20:47       ` [PATCH] NFSv4: Allow attribute caching with 'noac' mounts if client holds a delegation Trond Myklebust
  2010-04-16 22:29       ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
  0 siblings, 2 replies; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 20:47 UTC (permalink / raw)
  To: linux-nfs

We should not allow soft tasks to wait for longer than the major timeout
period when waiting for a reconnect to occur.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
 net/sunrpc/xprt.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index c71d835..01449a3 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -710,7 +710,7 @@ void xprt_connect(struct rpc_task *task)
 		if (task->tk_rqstp)
 			task->tk_rqstp->rq_bytes_sent = 0;
 
-		task->tk_timeout = xprt->connect_timeout;
+		task->tk_timeout = min(req->rq_timeout, xprt->connect_timeout);
 		rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
 
 		if (test_bit(XPRT_CLOSING, &xprt->state))
-- 
1.6.6.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH] NFSv4: Allow attribute caching with 'noac' mounts if client holds a delegation
  2010-04-16 20:47     ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
@ 2010-04-16 20:47       ` Trond Myklebust
  2010-04-16 20:47         ` [PATCH] NFSv4: Clean up the NFSv4 setclientid operation Trond Myklebust
  2010-04-16 22:29       ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
  1 sibling, 1 reply; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 20:47 UTC (permalink / raw)
  To: linux-nfs

If the server has given us a delegation on a file, we _know_ that we can
cache the attribute information even when the user has specified 'noac'.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
 fs/nfs/file.c  |   15 +++++++++------
 fs/nfs/inode.c |   12 +++++++++---
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 8d965bd..cac96bc 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -161,14 +161,17 @@ static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs_inode *nfsi = NFS_I(inode);
 
-	if (server->flags & NFS_MOUNT_NOAC)
-		goto force_reval;
+	if (nfs_have_delegated_attributes(inode))
+		goto out_noreval;
+
 	if (filp->f_flags & O_DIRECT)
 		goto force_reval;
-	if (nfsi->npages != 0)
-		return 0;
-	if (!(nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) && !nfs_attribute_timeout(inode))
-		return 0;
+	if (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
+		goto force_reval;
+	if (nfs_attribute_timeout(inode))
+		goto force_reval;
+out_noreval:
+	return 0;
 force_reval:
 	return __nfs_revalidate_inode(server, inode);
 }
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 50a56ed..69da585 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -730,9 +730,14 @@ int nfs_attribute_timeout(struct inode *inode)
 {
 	struct nfs_inode *nfsi = NFS_I(inode);
 
+	return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
+}
+
+static int nfs_attribute_cache_expired(struct inode *inode)
+{
 	if (nfs_have_delegated_attributes(inode))
 		return 0;
-	return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
+	return nfs_attribute_timeout(inode);
 }
 
 /**
@@ -745,7 +750,7 @@ int nfs_attribute_timeout(struct inode *inode)
 int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
 {
 	if (!(NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATTR)
-			&& !nfs_attribute_timeout(inode))
+			&& !nfs_attribute_cache_expired(inode))
 		return NFS_STALE(inode) ? -ESTALE : 0;
 	return __nfs_revalidate_inode(server, inode);
 }
@@ -782,7 +787,8 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
 	int ret = 0;
 
 	if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
-			|| nfs_attribute_timeout(inode) || NFS_STALE(inode)) {
+			|| nfs_attribute_cache_expired(inode)
+			|| NFS_STALE(inode)) {
 		ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
 		if (ret < 0)
 			goto out;
-- 
1.6.6.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH] NFSv4: Clean up the NFSv4 setclientid operation
  2010-04-16 20:47       ` [PATCH] NFSv4: Allow attribute caching with 'noac' mounts if client holds a delegation Trond Myklebust
@ 2010-04-16 20:47         ` Trond Myklebust
  0 siblings, 0 replies; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 20:47 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
 fs/nfs/nfs4_fs.h          |    4 ++--
 fs/nfs/nfs4proc.c         |   18 ++++++++++++------
 fs/nfs/nfs4state.c        |   15 ++++++++++-----
 fs/nfs/nfs4xdr.c          |   20 ++++++++++----------
 include/linux/nfs_fs_sb.h |    1 -
 include/linux/nfs_xdr.h   |    5 +++++
 6 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index a187200..5099306 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -206,8 +206,8 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
 
 
 /* nfs4proc.c */
-extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *);
-extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
+extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
+extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *);
 extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
 extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
 extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6380670..8a9a412 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3494,7 +3494,9 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
 	return _nfs4_async_handle_error(task, server, server->nfs_client, state);
 }
 
-int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
+int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
+		unsigned short port, struct rpc_cred *cred,
+		struct nfs4_setclientid_res *res)
 {
 	nfs4_verifier sc_verifier;
 	struct nfs4_setclientid setclientid = {
@@ -3504,7 +3506,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],
 		.rpc_argp = &setclientid,
-		.rpc_resp = clp,
+		.rpc_resp = res,
 		.rpc_cred = cred,
 	};
 	__be32 *p;
@@ -3547,12 +3549,14 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po
 	return status;
 }
 
-static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
+static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp,
+		struct nfs4_setclientid_res *arg,
+		struct rpc_cred *cred)
 {
 	struct nfs_fsinfo fsinfo;
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM],
-		.rpc_argp = clp,
+		.rpc_argp = arg,
 		.rpc_resp = &fsinfo,
 		.rpc_cred = cred,
 	};
@@ -3570,12 +3574,14 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cre
 	return status;
 }
 
-int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
+int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
+		struct nfs4_setclientid_res *arg,
+		struct rpc_cred *cred)
 {
 	long timeout = 0;
 	int err;
 	do {
-		err = _nfs4_proc_setclientid_confirm(clp, cred);
+		err = _nfs4_proc_setclientid_confirm(clp, arg, cred);
 		switch (err) {
 			case 0:
 				return err;
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 6c5ed51..cd2d904 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -62,6 +62,7 @@ static LIST_HEAD(nfs4_clientid_list);
 
 int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
 {
+	struct nfs4_setclientid_res clid;
 	unsigned short port;
 	int status;
 
@@ -69,11 +70,15 @@ int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
 	if (clp->cl_addr.ss_family == AF_INET6)
 		port = nfs_callback_tcpport6;
 
-	status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred);
-	if (status == 0)
-		status = nfs4_proc_setclientid_confirm(clp, cred);
-	if (status == 0)
-		nfs4_schedule_state_renewal(clp);
+	status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid);
+	if (status != 0)
+		goto out;
+	status = nfs4_proc_setclientid_confirm(clp, &clid, cred);
+	if (status != 0)
+		goto out;
+	clp->cl_clientid = clid.clientid;
+	nfs4_schedule_state_renewal(clp);
+out:
 	return status;
 }
 
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 38f3b58..d66f9ac 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1504,14 +1504,14 @@ static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclie
 	hdr->replen += decode_setclientid_maxsz;
 }
 
-static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state, struct compound_hdr *hdr)
+static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_setclientid_res *arg, struct compound_hdr *hdr)
 {
 	__be32 *p;
 
 	p = reserve_space(xdr, 12 + NFS4_VERIFIER_SIZE);
 	*p++ = cpu_to_be32(OP_SETCLIENTID_CONFIRM);
-	p = xdr_encode_hyper(p, client_state->cl_clientid);
-	xdr_encode_opaque_fixed(p, client_state->cl_confirm.data, NFS4_VERIFIER_SIZE);
+	p = xdr_encode_hyper(p, arg->clientid);
+	xdr_encode_opaque_fixed(p, arg->confirm.data, NFS4_VERIFIER_SIZE);
 	hdr->nops++;
 	hdr->replen += decode_setclientid_confirm_maxsz;
 }
@@ -2324,7 +2324,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4
 /*
  * a SETCLIENTID_CONFIRM request
  */
-static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_client *clp)
+static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs4_setclientid_res *arg)
 {
 	struct xdr_stream xdr;
 	struct compound_hdr hdr = {
@@ -2334,7 +2334,7 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str
 
 	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
 	encode_compound_hdr(&xdr, req, &hdr);
-	encode_setclientid_confirm(&xdr, clp, &hdr);
+	encode_setclientid_confirm(&xdr, arg, &hdr);
 	encode_putrootfh(&xdr, &hdr);
 	encode_fsinfo(&xdr, lease_bitmap, &hdr);
 	encode_nops(&hdr);
@@ -4397,7 +4397,7 @@ out_overflow:
 	return -EIO;
 }
 
-static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
+static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid_res *res)
 {
 	__be32 *p;
 	uint32_t opnum;
@@ -4417,8 +4417,8 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
 		p = xdr_inline_decode(xdr, 8 + NFS4_VERIFIER_SIZE);
 		if (unlikely(!p))
 			goto out_overflow;
-		p = xdr_decode_hyper(p, &clp->cl_clientid);
-		memcpy(clp->cl_confirm.data, p, NFS4_VERIFIER_SIZE);
+		p = xdr_decode_hyper(p, &res->clientid);
+		memcpy(res->confirm.data, p, NFS4_VERIFIER_SIZE);
 	} else if (nfserr == NFSERR_CLID_INUSE) {
 		uint32_t len;
 
@@ -5498,7 +5498,7 @@ static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, __be32 *p, void *dummy)
  * Decode SETCLIENTID response
  */
 static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
-		struct nfs_client *clp)
+		struct nfs4_setclientid_res *res)
 {
 	struct xdr_stream xdr;
 	struct compound_hdr hdr;
@@ -5507,7 +5507,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
 	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
 	status = decode_compound_hdr(&xdr, &hdr);
 	if (!status)
-		status = decode_setclientid(&xdr, clp);
+		status = decode_setclientid(&xdr, res);
 	return status;
 }
 
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index e82957a..d6e10a4 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -44,7 +44,6 @@ struct nfs_client {
 
 #ifdef CONFIG_NFS_V4
 	u64			cl_clientid;	/* constant */
-	nfs4_verifier		cl_confirm;
 	unsigned long		cl_state;
 
 	struct rb_root		cl_openowner_id;
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 89b2881..6b31645 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -824,6 +824,11 @@ struct nfs4_setclientid {
 	u32				sc_cb_ident;
 };
 
+struct nfs4_setclientid_res {
+	u64				clientid;
+	nfs4_verifier			confirm;
+};
+
 struct nfs4_statfs_arg {
 	const struct nfs_fh *		fh;
 	const u32 *			bitmask;
-- 
1.6.6.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] SUNRPC: Fail over more quickly on connect errors
  2010-04-16 20:47     ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
  2010-04-16 20:47       ` [PATCH] NFSv4: Allow attribute caching with 'noac' mounts if client holds a delegation Trond Myklebust
@ 2010-04-16 22:29       ` Trond Myklebust
  2010-04-19 23:35         ` Chuck Lever
  1 sibling, 1 reply; 8+ messages in thread
From: Trond Myklebust @ 2010-04-16 22:29 UTC (permalink / raw)
  To: linux-nfs

On Fri, 2010-04-16 at 16:47 -0400, Trond Myklebust wrote: 
> We should not allow soft tasks to wait for longer than the major timeout
> period when waiting for a reconnect to occur.
> 
> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
> ---
>  net/sunrpc/xprt.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
> index c71d835..01449a3 100644
> --- a/net/sunrpc/xprt.c
> +++ b/net/sunrpc/xprt.c
> @@ -710,7 +710,7 @@ void xprt_connect(struct rpc_task *task)
>  		if (task->tk_rqstp)
>  			task->tk_rqstp->rq_bytes_sent = 0;
>  
> -		task->tk_timeout = xprt->connect_timeout;
> +		task->tk_timeout = min(req->rq_timeout, xprt->connect_timeout);
                                         ^^^ task->tk_rqstp->rq_timeout

Apologies. I though I had tested that...

> 		rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
>  
>  		if (test_bit(XPRT_CLOSING, &xprt->state))



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] SUNRPC: Fail over more quickly on connect errors
  2010-04-16 22:29       ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
@ 2010-04-19 23:35         ` Chuck Lever
  0 siblings, 0 replies; 8+ messages in thread
From: Chuck Lever @ 2010-04-19 23:35 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: linux-nfs

On 04/16/2010 06:29 PM, Trond Myklebust wrote:
> On Fri, 2010-04-16 at 16:47 -0400, Trond Myklebust wrote:
>> We should not allow soft tasks to wait for longer than the major timeout
>> period when waiting for a reconnect to occur.
>>
>> Signed-off-by: Trond Myklebust<Trond.Myklebust@netapp.com>
>> ---
>>   net/sunrpc/xprt.c |    2 +-
>>   1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
>> index c71d835..01449a3 100644
>> --- a/net/sunrpc/xprt.c
>> +++ b/net/sunrpc/xprt.c
>> @@ -710,7 +710,7 @@ void xprt_connect(struct rpc_task *task)
>>   		if (task->tk_rqstp)
>>   			task->tk_rqstp->rq_bytes_sent = 0;
>>
>> -		task->tk_timeout = xprt->connect_timeout;
>> +		task->tk_timeout = min(req->rq_timeout, xprt->connect_timeout);
>                                           ^^^ task->tk_rqstp->rq_timeout
>
> Apologies. I though I had tested that...
>
>> 		rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
>>
>>   		if (test_bit(XPRT_CLOSING,&xprt->state))

I tested this series of patches with soft mounts, and RPC requests now 
fail, after the timeout period, if the client can't reconnect.

I also observed appropriate exponential back-off behavior as the client 
attempts to reconnect.  I would suggest one more patch to reduce the 
reestablish timeout maximum to 30 seconds.

For the series:

Reviewed-by: Chuck Lever <chuck.lever@oracle.com>

   and/or

Tested-by: Chuck Lever <chuck.lever@oracle.com>

-- 
chuck[dot]lever[at]oracle[dot]com

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-04-19 23:36 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-16 20:47 [PATCH] SUNRPC: Clean up xprt_release() Trond Myklebust
2010-04-16 20:47 ` [PATCH] SUNRPC: Cleanup - make rpc_new_task() call rpc_release_calldata on failure Trond Myklebust
2010-04-16 20:47   ` [PATCH] SUNRPC: Move the test for XPRT_CONNECTING into xprt_connect() Trond Myklebust
2010-04-16 20:47     ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
2010-04-16 20:47       ` [PATCH] NFSv4: Allow attribute caching with 'noac' mounts if client holds a delegation Trond Myklebust
2010-04-16 20:47         ` [PATCH] NFSv4: Clean up the NFSv4 setclientid operation Trond Myklebust
2010-04-16 22:29       ` [PATCH] SUNRPC: Fail over more quickly on connect errors Trond Myklebust
2010-04-19 23:35         ` Chuck Lever

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.