From owner-freebsd-hackers@FreeBSD.ORG Fri Mar 13 20:07:11 2015 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 69EDAB43 for ; Fri, 13 Mar 2015 20:07:11 +0000 (UTC) Received: from mail-we0-x22c.google.com (mail-we0-x22c.google.com [IPv6:2a00:1450:400c:c03::22c]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id BD04EE84 for ; Fri, 13 Mar 2015 20:07:10 +0000 (UTC) Received: by wesp10 with SMTP id p10so25571675wes.11; Fri, 13 Mar 2015 13:07:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:mail-followup-to:references :mime-version:content-type:content-disposition:in-reply-to :user-agent; bh=uObI21A+//nEXlOCOGJRQFajcTd9hV+jpEd9Ogitq9o=; b=YvIr833210vB9ZF4p98D0pzUiImNkhfYuV9brso+0yIqfac4e/hfNr5iXGHfiGBtqA 01Vb8RRFCrOZgMMssWaEc7XhzkiONnaAhFy1N3Ai/EtZzLLFFzIGyALvCaLbtCdKE2RD ZF/Kbe+RrVYt7ui9gm8YAcqJQB/pwmy8zqiAWoLX+C8hAlS5XN1SUkka0Aus4uWT2hJk I/fz9znHOG+zAdxv7u+VY+AjV+8yALIeDzNefbgf6ytXkwBKtTisZzwiDxiseyTgGntm pD39b2Ntu8kBOE6slWxMabDlaIRI0r9ZLhILnmaZTUJrqWqM9xPnaqqZXiLcTEYUkWEy iBRw== X-Received: by 10.180.208.107 with SMTP id md11mr58253702wic.10.1426277229154; Fri, 13 Mar 2015 13:07:09 -0700 (PDT) Received: from dft-labs.eu (n1x0n-1-pt.tunnel.tserv5.lon1.ipv6.he.net. [2001:470:1f08:1f7::2]) by mx.google.com with ESMTPSA id fm10sm4183793wib.7.2015.03.13.13.07.07 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 13 Mar 2015 13:07:07 -0700 (PDT) Date: Fri, 13 Mar 2015 21:07:05 +0100 From: Mateusz Guzik To: Tiwei Bie Subject: Re: [PATCH] Finish the task 'Convert mountlist_mtx to rwlock' Message-ID: <20150313200705.GA32157@dft-labs.eu> Mail-Followup-To: Mateusz Guzik , Tiwei Bie , Ryan Stone , "freebsd-hackers@freebsd.org" , wca@freebsd.org References: <1426079434-51568-1-git-send-email-btw@mail.ustc.edu.cn> <20150312132338.GA57932@freebsd> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20150312132338.GA57932@freebsd> User-Agent: Mutt/1.5.21 (2010-09-15) Cc: "freebsd-hackers@freebsd.org" , Ryan Stone , wca@freebsd.org X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 Mar 2015 20:07:11 -0000 On Thu, Mar 12, 2015 at 09:26:00PM +0800, Tiwei Bie wrote: > On Thu, Mar 12, 2015 at 12:06:02AM -0400, Ryan Stone wrote: > > On Wed, Mar 11, 2015 at 9:10 AM, Tiwei Bie wrote: > > > Hi, Mateusz! > > > > > > I have finished the task: Convert mountlist_mtx to rwlock [1]. > > > > My first comment is, are we sure that we actually want an rwlock here > > instead of an rmlock? An rmlock will offer much better performance in > > workloads that mostly only take read locks, and rmlocks do not suffer > > the priority inversion problems that rwlocks do. From the description > > on the wiki page, it sounds like an rmlock would be ideal here: > > > > > Interested person can upgrade this task to non-junior by coming up with a > > > solution exploiting rare need to modify the list. Example approaches include > > > designing a locking primitive with cheap shared locking (think: per-cpu) at > > > the expense of exclusive locking. > > > > I think rmlock is okay. But one more argument needs to be added > to vfs_busy(), that is 'struct rm_priotracker *tracker' which is > used to track read owners of mountlist_lock in vfs_busy(). So, this is not a simple s/rw_lock/rm_rlock and the like after all, sorry. :) I'll have to go over this and possibly gather some ACKs before committing. > > Following is my patch: > > --- > share/man/man9/vfs_busy.9 | 7 ++- > .../compat/opensolaris/kern/opensolaris_lookup.c | 2 +- > sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c | 5 ++- > .../opensolaris/uts/common/fs/zfs/zfs_ioctl.c | 6 ++- > .../opensolaris/uts/common/fs/zfs/zfs_vfsops.c | 6 ++- > sys/compat/linprocfs/linprocfs.c | 6 ++- > sys/fs/fuse/fuse_vnops.c | 4 +- > sys/fs/nfsclient/nfs_clstate.c | 2 +- > sys/fs/nfsclient/nfs_clvfsops.c | 2 +- > sys/fs/nfsclient/nfs_clvnops.c | 4 +- > sys/fs/nfsserver/nfs_nfsdport.c | 4 +- > sys/fs/nfsserver/nfs_nfsdserv.c | 2 +- > sys/fs/pseudofs/pseudofs_vnops.c | 6 +-- > sys/fs/smbfs/smbfs_vnops.c | 4 +- > sys/fs/tmpfs/tmpfs_vnops.c | 2 +- > sys/geom/journal/g_journal.c | 13 +++--- > sys/kern/vfs_extattr.c | 2 +- > sys/kern/vfs_lookup.c | 2 +- > sys/kern/vfs_mount.c | 26 ++++++----- > sys/kern/vfs_mountroot.c | 14 +++--- > sys/kern/vfs_subr.c | 51 ++++++++++++---------- > sys/kern/vfs_syscalls.c | 33 +++++++------- > sys/kern/vfs_vnops.c | 4 +- > sys/sys/mount.h | 8 ++-- > sys/ufs/ffs/ffs_softdep.c | 8 ++-- > sys/ufs/ffs/ffs_suspend.c | 2 +- > sys/ufs/ufs/ufs_quota.c | 2 +- > 27 files changed, 127 insertions(+), 100 deletions(-) > > diff --git a/share/man/man9/vfs_busy.9 b/share/man/man9/vfs_busy.9 > index 8b9ba86..155e1e6 100644 > --- a/share/man/man9/vfs_busy.9 > +++ b/share/man/man9/vfs_busy.9 > @@ -36,7 +36,7 @@ > .In sys/param.h > .In sys/mount.h > .Ft int > -.Fn vfs_busy "struct mount *mp" "int flags" > +.Fn vfs_busy "struct mount *mp" "int flags" "struct rm_priotracker *tracker" > .Sh DESCRIPTION > The > .Fn vfs_busy > @@ -68,8 +68,11 @@ do not sleep if > .Dv MNTK_UNMOUNT > is set. > .It Dv MBF_MNTLSTLOCK > -drop the mountlist_mtx in the critical path. > +drop the mountlist_lock in the critical path. > .El > +.It Fa tracker > +The tracker used to track read owners of mountlist_lock > +for priority propagation. > .El > .Sh RETURN VALUES > A 0 value is returned on success. > diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c b/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c > index 848007e..8e1c657b 100644 > --- a/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c > +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c > @@ -88,7 +88,7 @@ traverse(vnode_t **cvpp, int lktype) > vfsp = vn_mountedvfs(cvp); > if (vfsp == NULL) > break; > - error = vfs_busy(vfsp, 0); > + error = vfs_busy(vfsp, 0, NULL); > /* > * tvp is NULL for *cvpp vnode, which we can't unlock. > * At least some callers expect the reference to be > diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c > index a2532f8..9476641 100644 > --- a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c > +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c > @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); > #include > #include > #include > +#include > > MALLOC_DECLARE(M_MOUNT); > > @@ -222,9 +223,9 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath, > > vp->v_mountedhere = mp; > /* Put the new filesystem on the mount list. */ > - mtx_lock(&mountlist_mtx); > + rm_wlock(&mountlist_lock); > TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); > - mtx_unlock(&mountlist_mtx); > + rm_wunlock(&mountlist_lock); > vfs_event_signal(NULL, VQ_MOUNT, 0); > if (VFS_ROOT(mp, LK_EXCLUSIVE, &mvp)) > panic("mount: lost mount"); > diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c > index a829b06..a684516 100644 > --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c > +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c > @@ -142,6 +142,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -3014,15 +3015,16 @@ static vfs_t * > zfs_get_vfs(const char *resource) > { > vfs_t *vfsp; > + struct rm_priotracker tracker; > > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > TAILQ_FOREACH(vfsp, &mountlist, mnt_list) { > if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) { > VFS_HOLD(vfsp); > break; > } > } > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > return (vfsp); > } > > diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c > index 415db9e..55e11a1 100644 > --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c > +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c > @@ -62,6 +62,7 @@ > #include > #include > #include > +#include > #include "zfs_comutil.h" > > struct mtx zfs_debug_mtx; > @@ -2532,12 +2533,13 @@ zfsvfs_update_fromname(const char *oldname, const char *newname) > { > char tmpbuf[MAXPATHLEN]; > struct mount *mp; > + struct rm_priotracker tracker; > char *fromname; > size_t oldlen; > > oldlen = strlen(oldname); > > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > TAILQ_FOREACH(mp, &mountlist, mnt_list) { > fromname = mp->mnt_stat.f_mntfromname; > if (strcmp(fromname, oldname) == 0) { > @@ -2554,6 +2556,6 @@ zfsvfs_update_fromname(const char *oldname, const char *newname) > continue; > } > } > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > } > #endif > diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c > index 8607646..2d5a538 100644 > --- a/sys/compat/linprocfs/linprocfs.c > +++ b/sys/compat/linprocfs/linprocfs.c > @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); > #include > #include > #include > +#include > #include > #include > #include > @@ -327,6 +328,7 @@ linprocfs_domtab(PFS_FILL_ARGS) > { > struct nameidata nd; > struct mount *mp; > + struct rm_priotracker tracker; > const char *lep; > char *dlep, *flep, *mntto, *mntfrom, *fstype; > size_t lep_len; > @@ -344,7 +346,7 @@ linprocfs_domtab(PFS_FILL_ARGS) > } > lep_len = strlen(lep); > > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > error = 0; > TAILQ_FOREACH(mp, &mountlist, mnt_list) { > /* determine device name */ > @@ -387,7 +389,7 @@ linprocfs_domtab(PFS_FILL_ARGS) > /* a real Linux mtab will also show NFS options */ > sbuf_printf(sb, " 0 0\n"); > } > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > free(flep, M_TEMP); > return (error); > } > diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c > index 12b9778..b9827df 100644 > --- a/sys/fs/fuse/fuse_vnops.c > +++ b/sys/fs/fuse/fuse_vnops.c > @@ -902,11 +902,11 @@ calldaemon: > */ > mp = dvp->v_mount; > ltype = VOP_ISLOCKED(dvp); > - err = vfs_busy(mp, MBF_NOWAIT); > + err = vfs_busy(mp, MBF_NOWAIT, NULL); > if (err != 0) { > vfs_ref(mp); > VOP_UNLOCK(dvp, 0); > - err = vfs_busy(mp, 0); > + err = vfs_busy(mp, 0, NULL); > vn_lock(dvp, ltype | LK_RETRY); > vfs_rel(mp); > if (err) > diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c > index 2600b80..8737003 100644 > --- a/sys/fs/nfsclient/nfs_clstate.c > +++ b/sys/fs/nfsclient/nfs_clstate.c > @@ -3621,7 +3621,7 @@ nfscl_getmnt(int minorvers, uint8_t *sessionid, u_int32_t cbident, > mp = clp->nfsc_nmp->nm_mountp; > vfs_ref(mp); > NFSUNLOCKCLSTATE(); > - error = vfs_busy(mp, 0); > + error = vfs_busy(mp, 0, NULL); > vfs_rel(mp); > if (error != 0) > return (NULL); > diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c > index 9758b4c..aa8f8bc 100644 > --- a/sys/fs/nfsclient/nfs_clvfsops.c > +++ b/sys/fs/nfsclient/nfs_clvfsops.c > @@ -287,7 +287,7 @@ nfs_statfs(struct mount *mp, struct statfs *sbp) > > td = curthread; > > - error = vfs_busy(mp, MBF_NOWAIT); > + error = vfs_busy(mp, MBF_NOWAIT, NULL); > if (error) > return (error); > error = ncl_nget(mp, nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE); > diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c > index 513abf4..64a2eea 100644 > --- a/sys/fs/nfsclient/nfs_clvnops.c > +++ b/sys/fs/nfsclient/nfs_clvnops.c > @@ -1228,11 +1228,11 @@ nfs_lookup(struct vop_lookup_args *ap) > > if (flags & ISDOTDOT) { > ltype = NFSVOPISLOCKED(dvp); > - error = vfs_busy(mp, MBF_NOWAIT); > + error = vfs_busy(mp, MBF_NOWAIT, NULL); > if (error != 0) { > vfs_ref(mp); > NFSVOPUNLOCK(dvp, 0); > - error = vfs_busy(mp, 0); > + error = vfs_busy(mp, 0, NULL); > NFSVOPLOCK(dvp, ltype | LK_RETRY); > vfs_rel(mp); > if (error == 0 && (dvp->v_iflag & VI_DOOMED)) { > diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c > index 0ea48cd..c8a80c8 100644 > --- a/sys/fs/nfsserver/nfs_nfsdport.c > +++ b/sys/fs/nfsserver/nfs_nfsdport.c > @@ -1985,7 +1985,7 @@ again: > mp = vp->v_mount; > vfs_ref(mp); > NFSVOPUNLOCK(vp, 0); > - nd->nd_repstat = vfs_busy(mp, 0); > + nd->nd_repstat = vfs_busy(mp, 0, NULL); > vfs_rel(mp); > if (nd->nd_repstat != 0) { > vrele(vp); > @@ -2134,7 +2134,7 @@ again: > nvp->v_type == VDIR && > nvp->v_mountedhere != NULL) { > new_mp = nvp->v_mountedhere; > - r = vfs_busy(new_mp, 0); > + r = vfs_busy(new_mp, 0, NULL); > vput(nvp); > nvp = NULL; > if (r == 0) { > diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c > index e6e02d7..39f87c4 100644 > --- a/sys/fs/nfsserver/nfs_nfsdserv.c > +++ b/sys/fs/nfsserver/nfs_nfsdserv.c > @@ -271,7 +271,7 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram, > at_root = 0; > } > if (nd->nd_repstat == 0) > - nd->nd_repstat = vfs_busy(mp, 0); > + nd->nd_repstat = vfs_busy(mp, 0, NULL); > vfs_rel(mp); > if (nd->nd_repstat == 0) { > (void)nfsvno_fillattr(nd, mp, vp, &nva, > diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vnops.c > index f00b4b2..a0852ce 100644 > --- a/sys/fs/pseudofs/pseudofs_vnops.c > +++ b/sys/fs/pseudofs/pseudofs_vnops.c > @@ -392,7 +392,7 @@ pfs_vptocnp(struct vop_vptocnp_args *ap) > pfs_unlock(pd); > > mp = vp->v_mount; > - error = vfs_busy(mp, 0); > + error = vfs_busy(mp, 0, NULL); > if (error) > return (error); > > @@ -481,11 +481,11 @@ pfs_lookup(struct vop_cachedlookup_args *va) > if (cnp->cn_flags & ISDOTDOT) { > if (pd->pn_type == pfstype_root) > PFS_RETURN (EIO); > - error = vfs_busy(mp, MBF_NOWAIT); > + error = vfs_busy(mp, MBF_NOWAIT, NULL); > if (error != 0) { > vfs_ref(mp); > VOP_UNLOCK(vn, 0); > - error = vfs_busy(mp, 0); > + error = vfs_busy(mp, 0, NULL); > vn_lock(vn, LK_EXCLUSIVE | LK_RETRY); > vfs_rel(mp); > if (error != 0) > diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c > index 8ea1198..e0736fd 100644 > --- a/sys/fs/smbfs/smbfs_vnops.c > +++ b/sys/fs/smbfs/smbfs_vnops.c > @@ -1324,11 +1324,11 @@ smbfs_lookup(ap) > } > if (flags & ISDOTDOT) { > mp = dvp->v_mount; > - error = vfs_busy(mp, MBF_NOWAIT); > + error = vfs_busy(mp, MBF_NOWAIT, NULL); > if (error != 0) { > vfs_ref(mp); > VOP_UNLOCK(dvp, 0); > - error = vfs_busy(mp, 0); > + error = vfs_busy(mp, 0, NULL); > vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); > vfs_rel(mp); > if (error) { > diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c > index 885f84c..a366170 100644 > --- a/sys/fs/tmpfs/tmpfs_vnops.c > +++ b/sys/fs/tmpfs/tmpfs_vnops.c > @@ -789,7 +789,7 @@ tmpfs_rename(struct vop_rename_args *v) > if (fdvp != tdvp && fdvp != tvp) { > if (vn_lock(fdvp, LK_EXCLUSIVE | LK_NOWAIT) != 0) { > mp = tdvp->v_mount; > - error = vfs_busy(mp, 0); > + error = vfs_busy(mp, 0, NULL); > if (error != 0) { > mp = NULL; > goto out; > diff --git a/sys/geom/journal/g_journal.c b/sys/geom/journal/g_journal.c > index 9cc324c..3c2066e 100644 > --- a/sys/geom/journal/g_journal.c > +++ b/sys/geom/journal/g_journal.c > @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); > #include > #include > #include > +#include > #include > #include > #include > @@ -2867,6 +2868,7 @@ g_journal_do_switch(struct g_class *classp) > const struct g_journal_desc *desc; > struct g_geom *gp; > struct mount *mp; > + struct rm_priotracker tracker; > struct bintime bt; > char *mountpoint; > int error, save; > @@ -2888,7 +2890,7 @@ g_journal_do_switch(struct g_class *classp) > g_topology_unlock(); > PICKUP_GIANT(); > > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > TAILQ_FOREACH(mp, &mountlist, mnt_list) { > if (mp->mnt_gjprovider == NULL) > continue; > @@ -2897,9 +2899,10 @@ g_journal_do_switch(struct g_class *classp) > desc = g_journal_find_desc(mp->mnt_stat.f_fstypename); > if (desc == NULL) > continue; > - if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) > + if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK, &tracker)) > continue; > - /* mtx_unlock(&mountlist_mtx) was done inside vfs_busy() */ > + /* rm_runlock(&mountlist_lock, &tracker) was done inside > + * vfs_busy() */ > > DROP_GIANT(); > g_topology_lock(); > @@ -2977,10 +2980,10 @@ g_journal_do_switch(struct g_class *classp) > > vfs_write_resume(mp, 0); > next: > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > vfs_unbusy(mp); > } > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > > sc = NULL; > for (;;) { > diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c > index 24935ce..a82eddaf 100644 > --- a/sys/kern/vfs_extattr.c > +++ b/sys/kern/vfs_extattr.c > @@ -104,7 +104,7 @@ sys_extattrctl(td, uap) > if (error) > goto out; > mp = nd.ni_vp->v_mount; > - error = vfs_busy(mp, 0); > + error = vfs_busy(mp, 0, NULL); > if (error) { > NDFREE(&nd, 0); > mp = NULL; > diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c > index f2ffab2..610aa5f 100644 > --- a/sys/kern/vfs_lookup.c > +++ b/sys/kern/vfs_lookup.c > @@ -779,7 +779,7 @@ unionlookup: > */ > while (dp->v_type == VDIR && (mp = dp->v_mountedhere) && > (cnp->cn_flags & NOCROSSMOUNT) == 0) { > - if (vfs_busy(mp, 0)) > + if (vfs_busy(mp, 0, NULL)) > continue; > vput(dp); > if (dp != ndp->ni_dvp) > diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c > index 09fa7ed..636a55f 100644 > --- a/sys/kern/vfs_mount.c > +++ b/sys/kern/vfs_mount.c > @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); > #include > #include > #include > +#include > #include > #include > #include > @@ -85,8 +86,8 @@ static uma_zone_t mount_zone; > struct mntlist mountlist = TAILQ_HEAD_INITIALIZER(mountlist); > > /* For any iteration/modification of mountlist */ > -struct mtx mountlist_mtx; > -MTX_SYSINIT(mountlist, &mountlist_mtx, "mountlist", MTX_DEF); > +struct rmlock mountlist_lock; > +RM_SYSINIT(mountlist, &mountlist_lock, "mountlist"); > > /* > * Global opts, taken by all filesystems > @@ -462,7 +463,7 @@ vfs_mount_alloc(struct vnode *vp, struct vfsconf *vfsp, const char *fspath, > TAILQ_INIT(&mp->mnt_activevnodelist); > mp->mnt_activevnodelistsize = 0; > mp->mnt_ref = 0; > - (void) vfs_busy(mp, MBF_NOWAIT); > + (void) vfs_busy(mp, MBF_NOWAIT, NULL); > atomic_add_acq_int(&vfsp->vfc_refcount, 1); > mp->mnt_op = vfsp->vfc_vfsops; > mp->mnt_vfc = vfsp; > @@ -852,9 +853,9 @@ vfs_domount_first( > VI_UNLOCK(vp); > vp->v_mountedhere = mp; > /* Place the new filesystem at the end of the mount list. */ > - mtx_lock(&mountlist_mtx); > + rm_wlock(&mountlist_lock); > TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); > - mtx_unlock(&mountlist_mtx); > + rm_wunlock(&mountlist_lock); > vfs_event_signal(NULL, VQ_MOUNT, 0); > if (VFS_ROOT(mp, LK_EXCLUSIVE, &newdp)) > panic("mount: lost mount"); > @@ -918,7 +919,7 @@ vfs_domount_update( > vput(vp); > return (error); > } > - if (vfs_busy(mp, MBF_NOWAIT)) { > + if (vfs_busy(mp, MBF_NOWAIT, NULL)) { > vput(vp); > return (EBUSY); > } > @@ -1137,6 +1138,7 @@ sys_unmount(td, uap) > { > struct nameidata nd; > struct mount *mp; > + struct rm_priotracker tracker; > char *pathbuf; > int error, id0, id1; > > @@ -1161,13 +1163,13 @@ sys_unmount(td, uap) > return (EINVAL); > } > > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) { > if (mp->mnt_stat.f_fsid.val[0] == id0 && > mp->mnt_stat.f_fsid.val[1] == id1) > break; > } > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > } else { > /* > * Try to find global path for path argument. > @@ -1181,12 +1183,12 @@ sys_unmount(td, uap) > if (error == 0 || error == ENODEV) > vput(nd.ni_vp); > } > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) { > if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0) > break; > } > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > } > free(pathbuf, M_TEMP); > if (mp == NULL) { > @@ -1353,9 +1355,9 @@ dounmount(mp, flags, td) > VOP_UNLOCK(coveredvp, 0); > return (error); > } > - mtx_lock(&mountlist_mtx); > + rm_wlock(&mountlist_lock); > TAILQ_REMOVE(&mountlist, mp, mnt_list); > - mtx_unlock(&mountlist_mtx); > + rm_wunlock(&mountlist_lock); > EVENTHANDLER_INVOKE(vfs_unmounted, mp, td); > if (coveredvp != NULL) { > coveredvp->v_mountedhere = NULL; > diff --git a/sys/kern/vfs_mountroot.c b/sys/kern/vfs_mountroot.c > index a050099..ef3e9c9 100644 > --- a/sys/kern/vfs_mountroot.c > +++ b/sys/kern/vfs_mountroot.c > @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); > #include > #include > #include > +#include > #include > #include > #include > @@ -231,9 +232,9 @@ vfs_mountroot_devfs(struct thread *td, struct mount **mpp) > TAILQ_INIT(opts); > mp->mnt_opt = opts; > > - mtx_lock(&mountlist_mtx); > + rm_wlock(&mountlist_lock); > TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list); > - mtx_unlock(&mountlist_mtx); > + rm_wunlock(&mountlist_lock); > > *mpp = mp; > set_rootvnode(); > @@ -257,7 +258,7 @@ vfs_mountroot_shuffle(struct thread *td, struct mount *mpdevfs) > mpnroot = TAILQ_NEXT(mpdevfs, mnt_list); > > /* Shuffle the mountlist. */ > - mtx_lock(&mountlist_mtx); > + rm_wlock(&mountlist_lock); > mporoot = TAILQ_FIRST(&mountlist); > TAILQ_REMOVE(&mountlist, mpdevfs, mnt_list); > if (mporoot != mpdevfs) { > @@ -265,7 +266,7 @@ vfs_mountroot_shuffle(struct thread *td, struct mount *mpdevfs) > TAILQ_INSERT_HEAD(&mountlist, mpnroot, mnt_list); > } > TAILQ_INSERT_TAIL(&mountlist, mpdevfs, mnt_list); > - mtx_unlock(&mountlist_mtx); > + rm_wunlock(&mountlist_lock); > > cache_purgevfs(mporoot); > if (mporoot != mpdevfs) > @@ -933,6 +934,7 @@ void > vfs_mountroot(void) > { > struct mount *mp; > + struct rm_priotracker tracker; > struct sbuf *sb; > struct thread *td; > time_t timebase; > @@ -968,14 +970,14 @@ vfs_mountroot(void) > * timestamps we encounter. > */ > timebase = 0; > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > mp = TAILQ_FIRST(&mountlist); > while (mp != NULL) { > if (mp->mnt_time > timebase) > timebase = mp->mnt_time; > mp = TAILQ_NEXT(mp, mnt_list); > } > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > inittodr(timebase); > > /* Keep prison0's root in sync with the global rootvnode. */ > diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c > index fda80c9..3733178 100644 > --- a/sys/kern/vfs_subr.c > +++ b/sys/kern/vfs_subr.c > @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$"); > #include > #include > #include > +#include > #include > #include > #include > @@ -375,7 +376,7 @@ SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_FIRST, vntblinit, NULL); > > /* > * Mark a mount point as busy. Used to synchronize access and to delay > - * unmounting. Eventually, mountlist_mtx is not released on failure. > + * unmounting. Eventually, mountlist_lock is not released on failure. > * > * vfs_busy() is a custom lock, it can block the caller. > * vfs_busy() only sleeps if the unmount is active on the mount point. > @@ -410,7 +411,7 @@ SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_FIRST, vntblinit, NULL); > * dounmount() locks B while F is drained. > */ > int > -vfs_busy(struct mount *mp, int flags) > +vfs_busy(struct mount *mp, int flags, struct rm_priotracker *tracker) > { > > MPASS((flags & ~MBF_MASK) == 0); > @@ -439,15 +440,15 @@ vfs_busy(struct mount *mp, int flags) > return (ENOENT); > } > if (flags & MBF_MNTLSTLOCK) > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, tracker); > mp->mnt_kern_flag |= MNTK_MWAIT; > msleep(mp, MNT_MTX(mp), PVFS | PDROP, "vfs_busy", 0); > if (flags & MBF_MNTLSTLOCK) > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, tracker); > MNT_ILOCK(mp); > } > if (flags & MBF_MNTLSTLOCK) > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, tracker); > mp->mnt_lockref++; > MNT_IUNLOCK(mp); > return (0); > @@ -481,18 +482,19 @@ struct mount * > vfs_getvfs(fsid_t *fsid) > { > struct mount *mp; > + struct rm_priotracker tracker; > > CTR2(KTR_VFS, "%s: fsid %p", __func__, fsid); > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > TAILQ_FOREACH(mp, &mountlist, mnt_list) { > if (mp->mnt_stat.f_fsid.val[0] == fsid->val[0] && > mp->mnt_stat.f_fsid.val[1] == fsid->val[1]) { > vfs_ref(mp); > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > return (mp); > } > } > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > CTR2(KTR_VFS, "%s: lookup failed for %p id", __func__, fsid); > return ((struct mount *) 0); > } > @@ -501,7 +503,7 @@ vfs_getvfs(fsid_t *fsid) > * Lookup a mount point by filesystem identifier, busying it before > * returning. > * > - * To avoid congestion on mountlist_mtx, implement simple direct-mapped > + * To avoid congestion on mountlist_lock, implement simple direct-mapped > * cache for popular filesystem identifiers. The cache is lockess, using > * the fact that struct mount's are never freed. In worst case we may > * get pointer to unmounted or even different filesystem, so we have to > @@ -514,6 +516,7 @@ vfs_busyfs(fsid_t *fsid) > typedef struct mount * volatile vmp_t; > static vmp_t cache[FSID_CACHE_SIZE]; > struct mount *mp; > + struct rm_priotracker tracker; > int error; > uint32_t hash; > > @@ -525,7 +528,7 @@ vfs_busyfs(fsid_t *fsid) > mp->mnt_stat.f_fsid.val[0] != fsid->val[0] || > mp->mnt_stat.f_fsid.val[1] != fsid->val[1]) > goto slow; > - if (vfs_busy(mp, 0) != 0) { > + if (vfs_busy(mp, 0, NULL) != 0) { > cache[hash] = NULL; > goto slow; > } > @@ -536,14 +539,14 @@ vfs_busyfs(fsid_t *fsid) > vfs_unbusy(mp); > > slow: > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > TAILQ_FOREACH(mp, &mountlist, mnt_list) { > if (mp->mnt_stat.f_fsid.val[0] == fsid->val[0] && > mp->mnt_stat.f_fsid.val[1] == fsid->val[1]) { > - error = vfs_busy(mp, MBF_MNTLSTLOCK); > + error = vfs_busy(mp, MBF_MNTLSTLOCK, &tracker); > if (error) { > cache[hash] = NULL; > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > return (NULL); > } > cache[hash] = mp; > @@ -551,7 +554,7 @@ slow: > } > } > CTR2(KTR_VFS, "%s: lookup failed for %p id", __func__, fsid); > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > return ((struct mount *) 0); > } > > @@ -891,6 +894,7 @@ vnlru_proc(void) > struct mount *mp, *nmp; > int done; > struct proc *p = vnlruproc; > + struct rm_priotracker tracker; > > EVENTHANDLER_REGISTER(shutdown_pre_sync, kproc_shutdown, p, > SHUTDOWN_PRI_FIRST); > @@ -909,18 +913,18 @@ vnlru_proc(void) > } > mtx_unlock(&vnode_free_list_mtx); > done = 0; > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { > - if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) { > + if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK, &tracker)) { > nmp = TAILQ_NEXT(mp, mnt_list); > continue; > } > done += vlrureclaim(mp); > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > nmp = TAILQ_NEXT(mp, mnt_list); > vfs_unbusy(mp); > } > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > if (done == 0) { > #if 0 > /* These messages are temporary debugging aids */ > @@ -3397,6 +3401,7 @@ sysctl_vnode(SYSCTL_HANDLER_ARGS) > struct xvnode *xvn; > struct mount *mp; > struct vnode *vp; > + struct rm_priotracker tracker; > int error, len, n; > > /* > @@ -3413,9 +3418,9 @@ sysctl_vnode(SYSCTL_HANDLER_ARGS) > return (error); > xvn = malloc(len, M_TEMP, M_ZERO | M_WAITOK); > n = 0; > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > TAILQ_FOREACH(mp, &mountlist, mnt_list) { > - if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) > + if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK, &tracker)) > continue; > MNT_ILOCK(mp); > TAILQ_FOREACH(vp, &mp->mnt_nvnodelist, v_nmntvnodes) { > @@ -3465,12 +3470,12 @@ sysctl_vnode(SYSCTL_HANDLER_ARGS) > ++n; > } > MNT_IUNLOCK(mp); > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > vfs_unbusy(mp); > if (n == len) > break; > } > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > > error = SYSCTL_OUT(req, xvn, n * sizeof *xvn); > free(xvn, M_TEMP); > @@ -3760,7 +3765,7 @@ sync_fsync(struct vop_fsync_args *ap) > * Walk the list of vnodes pushing all that are dirty and > * not already on the sync list. > */ > - if (vfs_busy(mp, MBF_NOWAIT) != 0) > + if (vfs_busy(mp, MBF_NOWAIT, NULL) != 0) > return (0); > if (vn_start_write(NULL, &mp, V_NOWAIT) != 0) { > vfs_unbusy(mp); > diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c > index 14be379..0d3ae31 100644 > --- a/sys/kern/vfs_syscalls.c > +++ b/sys/kern/vfs_syscalls.c > @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); > #include > #include > #include > +#include > #include > #include > #include > @@ -129,11 +130,12 @@ sys_sync(td, uap) > struct sync_args *uap; > { > struct mount *mp, *nmp; > + struct rm_priotracker tracker; > int save; > > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { > - if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) { > + if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK, &tracker)) { > nmp = TAILQ_NEXT(mp, mnt_list); > continue; > } > @@ -145,11 +147,11 @@ sys_sync(td, uap) > curthread_pflags_restore(save); > vn_finished_write(mp); > } > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > nmp = TAILQ_NEXT(mp, mnt_list); > vfs_unbusy(mp); > } > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > return (0); > } > > @@ -190,7 +192,7 @@ sys_quotactl(td, uap) > mp = nd.ni_vp->v_mount; > vfs_ref(mp); > vput(nd.ni_vp); > - error = vfs_busy(mp, 0); > + error = vfs_busy(mp, 0, NULL); > vfs_rel(mp); > if (error != 0) > return (error); > @@ -297,7 +299,7 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, > vfs_ref(mp); > NDFREE(&nd, NDF_ONLY_PNBUF); > vput(nd.ni_vp); > - error = vfs_busy(mp, 0); > + error = vfs_busy(mp, 0, NULL); > vfs_rel(mp); > if (error != 0) > return (error); > @@ -383,7 +385,7 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf) > error = EBADF; > goto out; > } > - error = vfs_busy(mp, 0); > + error = vfs_busy(mp, 0, NULL); > vfs_rel(mp); > if (error != 0) > return (error); > @@ -449,6 +451,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, > enum uio_seg bufseg, int flags) > { > struct mount *mp, *nmp; > + struct rm_priotracker tracker; > struct statfs *sfsp, *sp, sb; > size_t count, maxcount; > int error; > @@ -460,18 +463,18 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, > sfsp = *buf; > else /* if (bufseg == UIO_SYSSPACE) */ { > count = 0; > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > TAILQ_FOREACH(mp, &mountlist, mnt_list) { > count++; > } > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > if (maxcount > count) > maxcount = count; > sfsp = *buf = malloc(maxcount * sizeof(struct statfs), M_TEMP, > M_WAITOK); > } > count = 0; > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { > if (prison_canseemount(td->td_ucred, mp) != 0) { > nmp = TAILQ_NEXT(mp, mnt_list); > @@ -483,7 +486,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, > continue; > } > #endif > - if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) { > + if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK, &tracker)) { > nmp = TAILQ_NEXT(mp, mnt_list); > continue; > } > @@ -504,7 +507,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, > if (((flags & (MNT_LAZY|MNT_NOWAIT)) == 0 || > (flags & MNT_WAIT)) && > (error = VFS_STATFS(mp, sp))) { > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > nmp = TAILQ_NEXT(mp, mnt_list); > vfs_unbusy(mp); > continue; > @@ -527,11 +530,11 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, > sfsp++; > } > count++; > - mtx_lock(&mountlist_mtx); > + rm_rlock(&mountlist_lock, &tracker); > nmp = TAILQ_NEXT(mp, mnt_list); > vfs_unbusy(mp); > } > - mtx_unlock(&mountlist_mtx); > + rm_runlock(&mountlist_lock, &tracker); > if (sfsp && count > maxcount) > td->td_retval[0] = maxcount; > else > @@ -741,7 +744,7 @@ sys_fchdir(td, uap) > AUDIT_ARG_VNODE1(vp); > error = change_dir(vp, td); > while (!error && (mp = vp->v_mountedhere) != NULL) { > - if (vfs_busy(mp, 0)) > + if (vfs_busy(mp, 0, NULL)) > continue; > error = VFS_ROOT(mp, LK_SHARED, &tdp); > vfs_unbusy(mp); > diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c > index ed4ad4d..8d38305 100644 > --- a/sys/kern/vfs_vnops.c > +++ b/sys/kern/vfs_vnops.c > @@ -2059,11 +2059,11 @@ vn_vget_ino_gen(struct vnode *vp, vn_get_ino_t alloc, void *alloc_arg, > ltype = VOP_ISLOCKED(vp); > KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED, > ("vn_vget_ino: vp not locked")); > - error = vfs_busy(mp, MBF_NOWAIT); > + error = vfs_busy(mp, MBF_NOWAIT, NULL); > if (error != 0) { > vfs_ref(mp); > VOP_UNLOCK(vp, 0); > - error = vfs_busy(mp, 0); > + error = vfs_busy(mp, 0, NULL); > vn_lock(vp, ltype | LK_RETRY); > vfs_rel(mp); > if (error != 0) > diff --git a/sys/sys/mount.h b/sys/sys/mount.h > index 6fb2d08..6c47d7f 100644 > --- a/sys/sys/mount.h > +++ b/sys/sys/mount.h > @@ -38,7 +38,9 @@ > #ifdef _KERNEL > #include > #include > +#include > #include > +#include > #include > #endif > > @@ -147,7 +149,7 @@ struct vfsopt { > * put on a doubly linked list. > * > * Lock reference: > - * m - mountlist_mtx > + * m - mountlist_lock > * i - interlock > * v - vnode freelist mutex > * > @@ -864,7 +866,7 @@ int vfs_setopts(struct vfsoptlist *opts, const char *name, > int vfs_setpublicfs /* set publicly exported fs */ > (struct mount *, struct netexport *, struct export_args *); > void vfs_msync(struct mount *, int); > -int vfs_busy(struct mount *, int); > +int vfs_busy(struct mount *, int, struct rm_priotracker *); > int vfs_export /* process mount export info */ > (struct mount *, struct export_args *); > void vfs_allocate_syncvnode(struct mount *); > @@ -890,7 +892,7 @@ int vfs_suser(struct mount *, struct thread *); > void vfs_unbusy(struct mount *); > void vfs_unmountall(void); > extern TAILQ_HEAD(mntlist, mount) mountlist; /* mounted filesystem list */ > -extern struct mtx mountlist_mtx; > +extern struct rmlock mountlist_lock; > extern struct nfs_public nfs_pub; > extern struct sx vfsconf_sx; > #define vfsconf_lock() sx_xlock(&vfsconf_sx) > diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c > index 700854e..8545df0 100644 > --- a/sys/ufs/ffs/ffs_softdep.c > +++ b/sys/ufs/ffs/ffs_softdep.c > @@ -12274,11 +12274,11 @@ restart: > FREE_LOCK(ump); > if (ffs_vgetf(mp, parentino, LK_NOWAIT | LK_EXCLUSIVE, &pvp, > FFSV_FORCEINSMQ)) { > - error = vfs_busy(mp, MBF_NOWAIT); > + error = vfs_busy(mp, MBF_NOWAIT, NULL); > if (error != 0) { > vfs_ref(mp); > VOP_UNLOCK(vp, 0); > - error = vfs_busy(mp, 0); > + error = vfs_busy(mp, 0, NULL); > vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); > vfs_rel(mp); > if (error != 0) > @@ -13427,7 +13427,7 @@ clear_remove(mp) > /* > * Let unmount clear deps > */ > - error = vfs_busy(mp, MBF_NOWAIT); > + error = vfs_busy(mp, MBF_NOWAIT, NULL); > if (error != 0) > goto finish_write; > error = ffs_vgetf(mp, ino, LK_EXCLUSIVE, &vp, > @@ -13503,7 +13503,7 @@ clear_inodedeps(mp) > if (vn_start_write(NULL, &mp, V_NOWAIT) != 0) > continue; > FREE_LOCK(ump); > - error = vfs_busy(mp, MBF_NOWAIT); /* Let unmount clear deps */ > + error = vfs_busy(mp, MBF_NOWAIT, NULL); /* Let unmount clear deps */ > if (error != 0) { > vn_finished_write(mp); > ACQUIRE_LOCK(ump); > diff --git a/sys/ufs/ffs/ffs_suspend.c b/sys/ufs/ffs/ffs_suspend.c > index b50fadc..6513a21 100644 > --- a/sys/ufs/ffs/ffs_suspend.c > +++ b/sys/ufs/ffs/ffs_suspend.c > @@ -286,7 +286,7 @@ ffs_susp_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, > error = ENOENT; > break; > } > - error = vfs_busy(mp, 0); > + error = vfs_busy(mp, 0, NULL); > vfs_rel(mp); > if (error != 0) > break; > diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c > index 4fbb8a1..3d17622 100644 > --- a/sys/ufs/ufs/ufs_quota.c > +++ b/sys/ufs/ufs/ufs_quota.c > @@ -519,7 +519,7 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname) > } > NDFREE(&nd, NDF_ONLY_PNBUF); > vp = nd.ni_vp; > - error = vfs_busy(mp, MBF_NOWAIT); > + error = vfs_busy(mp, MBF_NOWAIT, NULL); > vfs_rel(mp); > if (error == 0) { > if (vp->v_type != VREG) { > -- > 2.1.2 > > > The rmlock primitive does exactly this optimization. See the manpage > > for the API (it's mostly very similar to the rwlock API): > > https://www.freebsd.org/cgi/man.cgi?query=rmlock&apropos=0&sektion=0&manpath=FreeBSD+10.1-RELEASE&arch=default&format=html > > > > > > > void zfs_mountlist_wlock(void); > > > void zfs_mountlist_wunlock(void); > > > void zfs_mountlist_rlock(void); > > > void zfs_mountlist_runlock(void); > > > > Why not: > > > > #define zfs_mountlist_wlock() _zfs_mountlist_wlock(__FILE__, __LINE__) > > void _zfs_mountlist_wlock(const char *file, int line); > > > > /* etc, etc */ > > > > (This may be moot if we switch to an rmlock though) > > Tiwei Bie > -- Mateusz Guzik