]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
NLM: Don't hang forever on NLM unlock requests
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 31 May 2011 19:15:34 +0000 (15:15 -0400)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sat, 9 Jul 2011 06:15:35 +0000 (23:15 -0700)
commit 0b760113a3a155269a3fba93a409c640031dd68f upstream.

If the NLM daemon is killed on the NFS server, we can currently end up
hanging forever on an 'unlock' request, instead of aborting. Basically,
if the rpcbind request fails, or the server keeps returning garbage, we
really want to quit instead of retrying.

Tested-by: Vasily Averin <vvs@sw.ru>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/lockd/clntproc.c
include/linux/sunrpc/sched.h
net/sunrpc/clnt.c
net/sunrpc/sched.c

index adb45ec9038cc95530e5d1be50d521a927110ac2..e374050a911c6141342bf5b464bb04fca396ce3e 100644 (file)
@@ -708,7 +708,13 @@ static void nlmclnt_unlock_callback(struct rpc_task *task, void *data)
 
        if (task->tk_status < 0) {
                dprintk("lockd: unlock failed (err = %d)\n", -task->tk_status);
-               goto retry_rebind;
+               switch (task->tk_status) {
+               case -EACCES:
+               case -EIO:
+                       goto die;
+               default:
+                       goto retry_rebind;
+               }
        }
        if (status == NLM_LCK_DENIED_GRACE_PERIOD) {
                rpc_delay(task, NLMCLNT_GRACE_WAIT);
index f73c482ec9c6080cc5201c047546928c53c8b723..fe2d8e6b923b416908220e2ef70bed01dee60897 100644 (file)
@@ -84,7 +84,8 @@ struct rpc_task {
 #endif
        unsigned char           tk_priority : 2,/* Task priority */
                                tk_garb_retry : 2,
-                               tk_cred_retry : 2;
+                               tk_cred_retry : 2,
+                               tk_rebind_retry : 2;
 };
 #define tk_xprt                        tk_client->cl_xprt
 
index 489245f6e910d70cf75b8405310dc274cd997c8b..00df09bb365f6eaf127754f11369c98266eae30b 100644 (file)
@@ -1172,6 +1172,9 @@ call_bind_status(struct rpc_task *task)
                        status = -EOPNOTSUPP;
                        break;
                }
+               if (task->tk_rebind_retry == 0)
+                       break;
+               task->tk_rebind_retry--;
                rpc_delay(task, 3*HZ);
                goto retry_timeout;
        case -ETIMEDOUT:
index 6b43ee7221d5a830b8b0acea4375f9341aacfc90..a27406b1654f190f645e9b3c393b46f4b6d939fb 100644 (file)
@@ -792,6 +792,7 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
        /* Initialize retry counters */
        task->tk_garb_retry = 2;
        task->tk_cred_retry = 2;
+       task->tk_rebind_retry = 2;
 
        task->tk_priority = task_setup_data->priority - RPC_PRIORITY_LOW;
        task->tk_owner = current->tgid;