]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
NFSv4/pnfs: If the server is down, retry the layout returns on reboot
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 5 Jan 2026 21:43:21 +0000 (16:43 -0500)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 13 Apr 2026 16:26:19 +0000 (09:26 -0700)
If a layout return is embedded in a CLOSE or DELEGRETURN rpc call, and
the metadata server reboots, the expectation now is that the client
should resend the layout return once the server comes back up.
This patch changes the current behaviour of dropping the layouts on the
floor, and instead queues them up for retrying.

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

index 91bcf67bd743f72a008a9dcde29207bf7a36c407..768de9935ff16ac87dd6eb66d549e66acbf42679 100644 (file)
@@ -9769,16 +9769,26 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
        if (!nfs41_sequence_process(task, &lrp->res.seq_res))
                return;
 
-       if (task->tk_rpc_status == -ETIMEDOUT) {
-               lrp->rpc_status = -EAGAIN;
-               lrp->res.lrs_present = 0;
-               return;
-       }
-       /*
-        * Was there an RPC level error? Assume the call succeeded,
-        * and that we need to release the layout
-        */
-       if (task->tk_rpc_status != 0 && RPC_WAS_SENT(task)) {
+       if (task->tk_rpc_status < 0) {
+               switch (task->tk_rpc_status) {
+               case -EACCES:
+               case -EIO:
+               case -EKEYEXPIRED:
+               case -ERESTARTSYS:
+               case -EINTR:
+                       lrp->rpc_status = 0;
+                       break;
+               case -ENETDOWN:
+               case -ENETUNREACH:
+                       if (task->tk_flags & RPC_TASK_NETUNREACH_FATAL)
+                               lrp->rpc_status = 0;
+                       else
+                               lrp->rpc_status = -EAGAIN;
+                       break;
+               default:
+                       lrp->rpc_status = -EAGAIN;
+                       break;
+               }
                lrp->res.lrs_present = 0;
                return;
        }
index bc13d1e69449ce9bb3ed3ef0bbff06dfab5c60b5..e89e476070a1a73ac1f4df636533b419f800bc68 100644 (file)
@@ -1698,11 +1698,23 @@ int pnfs_roc_done(struct rpc_task *task, struct nfs4_layoutreturn_args **argpp,
                /* If the call was not sent, let caller handle it */
                if (!RPC_WAS_SENT(task))
                        return 0;
-               /*
-                * Otherwise, assume the call succeeded and
-                * that we need to release the layout
-                */
-               *ret = 0;
+               switch (task->tk_rpc_status) {
+               default:
+                       /*
+                        * Defer the layoutreturn if it was due
+                        * to the server being down.
+                        */
+                       *ret = -NFS4ERR_NOMATCHING_LAYOUT;
+                       break;
+               case -EACCES:
+               case -EIO:
+               case -EKEYEXPIRED:
+               case -ERESTARTSYS:
+               case -EINTR:
+                       /* Don't retry */
+                       *ret = 0;
+                       break;
+               }
                (*respp)->lrs_present = 0;
                retval = 0;
                break;