]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
NFSD: Fix infinite loop in layout state revocation
authorChuck Lever <chuck.lever@oracle.com>
Sun, 19 Apr 2026 18:52:59 +0000 (14:52 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Jun 2026 15:46:26 +0000 (17:46 +0200)
[ Upstream commit 4f8ef58c10bfe5f86a643c7c8331b37e69e3dae1 ]

find_one_sb_stid() skips stids whose sc_status is non-zero, but the
SC_TYPE_LAYOUT case in nfsd4_revoke_states() never sets sc_status
before calling nfsd4_close_layout(). The retry loop therefore finds
the same layout stid on every iteration, hanging the revoker
indefinitely.

Fixes: 1e33e1414bec ("nfsd: allow layout state to be admin-revoked.")
Reported-by: Dai Ngo <dai.ngo@oracle.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Tested-by: Dai Ngo <dai.ngo@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/nfsd/nfs4state.c

index 1a15e458b178ae5952db7cce1eacb0528f31bbd0..2d91747297820784d96608aee12a77e060ba5979 100644 (file)
@@ -1832,6 +1832,13 @@ void nfsd4_revoke_states(struct nfsd_net *nn, struct super_block *sb)
                                        break;
                                case SC_TYPE_LAYOUT:
                                        ls = layoutstateid(stid);
+                                       spin_lock(&clp->cl_lock);
+                                       if (stid->sc_status == 0) {
+                                               stid->sc_status |=
+                                                       SC_STATUS_ADMIN_REVOKED;
+                                               atomic_inc(&clp->cl_admin_revoked);
+                                       }
+                                       spin_unlock(&clp->cl_lock);
                                        nfsd4_close_layout(ls);
                                        break;
                                }