The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=7fd37611b92b5f365f33435bb725b335c2f10ba8

commit 7fd37611b92b5f365f33435bb725b335c2f10ba8
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2022-06-10 11:35:45 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2022-06-14 07:32:45 +0000

    null_vptocnp(): busy nullfs mp instead of refing it
    
    null_nodeget() needs a valid mount point data, otherwise we might
    race and dereference NULL.
    
    Using MBF_NOWAIT makes non-forced unmount non-transparent for
    vn_fullpath() over nullfs, but we make no guarantee that fullpath
    calculation succeeds anyway.
    
    Reported and tested by: pho
    Reviewed by:    jah
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D35477
---
 sys/fs/nullfs/null_vnops.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
index e3a320a22bfa..bb18bc8ee55f 100644
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -989,9 +989,11 @@ null_vptocnp(struct vop_vptocnp_args *ap)
 
        locked = VOP_ISLOCKED(vp);
        lvp = NULLVPTOLOWERVP(vp);
-       vhold(lvp);
        mp = vp->v_mount;
-       vfs_ref(mp);
+       error = vfs_busy(mp, MBF_NOWAIT);
+       if (error != 0)
+               return (error);
+       vhold(lvp);
        VOP_UNLOCK(vp); /* vp is held by vn_vptocnp_locked that called us */
        ldvp = lvp;
        vref(lvp);
@@ -999,7 +1001,7 @@ null_vptocnp(struct vop_vptocnp_args *ap)
        vdrop(lvp);
        if (error != 0) {
                vn_lock(vp, locked | LK_RETRY);
-               vfs_rel(mp);
+               vfs_unbusy(mp);
                return (ENOENT);
        }
 
@@ -1007,7 +1009,7 @@ null_vptocnp(struct vop_vptocnp_args *ap)
        if (error != 0) {
                vrele(ldvp);
                vn_lock(vp, locked | LK_RETRY);
-               vfs_rel(mp);
+               vfs_unbusy(mp);
                return (ENOENT);
        }
        error = null_nodeget(mp, ldvp, dvp);
@@ -1018,7 +1020,7 @@ null_vptocnp(struct vop_vptocnp_args *ap)
                VOP_UNLOCK(*dvp); /* keep reference on *dvp */
        }
        vn_lock(vp, locked | LK_RETRY);
-       vfs_rel(mp);
+       vfs_unbusy(mp);
        return (error);
 }
 

Reply via email to