Author: kib
Date: Tue Feb  4 17:17:40 2020
New Revision: 357508
URL: https://svnweb.freebsd.org/changeset/base/357508

Log:
  MFC r357199, r357306:
  Save lower root vnode in nullfs mnt data instead of upper.

Modified:
  stable/11/sys/fs/nullfs/null.h
  stable/11/sys/fs/nullfs/null_subr.c
  stable/11/sys/fs/nullfs/null_vfsops.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/fs/nullfs/null.h
==============================================================================
--- stable/11/sys/fs/nullfs/null.h      Tue Feb  4 17:15:51 2020        
(r357507)
+++ stable/11/sys/fs/nullfs/null.h      Tue Feb  4 17:17:40 2020        
(r357508)
@@ -41,7 +41,7 @@
 
 struct null_mount {
        struct mount    *nullm_vfs;
-       struct vnode    *nullm_rootvp;  /* Reference to root null_node */
+       struct vnode    *nullm_lowerrootvp;     /* Ref to lower root vnode */
        uint64_t        nullm_flags;
 };
 

Modified: stable/11/sys/fs/nullfs/null_subr.c
==============================================================================
--- stable/11/sys/fs/nullfs/null_subr.c Tue Feb  4 17:15:51 2020        
(r357507)
+++ stable/11/sys/fs/nullfs/null_subr.c Tue Feb  4 17:17:40 2020        
(r357508)
@@ -254,6 +254,9 @@ null_nodeget(mp, lowervp, vpp)
        error = insmntque1(vp, mp, null_insmntque_dtr, xp);
        if (error != 0)
                return (error);
+       if (lowervp == MOUNTTONULLMOUNT(mp)->nullm_lowerrootvp)
+               vp->v_vflag |= VV_ROOT;
+
        /*
         * Atomically insert our new node into the hash or vget existing 
         * if someone else has beaten us to it.

Modified: stable/11/sys/fs/nullfs/null_vfsops.c
==============================================================================
--- stable/11/sys/fs/nullfs/null_vfsops.c       Tue Feb  4 17:15:51 2020        
(r357507)
+++ stable/11/sys/fs/nullfs/null_vfsops.c       Tue Feb  4 17:17:40 2020        
(r357508)
@@ -72,7 +72,7 @@ static vfs_extattrctl_t       nullfs_extattrctl;
 static int
 nullfs_mount(struct mount *mp)
 {
-       struct vnode *lowerrootvp, *vp;
+       struct vnode *lowerrootvp;
        struct vnode *nullm_rootvp;
        struct null_mount *xmp;
        struct thread *td = curthread;
@@ -159,36 +159,24 @@ nullfs_mount(struct mount *mp)
            M_NULLFSMNT, M_WAITOK | M_ZERO);
 
        /*
-        * Save reference to underlying FS
+        * Save pointer to underlying FS and the reference to the
+        * lower root vnode.
         */
        xmp->nullm_vfs = lowerrootvp->v_mount;
+       vref(lowerrootvp);
+       xmp->nullm_lowerrootvp = lowerrootvp;
+       mp->mnt_data = xmp;
 
        /*
-        * Save reference.  Each mount also holds
-        * a reference on the root vnode.
+        * Make sure the node alias worked.
         */
