The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6280d03bb5fda4ba4a33a6e6faff2de34b2eda61

commit 6280d03bb5fda4ba4a33a6e6faff2de34b2eda61
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2025-07-08 19:53:55 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2025-07-09 17:38:11 +0000

    nfsserver rename: lock mnt_renamelock as required
    
    Fixes:  ef6ea91593ebff73e2fc201efd9f848b71c5a125
    Reported by:    des
    Reviewed by:    markj, rmacklem
    Tested by:      pho
    Sponsored by:   The FreeBSD Foundation
    Differential revision:  https://reviews.freebsd.org/D51211
---
 sys/fs/nfsserver/nfs_nfsdport.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index 95dc44438acc..43ee0383669f 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -1698,10 +1698,26 @@ nfsvno_rename(struct nameidata *fromndp, struct 
nameidata *tondp,
                    " dsdvp=%p\n", dsdvp[0]);
        }
 out:
-       if (!error) {
+       mp = NULL;
+       if (error == 0) {
+               error = VOP_GETWRITEMOUNT(tondp->ni_dvp, &mp);
+               if (error == 0) {
+                       if (mp == NULL) {
+                               error = ENOENT;
+                       } else {
+                               error = lockmgr(&mp->mnt_renamelock,
+                                   LK_EXCLUSIVE | LK_NOWAIT, NULL);
+                               if (error != 0)
+                                       error = ERELOOKUP;
+                       }
+               }
+       }
+       if (error == 0) {
                error = VOP_RENAME(fromndp->ni_dvp, fromndp->ni_vp,
                    &fromndp->ni_cnd, tondp->ni_dvp, tondp->ni_vp,
                    &tondp->ni_cnd);
+               lockmgr(&mp->mnt_renamelock, LK_RELEASE, 0);
+               vfs_rel(mp);
        } else {
                if (tdvp == tvp)
                        vrele(tdvp);
@@ -1711,8 +1727,13 @@ out:
                        vput(tvp);
                vrele(fromndp->ni_dvp);
                vrele(fvp);
-               if (error == EJUSTRETURN)
+               if (error == EJUSTRETURN) {
                        error = 0;
+               } else if (error == ERELOOKUP && mp != NULL) {
+                       lockmgr(&mp->mnt_renamelock, LK_EXCLUSIVE, 0);
+                       lockmgr(&mp->mnt_renamelock, LK_RELEASE, 0);
+                       vfs_rel(mp);
+               }
        }
 
        /*

Reply via email to