[PATCH] NFSv4.1/pNFS: fix LAYOUTCOMMIT retry loop on OLD_STATEID

Lei Yin posted 1 patch 1 month, 3 weeks ago
There is a newer version of this series
fs/nfs/nfs4proc.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
[PATCH] NFSv4.1/pNFS: fix LAYOUTCOMMIT retry loop on OLD_STATEID
Posted by Lei Yin 1 month, 3 weeks ago
From: Lei Yin <yinlei2@lenovo.com>

Handle -NFS4ERR_OLD_STATEID in nfs4_layoutcommit_done().

Without refreshing data->args.stateid, LAYOUTCOMMIT can keep retrying
with the same stale stateid after OLD_STATEID, resulting in an
unbounded retry loop.

Refresh the layout stateid with nfs4_layout_refresh_old_stateid()
and restart the RPC only after a successful refresh.

This also keeps the OLD_STATEID recovery path consistent with other
pNFS layout operations.

Signed-off-by: Lei Yin <yinlei2@lenovo.com>
---
 fs/nfs/nfs4proc.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index d839a97df822..57a12efef0aa 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -9970,6 +9970,21 @@ nfs4_layoutcommit_done(struct rpc_task *task, void *calldata)
 	case -NFS4ERR_GRACE:	    /* loca_recalim always false */
 		task->tk_status = 0;
 		break;
+	case -NFS4ERR_OLD_STATEID: {
+		struct pnfs_layout_range range = {
+			.iomode = IOMODE_ANY,
+			.offset = 0,
+			.length = NFS4_MAX_UINT64,
+		};
+
+		if (nfs4_layout_refresh_old_stateid(&data->args.stateid,
+						    &range,
+						    data->args.inode)) {
+			rpc_restart_call_prepare(task);
+			return;
+		}
+		fallthrough;
+	}
 	case 0:
 		break;
 	default:
-- 
2.43.0