-       error = null_nodeget(mp, lowerrootvp, &vp);
-       /*
-        * Make sure the node alias worked
-        */
-       if (error) {
+       error = null_nodeget(mp, lowerrootvp, &nullm_rootvp);
+       if (error != 0) {
+               vrele(lowerrootvp);
                free(xmp, M_NULLFSMNT);
                return (error);
        }
 
-       /*
-        * Keep a held reference to the root vnode.
-        * It is vrele'd in nullfs_unmount.
-        */
-       nullm_rootvp = vp;
-       nullm_rootvp->v_vflag |= VV_ROOT;
-       xmp->nullm_rootvp = nullm_rootvp;
-
-       /*
-        * Unlock the node (either the lower or the alias)
-        */
-       VOP_UNLOCK(vp, 0);
-
        if (NULLVPTOLOWERVP(nullm_rootvp)->v_mount->mnt_flag & MNT_LOCAL) {
                MNT_ILOCK(mp);
                mp->mnt_flag |= MNT_LOCAL;
@@ -210,7 +198,6 @@ nullfs_mount(struct mount *mp)
        mp->mnt_kern_flag |= lowerrootvp->v_mount->mnt_kern_flag &
            (MNTK_USES_BCACHE | MNTK_NO_IOPF | MNTK_UNMAPPED_BUFS);
        MNT_IUNLOCK(mp);
-       mp->mnt_data = xmp;
        vfs_getnewfsid(mp);
        if ((xmp->nullm_flags & NULLM_CACHE) != 0) {
                MNT_ILOCK(xmp->nullm_vfs);
@@ -220,6 +207,7 @@ nullfs_mount(struct mount *mp)
        }
 
        vfs_mountedfrom(mp, target);
+       vput(nullm_rootvp);
 
        NULLFSDEBUG("nullfs_mount: lower %s, alias at %s\n",
                mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);
@@ -236,7 +224,7 @@ nullfs_unmount(mp, mntflags)
 {
        struct null_mount *mntdata;
        struct mount *ump;
-       int error, flags, rootrefs;
+       int error, flags;
 
        NULLFSDEBUG("nullfs_unmount: mp = %p\n", (void *)mp);
 
@@ -245,9 +233,9 @@ nullfs_unmount(mp, mntflags)
        else
                flags = 0;
 
-       for (rootrefs = 1;; rootrefs = 0) {
+       for (;;) {
                /* There is 1 extra root vnode reference (nullm_rootvp). */
-               error = vflush(mp, rootrefs, flags, curthread);
+               error = vflush(mp, 0, flags, curthread);
                if (error)
                        return (error);
                MNT_ILOCK(mp);
@@ -274,6 +262,7 @@ nullfs_unmount(mp, mntflags)
                TAILQ_REMOVE(&ump->mnt_uppers, mp, mnt_upper_link);
                MNT_IUNLOCK(ump);
        }
+       vrele(mntdata->nullm_lowerrootvp);
        mp->mnt_data = NULL;
        free(mntdata, M_NULLFSMNT);
        return (0);
@@ -286,21 +275,24 @@ nullfs_root(mp, flags, vpp)
        struct vnode **vpp;
 {
        struct vnode *vp;
+       struct null_mount *mntdata;
+       int error;
 
-       NULLFSDEBUG("nullfs_root(mp = %p, vp = %p->%p)\n", (void *)mp,
-           (void *)MOUNTTONULLMOUNT(mp)->nullm_rootvp,
-           (void *)NULLVPTOLOWERVP(MOUNTTONULLMOUNT(mp)->nullm_rootvp));
+       mntdata = MOUNTTONULLMOUNT(mp);
+       NULLFSDEBUG("nullfs_root(mp = %p, vp = %p)\n", mp,
+           mntdata->nullm_lowerrootvp);
 
-       /*
-        * Return locked reference to root.
-        */
-       vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
-       VREF(vp);
-
-       ASSERT_VOP_UNLOCKED(vp, "root vnode is locked");
-       vn_lock(vp, flags | LK_RETRY);
-       *vpp = vp;
-       return 0;
+       error = vget(mntdata->nullm_lowerrootvp, (flags & ~LK_TYPE_MASK) |
+           LK_EXCLUSIVE, curthread);
+       if (error == 0) {
+               error = null_nodeget(mp, mntdata->nullm_lowerrootvp, &vp);
+               if (error == 0) {
+                       if ((flags & LK_TYPE_MASK) == LK_SHARED)
+                               vn_lock(vp, LK_DOWNGRADE | LK_RETRY);
+                       *vpp = vp;
+               }
+       }
+       return (error);
 }
 
 static int
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to