Date: Tue, 4 Feb 2020 17:17:40 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r357508 - stable/11/sys/fs/nullfs Message-ID: <202002041717.014HHeqN068011@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202002041717.014HHeqN068011>