[PATCH] Finish the task 'Convert mountlist_mtx to rwlock'
Tiwei Bie
btw at mail.ustc.edu.cn
Wed Mar 11 13:10:57 UTC 2015
Hi, Mateusz!
I have finished the task: Convert mountlist_mtx to rwlock [1].
sys/rwlock.h and cddl/compat/opensolaris/sys/rwlock.h have defined
the same symbols, such as rw_init(), rw_destroy(). So they could not
be included in the same file. And the latter has been indirectly
included in cddl/compat/opensolaris/kern/opensolaris_vfs.c and
cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
which needs to use mountlist_lock. So I implemented the following
functions to access mountlist_lock in these files:
void zfs_mountlist_wlock(void);
void zfs_mountlist_wunlock(void);
void zfs_mountlist_rlock(void);
void zfs_mountlist_runlock(void);
Following is my patch:
---
.../compat/opensolaris/kern/opensolaris_mount.c | 66 ++++++++++++++++++++++
sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c | 4 +-
sys/cddl/compat/opensolaris/sys/mount.h | 5 ++
.../opensolaris/uts/common/fs/zfs/zfs_ioctl.c | 4 +-
.../opensolaris/uts/common/fs/zfs/zfs_vfsops.c | 4 +-
sys/compat/linprocfs/linprocfs.c | 4 +-
sys/geom/journal/g_journal.c | 9 +--
sys/kern/vfs_mount.c | 21 +++----
sys/kern/vfs_mountroot.c | 13 +++--
sys/kern/vfs_subr.c | 34 +++++------
sys/kern/vfs_syscalls.c | 18 +++---
sys/modules/zfs/Makefile | 1 +
sys/sys/mount.h | 5 +-
13 files changed, 132 insertions(+), 56 deletions(-)
create mode 100644 sys/cddl/compat/opensolaris/kern/opensolaris_mount.c
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_mount.c b/sys/cddl/compat/opensolaris/kern/opensolaris_mount.c
new file mode 100644
index 0000000..1a844d8
--- /dev/null
+++ b/sys/cddl/compat/opensolaris/kern/opensolaris_mount.c
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) .
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mount.h>
+#include <sys/freebsd_rwlock.h>
+
+void
+zfs_mountlist_wlock(void)
+{
+
+ /*
+ * This is not ideal because FILE/LINE used by assertions will not
+ * be too helpful, but it must be an hard function for
+ * compatibility reasons.
+ */
+ rw_wlock(&mountlist_lock);
+}
+
+void
+zfs_mountlist_wunlock(void)
+{
+
+ rw_wunlock(&mountlist_lock);
+}
+
+void
+zfs_mountlist_rlock(void)
+{
+
+ rw_rlock(&mountlist_lock);
+}
+
+void
+zfs_mountlist_runlock(void)
+{
+
+ rw_runlock(&mountlist_lock);
+}
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c
index a2532f8..045aa80 100644
--- a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c
+++ b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c
@@ -222,9 +222,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);
+ zfs_mountlist_wlock();
TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
- mtx_unlock(&mountlist_mtx);
+ zfs_mountlist_wunlock();
vfs_event_signal(NULL, VQ_MOUNT, 0);
if (VFS_ROOT(mp, LK_EXCLUSIVE, &mvp))
panic("mount: lost mount");
diff --git a/sys/cddl/compat/opensolaris/sys/mount.h b/sys/cddl/compat/opensolaris/sys/mount.h
index e012597..8ad4598 100644
--- a/sys/cddl/compat/opensolaris/sys/mount.h
+++ b/sys/cddl/compat/opensolaris/sys/mount.h
@@ -38,4 +38,9 @@
typedef struct fid fid_t;
+void zfs_mountlist_wlock(void);
+void zfs_mountlist_wunlock(void);
+void zfs_mountlist_rlock(void);
+void zfs_mountlist_runlock(void);
+
#endif /* !_OPENSOLARIS_SYS_MOUNT_H_ */
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..4d86892 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
@@ -3015,14 +3015,14 @@ zfs_get_vfs(const char *resource)
{
vfs_t *vfsp;
- mtx_lock(&mountlist_mtx);
+ zfs_mountlist_rlock();
TAILQ_FOREACH(vfsp, &mountlist, mnt_list) {
if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) {
VFS_HOLD(vfsp);
break;
}
}
- mtx_unlock(&mountlist_mtx);
+ zfs_mountlist_runlock();
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..9b29323 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
@@ -2537,7 +2537,7 @@ zfsvfs_update_fromname(const char *oldname, const char *newname)
oldlen = strlen(oldname);
- mtx_lock(&mountlist_mtx);
+ zfs_mountlist_rlock();
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
fromname = mp->mnt_stat.f_mntfromname;
if (strcmp(fromname, oldname) == 0) {
@@ -2554,6 +2554,6 @@ zfsvfs_update_fromname(const char *oldname, const char *newname)
continue;
}
}
- mtx_unlock(&mountlist_mtx);
+ zfs_mountlist_runlock();
}
#endif
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 8607646..b39f194 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -344,7 +344,7 @@ linprocfs_domtab(PFS_FILL_ARGS)
}
lep_len = strlen(lep);
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
error = 0;
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
/* determine device name */
@@ -387,7 +387,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);
+ rw_runlock(&mountlist_lock);
free(flep, M_TEMP);
return (error);
}
diff --git a/sys/geom/journal/g_journal.c b/sys/geom/journal/g_journal.c
index 9cc324c..bdef5d1 100644
--- a/sys/geom/journal/g_journal.c
+++ b/sys/geom/journal/g_journal.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/rwlock.h>
#include <sys/bio.h>
#include <sys/sysctl.h>
#include <sys/malloc.h>
@@ -2888,7 +2889,7 @@ g_journal_do_switch(struct g_class *classp)
g_topology_unlock();
PICKUP_GIANT();
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
if (mp->mnt_gjprovider == NULL)
continue;
@@ -2899,7 +2900,7 @@ g_journal_do_switch(struct g_class *classp)
continue;
if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK))
continue;
- /* mtx_unlock(&mountlist_mtx) was done inside vfs_busy() */
+ /* rw_runlock(&mountlist_lock) was done inside vfs_busy() */
DROP_GIANT();
g_topology_lock();
@@ -2977,10 +2978,10 @@ g_journal_do_switch(struct g_class *classp)
vfs_write_resume(mp, 0);
next:
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
vfs_unbusy(mp);
}
- mtx_unlock(&mountlist_mtx);
+ rw_runlock(&mountlist_lock);
sc = NULL;
for (;;) {
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 09fa7ed..da4b452 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/filedesc.h>
#include <sys/reboot.h>
+#include <sys/rwlock.h>
#include <sys/sbuf.h>
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
@@ -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 rwlock mountlist_lock;
+RW_SYSINIT(mountlist, &mountlist_lock, "mountlist");
/*
* Global opts, taken by all filesystems
@@ -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);
+ rw_wlock(&mountlist_lock);
TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
- mtx_unlock(&mountlist_mtx);
+ rw_wunlock(&mountlist_lock);
vfs_event_signal(NULL, VQ_MOUNT, 0);
if (VFS_ROOT(mp, LK_EXCLUSIVE, &newdp))
panic("mount: lost mount");
@@ -1161,13 +1162,13 @@ sys_unmount(td, uap)
return (EINVAL);
}
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
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);
+ rw_runlock(&mountlist_lock);
} else {
/*
* Try to find global path for path argument.
@@ -1181,12 +1182,12 @@ sys_unmount(td, uap)
if (error == 0 || error == ENODEV)
vput(nd.ni_vp);
}
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) {
if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0)
break;
}
- mtx_unlock(&mountlist_mtx);
+ rw_runlock(&mountlist_lock);
}
free(pathbuf, M_TEMP);
if (mp == NULL) {
@@ -1353,9 +1354,9 @@ dounmount(mp, flags, td)
VOP_UNLOCK(coveredvp, 0);
return (error);
}
- mtx_lock(&mountlist_mtx);
+ rw_wlock(&mountlist_lock);
TAILQ_REMOVE(&mountlist, mp, mnt_list);
- mtx_unlock(&mountlist_mtx);
+ rw_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..2ba1f36 100644
--- a/sys/kern/vfs_mountroot.c
+++ b/sys/kern/vfs_mountroot.c
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/filedesc.h>
#include <sys/reboot.h>
+#include <sys/rwlock.h>
#include <sys/sbuf.h>
#include <sys/stat.h>
#include <sys/syscallsubr.h>
@@ -231,9 +232,9 @@ vfs_mountroot_devfs(struct thread *td, struct mount **mpp)
TAILQ_INIT(opts);
mp->mnt_opt = opts;
- mtx_lock(&mountlist_mtx);
+ rw_wlock(&mountlist_lock);
TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list);
- mtx_unlock(&mountlist_mtx);
+ rw_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);
+ rw_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);
+ rw_wunlock(&mountlist_lock);
cache_purgevfs(mporoot);
if (mporoot != mpdevfs)
@@ -968,14 +969,14 @@ vfs_mountroot(void)
* timestamps we encounter.
*/
timebase = 0;
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
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);
+ rw_runlock(&mountlist_lock);
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..de9ee7f 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -375,7 +375,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.
@@ -439,15 +439,15 @@ vfs_busy(struct mount *mp, int flags)
return (ENOENT);
}
if (flags & MBF_MNTLSTLOCK)
- mtx_unlock(&mountlist_mtx);
+ rw_runlock(&mountlist_lock);
mp->mnt_kern_flag |= MNTK_MWAIT;
msleep(mp, MNT_MTX(mp), PVFS | PDROP, "vfs_busy", 0);
if (flags & MBF_MNTLSTLOCK)
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
MNT_ILOCK(mp);
}
if (flags & MBF_MNTLSTLOCK)
- mtx_unlock(&mountlist_mtx);
+ rw_runlock(&mountlist_lock);
mp->mnt_lockref++;
MNT_IUNLOCK(mp);
return (0);
@@ -483,16 +483,16 @@ vfs_getvfs(fsid_t *fsid)
struct mount *mp;
CTR2(KTR_VFS, "%s: fsid %p", __func__, fsid);
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
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);
+ rw_runlock(&mountlist_lock);
return (mp);
}
}
- mtx_unlock(&mountlist_mtx);
+ rw_runlock(&mountlist_lock);
CTR2(KTR_VFS, "%s: lookup failed for %p id", __func__, fsid);
return ((struct mount *) 0);
}
@@ -501,7 +501,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
@@ -536,14 +536,14 @@ vfs_busyfs(fsid_t *fsid)
vfs_unbusy(mp);
slow:
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
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);
if (error) {
cache[hash] = NULL;
- mtx_unlock(&mountlist_mtx);
+ rw_runlock(&mountlist_lock);
return (NULL);
}
cache[hash] = mp;
@@ -551,7 +551,7 @@ slow:
}
}
CTR2(KTR_VFS, "%s: lookup failed for %p id", __func__, fsid);
- mtx_unlock(&mountlist_mtx);
+ rw_runlock(&mountlist_lock);
return ((struct mount *) 0);
}
@@ -909,18 +909,18 @@ vnlru_proc(void)
}
mtx_unlock(&vnode_free_list_mtx);
done = 0;
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) {
nmp = TAILQ_NEXT(mp, mnt_list);
continue;
}
done += vlrureclaim(mp);
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
nmp = TAILQ_NEXT(mp, mnt_list);
vfs_unbusy(mp);
}
- mtx_unlock(&mountlist_mtx);
+ rw_runlock(&mountlist_lock);
if (done == 0) {
#if 0
/* These messages are temporary debugging aids */
@@ -3413,7 +3413,7 @@ sysctl_vnode(SYSCTL_HANDLER_ARGS)
return (error);
xvn = malloc(len, M_TEMP, M_ZERO | M_WAITOK);
n = 0;
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK))
continue;
@@ -3465,12 +3465,12 @@ sysctl_vnode(SYSCTL_HANDLER_ARGS)
++n;
}
MNT_IUNLOCK(mp);
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
vfs_unbusy(mp);
if (n == len)
break;
}
- mtx_unlock(&mountlist_mtx);
+ rw_runlock(&mountlist_lock);
error = SYSCTL_OUT(req, xvn, n * sizeof *xvn);
free(xvn, M_TEMP);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 14be379..08f4bae 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -131,7 +131,7 @@ sys_sync(td, uap)
struct mount *mp, *nmp;
int save;
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
if (vfs_busy(mp, MBF_NOWAIT | MBF_MNTLSTLOCK)) {
nmp = TAILQ_NEXT(mp, mnt_list);
@@ -145,11 +145,11 @@ sys_sync(td, uap)
curthread_pflags_restore(save);
vn_finished_write(mp);
}
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
nmp = TAILQ_NEXT(mp, mnt_list);
vfs_unbusy(mp);
}
- mtx_unlock(&mountlist_mtx);
+ rw_runlock(&mountlist_lock);
return (0);
}
@@ -460,18 +460,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);
+ rw_rlock(&mountlist_lock);
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
count++;
}
- mtx_unlock(&mountlist_mtx);
+ rw_runlock(&mountlist_lock);
if (maxcount > count)
maxcount = count;
sfsp = *buf = malloc(maxcount * sizeof(struct statfs), M_TEMP,
M_WAITOK);
}
count = 0;
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
if (prison_canseemount(td->td_ucred, mp) != 0) {
nmp = TAILQ_NEXT(mp, mnt_list);
@@ -504,7 +504,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);
+ rw_rlock(&mountlist_lock);
nmp = TAILQ_NEXT(mp, mnt_list);
vfs_unbusy(mp);
continue;
@@ -527,11 +527,11 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
sfsp++;
}
count++;
- mtx_lock(&mountlist_mtx);
+ rw_rlock(&mountlist_lock);
nmp = TAILQ_NEXT(mp, mnt_list);
vfs_unbusy(mp);
}
- mtx_unlock(&mountlist_mtx);
+ rw_runlock(&mountlist_lock);
if (sfsp && count > maxcount)
td->td_retval[0] = maxcount;
else
diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile
index 29f4ae0..52f083d 100644
--- a/sys/modules/zfs/Makefile
+++ b/sys/modules/zfs/Makefile
@@ -25,6 +25,7 @@ SRCS+= opensolaris_dtrace.c
SRCS+= opensolaris_kobj.c
SRCS+= opensolaris_kstat.c
SRCS+= opensolaris_lookup.c
+SRCS+= opensolaris_mount.c
SRCS+= opensolaris_policy.c
SRCS+= opensolaris_string.c
SRCS+= opensolaris_sysevent.c
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 6fb2d08..376d613 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -39,6 +39,7 @@
#include <sys/lock.h>
#include <sys/lockmgr.h>
#include <sys/_mutex.h>
+#include <sys/_rwlock.h>
#include <sys/_sx.h>
#endif
@@ -147,7 +148,7 @@ struct vfsopt {
* put on a doubly linked list.
*
* Lock reference:
- * m - mountlist_mtx
+ * m - mountlist_lock
* i - interlock
* v - vnode freelist mutex
*
@@ -890,7 +891,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 rwlock mountlist_lock;
extern struct nfs_public nfs_pub;
extern struct sx vfsconf_sx;
#define vfsconf_lock() sx_xlock(&vfsconf_sx)
--
2.1.2
[1] https://wiki.freebsd.org/JuniorJobs#Convert_mountlist_mtx_to_rwlock
Tiwei Bie
More information about the freebsd-hackers
mailing list