Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern Switch vfs_getvfs(), dounmount() and vfs_mountroot(...
details: https://anonhg.NetBSD.org/src/rev/285d2994ccd2
branches: trunk
changeset: 352847:285d2994ccd2
user: hannken <hannken%NetBSD.org@localhost>
date: Wed Apr 12 10:35:10 2017 +0000
description:
Switch vfs_getvfs(), dounmount() and vfs_mountroot() to mountlist iterator.
Add a helper to retrieve a mount with "highest generation < arg" and
use it from vfs_unmount_forceone() and vfs_unmountall1().
diffstat:
sys/kern/vfs_mount.c | 100 +++++++++++++++++++++++++++++++++-----------------
1 files changed, 65 insertions(+), 35 deletions(-)
diffs (201 lines):
diff -r 3b9e62d07116 -r 285d2994ccd2 sys/kern/vfs_mount.c
--- a/sys/kern/vfs_mount.c Wed Apr 12 10:30:02 2017 +0000
+++ b/sys/kern/vfs_mount.c Wed Apr 12 10:35:10 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_mount.c,v 1.52 2017/04/11 07:46:37 hannken Exp $ */
+/* $NetBSD: vfs_mount.c,v 1.53 2017/04/12 10:35:10 hannken Exp $ */
/*-
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.52 2017/04/11 07:46:37 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.53 2017/04/12 10:35:10 hannken Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -234,11 +234,9 @@
++xxxfs_mntid;
tfsid.__fsid_val[0] = makedev(mtype & 0xff, xxxfs_mntid);
tfsid.__fsid_val[1] = mtype;
- if (!TAILQ_EMPTY(&mountlist)) {
- while (vfs_getvfs(&tfsid)) {
- tfsid.__fsid_val[0]++;
- xxxfs_mntid++;
- }
+ while (vfs_getvfs(&tfsid)) {
+ tfsid.__fsid_val[0]++;
+ xxxfs_mntid++;
}
mp->mnt_stat.f_fsidx.__fsid_val[0] = tfsid.__fsid_val[0];
mp->mnt_stat.f_fsid = mp->mnt_stat.f_fsidx.__fsid_val[0];
@@ -253,17 +251,18 @@
struct mount *
vfs_getvfs(fsid_t *fsid)
{
+ mount_iterator_t *iter;
struct mount *mp;
- mutex_enter(&mountlist_lock);
- TAILQ_FOREACH(mp, &mountlist, mnt_list) {
+ mountlist_iterator_init(&iter);
+ while ((mp = mountlist_iterator_next(iter)) != NULL) {
if (mp->mnt_stat.f_fsidx.__fsid_val[0] == fsid->__fsid_val[0] &&
mp->mnt_stat.f_fsidx.__fsid_val[1] == fsid->__fsid_val[1]) {
- mutex_exit(&mountlist_lock);
- return (mp);
+ mountlist_iterator_destroy(iter);
+ return mp;
}
}
- mutex_exit(&mountlist_lock);
+ mountlist_iterator_destroy(iter);
return NULL;
}
@@ -832,6 +831,7 @@
int
dounmount(struct mount *mp, int flags, struct lwp *l)
{
+ mount_iterator_t *iter;
struct mount *cmp;
vnode_t *coveredvp;
int error, async, used_syncer, used_extattr;
@@ -845,14 +845,14 @@
/*
* No unmount below layered mounts.
*/
- mutex_enter(&mountlist_lock);
- TAILQ_FOREACH(cmp, &mountlist, mnt_list) {
+ mountlist_iterator_init(&iter);
+ while ((cmp = mountlist_iterator_next(iter)) != NULL) {
if (cmp->mnt_lower == mp) {
- mutex_exit(&mountlist_lock);
+ mountlist_iterator_destroy(iter);
return EBUSY;
}
}
- mutex_exit(&mountlist_lock);
+ mountlist_iterator_destroy(iter);
/*
* XXX Freeze syncer. Must do this before locking the
@@ -983,38 +983,57 @@
mp->mnt_stat.f_fstypename);
}
+/*
+ * Return the mount with the highest generation less than "gen".
+ */
+static struct mount *
+vfs_unmount_next(uint64_t gen)
+{
+ mount_iterator_t *iter;
+ struct mount *mp, *nmp;
+
+ nmp = NULL;
+
+ mountlist_iterator_init(&iter);
+ while ((mp = mountlist_iterator_next(iter)) != NULL) {
+ if ((nmp == NULL || mp->mnt_gen > nmp->mnt_gen) &&
+ mp->mnt_gen < gen) {
+ if (nmp != NULL)
+ vfs_destroy(nmp);
+ nmp = mp;
+ atomic_inc_uint(&nmp->mnt_refcnt);
+ }
+ }
+ mountlist_iterator_destroy(iter);
+
+ return nmp;
+}
+
bool
vfs_unmount_forceone(struct lwp *l)
{
- struct mount *mp, *nmp;
+ struct mount *mp;
int error;
- nmp = NULL;
-
- TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) {
- if (nmp == NULL || mp->mnt_gen > nmp->mnt_gen) {
- nmp = mp;
- }
- }
- if (nmp == NULL) {
+ mp = vfs_unmount_next(mountgen);
+ if (mp == NULL) {
return false;
}
#ifdef DEBUG
printf("forcefully unmounting %s (%s)...\n",
- nmp->mnt_stat.f_mntonname, nmp->mnt_stat.f_mntfromname);
+ mp->mnt_stat.f_mntonname, mp->mnt_stat.f_mntfromname);
#endif
- atomic_inc_uint(&nmp->mnt_refcnt);
- if ((error = dounmount(nmp, MNT_FORCE, l)) == 0) {
- vfs_unmount_print(nmp, "forcefully ");
+ if ((error = dounmount(mp, MNT_FORCE, l)) == 0) {
+ vfs_unmount_print(mp, "forcefully ");
return true;
} else {
- vfs_destroy(nmp);
+ vfs_destroy(mp);
}
#ifdef DEBUG
printf("forceful unmount of %s failed with error %d\n",
- nmp->mnt_stat.f_mntonname, error);
+ mp->mnt_stat.f_mntonname, error);
#endif
return false;
@@ -1023,17 +1042,23 @@
bool
vfs_unmountall1(struct lwp *l, bool force, bool verbose)
{
- struct mount *mp, *nmp;
+ struct mount *mp;
bool any_error = false, progress = false;
+ uint64_t gen;
int error;
- TAILQ_FOREACH_REVERSE_SAFE(mp, &mountlist, mntlist, mnt_list, nmp) {
+ gen = mountgen;
+ for (;;) {
+ mp = vfs_unmount_next(gen);
+ if (mp == NULL)
+ break;
+ gen = mp->mnt_gen;
+
#ifdef DEBUG
printf("unmounting %p %s (%s)...\n",
(void *)mp, mp->mnt_stat.f_mntonname,
mp->mnt_stat.f_mntfromname);
#endif
- atomic_inc_uint(&mp->mnt_refcnt);
if ((error = dounmount(mp, force ? MNT_FORCE : 0, l)) == 0) {
vfs_unmount_print(mp, "");
progress = true;
@@ -1229,10 +1254,15 @@
vrele(rootvp);
}
if (error == 0) {
+ mount_iterator_t *iter;
struct mount *mp;
extern struct cwdinfo cwdi0;
- mp = TAILQ_FIRST(&mountlist);
+ mountlist_iterator_init(&iter);
+ mp = mountlist_iterator_next(iter);
+ KASSERT(mp != NULL);
+ mountlist_iterator_destroy(iter);
+
mp->mnt_flag |= MNT_ROOTFS;
mp->mnt_op->vfs_refcount++;
error = fstrans_mount(mp);
Home |
Main Index |
Thread Index |
Old Index