[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