NFSv4: Retry NFS4ERR_OLD_STATEID errors in layoutreturn
authorTrond Myklebust <trond.myklebust@primarydata.com>
Mon, 6 Nov 2017 20:28:08 +0000 (15:28 -0500)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Fri, 17 Nov 2017 21:43:48 +0000 (16:43 -0500)
If our layoutreturn returns an NFS4ERR_OLD_STATEID, then try to
update the stateid and retry.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
fs/nfs/nfs4proc.c

index 7ff9c43f79ebe3d8b6e578146d4d6001c6482290..8e7604a1eee4a08e2e30bc36490be0da8f696c74 100644 (file)
@@ -8750,18 +8750,27 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
 
        server = NFS_SERVER(lrp->args.inode);
        switch (task->tk_status) {
+       case -NFS4ERR_OLD_STATEID:
+               if (nfs4_refresh_layout_stateid(&lrp->args.stateid,
+                                       lrp->args.inode))
+                       goto out_restart;
+               /* Fallthrough */
        default:
                task->tk_status = 0;
+               /* Fallthrough */
        case 0:
                break;
        case -NFS4ERR_DELAY:
                if (nfs4_async_handle_error(task, server, NULL, NULL) != -EAGAIN)
                        break;
-               nfs4_sequence_free_slot(&lrp->res.seq_res);
-               rpc_restart_call_prepare(task);
-               return;
+               goto out_restart;
        }
        dprintk("<-- %s\n", __func__);
+       return;
+out_restart:
+       task->tk_status = 0;
+       nfs4_sequence_free_slot(&lrp->res.seq_res);
+       rpc_restart_call_prepare(task);
 }
 
 static void nfs4_layoutreturn_release(void *calldata)