NFSv4: Handle timeouts correctly when probing for lease validity
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Mon, 8 Apr 2013 21:50:28 +0000 (17:50 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Mon, 8 Apr 2013 22:01:59 +0000 (18:01 -0400)
When we send a RENEW or SEQUENCE operation in order to probe if the
lease is still valid, we want it to be able to time out since the
lease we are probing is likely to time out too. Currently, because
we use soft mount semantics for these RPC calls, the return value
is EIO, which causes the state manager to exit with an "unhandled
error" message.
This patch changes the call semantics, so that the RPC layer returns
ETIMEDOUT instead of EIO. We then have the state manager default to
a simple retry instead of exiting.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c

index bdf3d07ce974098254562e8506d2a09435407eb3..264ddb16255fa0197eadbcd0c7a5ffdad72e8521 100644 (file)
@@ -3797,7 +3797,7 @@ static int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred,
                return -ENOMEM;
        data->client = clp;
        data->timestamp = jiffies;
-       return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
+       return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT,
                        &nfs4_renew_ops, data);
 }
 
@@ -3811,7 +3811,7 @@ static int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
        unsigned long now = jiffies;
        int status;
 
-       status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
+       status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
        if (status < 0)
                return status;
        do_renew_lease(clp, now);
@@ -5959,7 +5959,7 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
                .rpc_client = clp->cl_rpcclient,
                .rpc_message = &msg,
                .callback_ops = &nfs41_sequence_ops,
-               .flags = RPC_TASK_ASYNC | RPC_TASK_SOFT,
+               .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT,
        };
 
        if (!atomic_inc_not_zero(&clp->cl_count))
index b924bdd6949483dd510cc38cf3675259962937b2..1eb17285c99aef208f7954063e457d3a326758ee 100644 (file)
@@ -1739,6 +1739,10 @@ static int nfs4_check_lease(struct nfs_client *clp)
        }
        status = ops->renew_lease(clp, cred);
        put_rpccred(cred);
+       if (status == -ETIMEDOUT) {
+               set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
+               return 0;
+       }
 out:
        return nfs4_recovery_handle_error(clp, status);
 }