]> 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)
committerPaul Gortmaker <paul.gortmaker@windriver.com>
Fri, 17 Aug 2012 19:35:41 +0000 (15:35 -0400)
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>
[PG: struct rpc_task in sched.h slightly different layout vs. v3.0]
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
fs/lockd/clntproc.c
include/linux/sunrpc/sched.h
net/sunrpc/clnt.c
net/sunrpc/sched.c

index 7932c399fab41421095fbb0f98f0b21819e96514..f4ef9d120f24f67dfad780455b99d93e1900239e 100644 (file)
@@ -710,7 +710,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 7bc7fd5291ce37d6abcbe7f44e96156540beb46d..f2338ca42fe7427191d23bed9bb461f8634bce6b 100644 (file)
@@ -55,6 +55,7 @@ struct rpc_task {
        struct rpc_message      tk_msg;         /* RPC call info */
        __u8                    tk_garb_retry;
        __u8                    tk_cred_retry;
+       __u8                    tk_rebind_retry;
 
        /*
         * callback     to be executed after waking up
index 0ad782838ed76d87d2c43cbccc61a34701b7cbef..018903ce7550f785b8ed4dbe4bb56ccd2899b12d 100644 (file)
@@ -1053,6 +1053,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 416ca5e9378eaa93aee7041f18242565b8b54398..e961e064a5bc5dbbecc0637e6a8a9572ac8905d4 100644 (file)
@@ -799,6 +799,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;