From: Trond Myklebust <trond.myklebust@fys.uio.no>

RPC/NFSv4: Allow lease RENEW calls to be soft (i.e.  to time out) despite the
mount being hard.


---

 fs/nfs/nfs4proc.c            |    3 ++-
 include/linux/sunrpc/sched.h |    2 ++
 net/sunrpc/clnt.c            |    4 ++--
 net/sunrpc/sched.c           |    5 ++++-
 net/sunrpc/xprt.c            |    6 +++---
 5 files changed, 13 insertions(+), 7 deletions(-)

diff -puN fs/nfs/nfs4proc.c~nfs-25-soft fs/nfs/nfs4proc.c
--- 25/fs/nfs/nfs4proc.c~nfs-25-soft	2004-01-09 22:16:23.000000000 -0800
+++ 25-akpm/fs/nfs/nfs4proc.c	2004-01-09 22:16:23.000000000 -0800
@@ -1639,7 +1639,8 @@ nfs4_proc_async_renew(struct nfs4_client
 		.rpc_cred	= clp->cl_cred,
 	};
 
-	return rpc_call_async(clp->cl_rpcclient, &msg, 0, renew_done, (void *)jiffies);
+	return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
+			renew_done, (void *)jiffies);
 }
 
 int
diff -puN include/linux/sunrpc/sched.h~nfs-25-soft include/linux/sunrpc/sched.h
--- 25/include/linux/sunrpc/sched.h~nfs-25-soft	2004-01-09 22:16:23.000000000 -0800
+++ 25-akpm/include/linux/sunrpc/sched.h	2004-01-09 22:16:23.000000000 -0800
@@ -108,6 +108,7 @@ typedef void			(*rpc_action)(struct rpc_
 #define RPC_TASK_ROOTCREDS	0x0040		/* force root creds */
 #define RPC_TASK_DYNAMIC	0x0080		/* task was kmalloc'ed */
 #define RPC_TASK_KILLED		0x0100		/* task was killed */
+#define RPC_TASK_SOFT		0x0200		/* Use soft timeouts */
 
 #define RPC_IS_ASYNC(t)		((t)->tk_flags & RPC_TASK_ASYNC)
 #define RPC_IS_SETUID(t)	((t)->tk_flags & RPC_TASK_SETUID)
@@ -117,6 +118,7 @@ typedef void			(*rpc_action)(struct rpc_
 #define RPC_ASSASSINATED(t)	((t)->tk_flags & RPC_TASK_KILLED)
 #define RPC_IS_ACTIVATED(t)	((t)->tk_active)
 #define RPC_DO_CALLBACK(t)	((t)->tk_callback != NULL)
+#define RPC_IS_SOFT(t)		((t)->tk_flags & RPC_TASK_SOFT)
 
 #define RPC_TASK_SLEEPING	0
 #define RPC_TASK_RUNNING	1
diff -puN net/sunrpc/clnt.c~nfs-25-soft net/sunrpc/clnt.c
--- 25/net/sunrpc/clnt.c~nfs-25-soft	2004-01-09 22:16:23.000000000 -0800
+++ 25-akpm/net/sunrpc/clnt.c	2004-01-09 22:16:23.000000000 -0800
@@ -798,7 +798,7 @@ call_timeout(struct rpc_task *task)
 	to->to_retries = clnt->cl_timeout.to_retries;
 
 	dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid);
-	if (clnt->cl_softrtry) {
+	if (RPC_IS_SOFT(task)) {
 		if (clnt->cl_chatty)
 			printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
 				clnt->cl_protname, clnt->cl_server);
@@ -841,7 +841,7 @@ call_decode(struct rpc_task *task)
 	}
 
 	if (task->tk_status < 12) {
-		if (!clnt->cl_softrtry) {
+		if (!RPC_IS_SOFT(task)) {
 			task->tk_action = call_bind;
 			clnt->cl_stats->rpcretrans++;
 			goto out_retry;
diff -puN net/sunrpc/sched.c~nfs-25-soft net/sunrpc/sched.c
--- 25/net/sunrpc/sched.c~nfs-25-soft	2004-01-09 22:16:23.000000000 -0800
+++ 25-akpm/net/sunrpc/sched.c	2004-01-09 22:16:23.000000000 -0800
@@ -731,8 +731,11 @@ rpc_init_task(struct rpc_task *task, str
 	list_add(&task->tk_task, &all_tasks);
 	spin_unlock(&rpc_sched_lock);
 
-	if (clnt)
+	if (clnt) {
 		atomic_inc(&clnt->cl_users);
+		if (clnt->cl_softrtry)
+			task->tk_flags |= RPC_TASK_SOFT;
+	}
 
 #ifdef RPC_DEBUG
 	task->tk_magic = 0xf00baa;
diff -puN net/sunrpc/xprt.c~nfs-25-soft net/sunrpc/xprt.c
--- 25/net/sunrpc/xprt.c~nfs-25-soft	2004-01-09 22:16:23.000000000 -0800
+++ 25-akpm/net/sunrpc/xprt.c	2004-01-09 22:16:23.000000000 -0800
@@ -488,7 +488,7 @@ xprt_connect(struct rpc_task *task)
 	case -ECONNREFUSED:
 	case -ECONNRESET:
 	case -ENOTCONN:
-		if (!task->tk_client->cl_softrtry) {
+		if (!RPC_IS_SOFT(task)) {
 			rpc_delay(task, RPC_REESTABLISH_TIMEOUT);
 			task->tk_status = -ENOTCONN;
 			break;
@@ -496,7 +496,7 @@ xprt_connect(struct rpc_task *task)
 	default:
 		/* Report myriad other possible returns.  If this file
 		 * system is soft mounted, just error out, like Solaris.  */
-		if (task->tk_client->cl_softrtry) {
+		if (RPC_IS_SOFT(task)) {
 			printk(KERN_WARNING
 			"RPC: error %d connecting to server %s, exiting\n",
 					-status, task->tk_client->cl_server);
@@ -530,7 +530,7 @@ xprt_connect_status(struct rpc_task *tas
 	}
 
 	/* if soft mounted, just cause this RPC to fail */
-	if (task->tk_client->cl_softrtry)
+	if (RPC_IS_SOFT(task))
 		task->tk_status = -EIO;
 
 	switch (task->tk_status) {

_