NFSv4: Ensure state recovery handles ETIMEDOUT correctly
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 7 Aug 2019 11:31:27 +0000 (07:31 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 7 Aug 2019 16:55:11 +0000 (12:55 -0400)
Ensure that the state recovery code handles ETIMEDOUT correctly,
and also that we set RPC_TASK_TIMEOUT when recovering open state.

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

index 12b2b65ad8a8294e210460d23a4de2ca747d04c4..1406858bae6c95187c1190d3bb3b64bc5f317c58 100644 (file)
@@ -2179,6 +2179,7 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
                case -ENOENT:
                case -EAGAIN:
                case -ESTALE:
+               case -ETIMEDOUT:
                        break;
                case -NFS4ERR_BADSESSION:
                case -NFS4ERR_BADSLOT:
@@ -2499,6 +2500,7 @@ static int nfs4_run_open_task(struct nfs4_opendata *data,
        if (!ctx) {
                nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 1);
                data->is_recover = true;
+               task_setup_data.flags |= RPC_TASK_TIMEOUT;
        } else {
                nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 0);
                pnfs_lgopen_prepare(data, ctx);
index a4e866b2b43bd15b7f0de5a3e164631b75f1aca7..cad4e064b328747e29fdc20578c53f28bf438607 100644 (file)
@@ -1529,6 +1529,7 @@ restart:
                switch (status) {
                case 0:
                        break;
+               case -ETIMEDOUT:
                case -ESTALE:
                case -NFS4ERR_ADMIN_REVOKED:
                case -NFS4ERR_STALE_STATEID:
@@ -1682,11 +1683,13 @@ restart:
                case -NFS4ERR_EXPIRED:
                case -NFS4ERR_NO_GRACE:
                        nfs4_state_mark_reclaim_nograce(sp->so_server->nfs_client, state);
+                       /* Fall through */
                case -NFS4ERR_STALE_CLIENTID:
                case -NFS4ERR_BADSESSION:
                case -NFS4ERR_BADSLOT:
                case -NFS4ERR_BAD_HIGH_SLOT:
                case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
+               case -ETIMEDOUT:
                        goto out_err;
                }
                nfs4_put_open_state(state);
@@ -1971,7 +1974,6 @@ static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status)
                return -EPERM;
        case -EACCES:
        case -NFS4ERR_DELAY:
-       case -ETIMEDOUT:
        case -EAGAIN:
                ssleep(1);
                break;
@@ -2600,7 +2602,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
                }
 
                /* Now recover expired state... */
-               if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) {
+               if (test_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) {
                        section = "reclaim nograce";
                        status = nfs4_do_reclaim(clp,
                                clp->cl_mvops->nograce_recovery_ops);
@@ -2608,6 +2610,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
                                continue;
                        if (status < 0)
                                goto out_error;
+                       clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
                }
 
                nfs4_end_drain_session(clp);