Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Change forced unmount to revert open device vnodes to an...
details: https://anonhg.NetBSD.org/src/rev/13863d9730ed
branches: trunk
changeset: 355906:13863d9730ed
user: hannken <hannken%NetBSD.org@localhost>
date: Mon Aug 21 09:00:21 2017 +0000
description:
Change forced unmount to revert open device vnodes to anonymous devices.
diffstat:
sys/kern/vfs_mount.c | 13 +++++++--
sys/kern/vfs_vnode.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++-
sys/sys/vnode_impl.h | 3 +-
3 files changed, 81 insertions(+), 6 deletions(-)
diffs (152 lines):
diff -r 3687fe4ce6a6 -r 13863d9730ed sys/kern/vfs_mount.c
--- a/sys/kern/vfs_mount.c Mon Aug 21 08:56:45 2017 +0000
+++ b/sys/kern/vfs_mount.c Mon Aug 21 09:00:21 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_mount.c,v 1.66 2017/06/04 08:05:42 hannken Exp $ */
+/* $NetBSD: vfs_mount.c,v 1.67 2017/08/21 09:00:21 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.66 2017/06/04 08:05:42 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.67 2017/08/21 09:00:21 hannken Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -558,9 +558,16 @@
return 0;
/*
* If FORCECLOSE is set, forcibly close the vnode.
+ * For block or character devices, revert to an
+ * anonymous device. For all other files, just
+ * kill them.
*/
if (flags & FORCECLOSE) {
- vgone(vp);
+ if (vp->v_usecount > 1 &&
+ (vp->v_type == VBLK || vp->v_type == VCHR))
+ vcache_make_anon(vp);
+ else
+ vgone(vp);
return 0;
}
vrele(vp);
diff -r 3687fe4ce6a6 -r 13863d9730ed sys/kern/vfs_vnode.c
--- a/sys/kern/vfs_vnode.c Mon Aug 21 08:56:45 2017 +0000
+++ b/sys/kern/vfs_vnode.c Mon Aug 21 09:00:21 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_vnode.c,v 1.97 2017/08/21 08:56:45 hannken Exp $ */
+/* $NetBSD: vfs_vnode.c,v 1.98 2017/08/21 09:00:21 hannken Exp $ */
/*-
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -156,7 +156,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.97 2017/08/21 08:56:45 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.98 2017/08/21 09:00:21 hannken Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -225,6 +225,7 @@
/* Routines having to do with the management of the vnode table. */
extern struct mount *dead_rootmount;
extern int (**dead_vnodeop_p)(void *);
+extern int (**spec_vnodeop_p)(void *);
extern struct vfsops dead_vfsops;
/* Vnode state operations and diagnostics. */
@@ -1650,6 +1651,72 @@
}
/*
+ * Disassociate the underlying file system from an open device vnode
+ * and make it anonymous.
+ *
+ * Vnode unlocked on entry, drops a reference to the vnode.
+ */
+void
+vcache_make_anon(vnode_t *vp)
+{
+ vnode_impl_t *vip = VNODE_TO_VIMPL(vp);
+ uint32_t hash;
+ bool recycle;
+
+ KASSERT(vp->v_type == VBLK || vp->v_type == VCHR);
+ KASSERT((vp->v_mount->mnt_iflag & IMNT_HAS_TRANS) == 0 ||
+ fstrans_is_owner(vp->v_mount));
+ VSTATE_ASSERT_UNLOCKED(vp, VS_ACTIVE);
+
+ /* Remove from vnode cache. */
+ hash = vcache_hash(&vip->vi_key);
+ mutex_enter(&vcache_lock);
+ KASSERT(vip == vcache_hash_lookup(&vip->vi_key, hash));
+ SLIST_REMOVE(&vcache_hashtab[hash & vcache_hashmask],
+ vip, vnode_impl, vi_hash);
+ vip->vi_key.vk_mount = dead_rootmount;
+ vip->vi_key.vk_key_len = 0;
+ vip->vi_key.vk_key = NULL;
+ mutex_exit(&vcache_lock);
+
+ /*
+ * Disassociate the underlying file system from the vnode.
+ * VOP_INACTIVE leaves the vnode locked; VOP_RECLAIM unlocks
+ * the vnode, and may destroy the vnode so that VOP_UNLOCK
+ * would no longer function.
+ */
+ if (vn_lock(vp, LK_EXCLUSIVE)) {
+ vnpanic(vp, "%s: cannot lock", __func__);
+ }
+ VOP_INACTIVE(vp, &recycle);
+ KASSERT((vp->v_vflag & VV_LOCKSWORK) == 0 ||
+ VOP_ISLOCKED(vp) == LK_EXCLUSIVE);
+ if (VOP_RECLAIM(vp)) {
+ vnpanic(vp, "%s: cannot reclaim", __func__);
+ }
+
+ /* Purge name cache. */
+ cache_purge(vp);
+
+ /* Done with purge, change operations vector. */
+ mutex_enter(vp->v_interlock);
+ vp->v_op = spec_vnodeop_p;
+ vp->v_vflag |= VV_MPSAFE;
+ vp->v_vflag &= ~VV_LOCKSWORK;
+ mutex_exit(vp->v_interlock);
+
+ /*
+ * Move to dead mount. Must be after changing the operations
+ * vector as vnode operations enter the mount before using the
+ * operations vector. See sys/kern/vnode_if.c.
+ */
+ vfs_ref(dead_rootmount);
+ vfs_insmntque(vp, dead_rootmount);
+
+ vrele(vp);
+}
+
+/*
* Update outstanding I/O count and do wakeup if requested.
*/
void
diff -r 3687fe4ce6a6 -r 13863d9730ed sys/sys/vnode_impl.h
--- a/sys/sys/vnode_impl.h Mon Aug 21 08:56:45 2017 +0000
+++ b/sys/sys/vnode_impl.h Mon Aug 21 09:00:21 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vnode_impl.h,v 1.15 2017/06/04 08:02:26 hannken Exp $ */
+/* $NetBSD: vnode_impl.h,v 1.16 2017/08/21 09:00:21 hannken Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -119,6 +119,7 @@
vnalloc_marker(struct mount *);
void vnfree_marker(vnode_t *);
bool vnis_marker(vnode_t *);
+void vcache_make_anon(vnode_t *);
int vcache_vget(vnode_t *);
int vcache_tryvget(vnode_t *);
int vfs_drainvnodes(void);
Home |
Main Index |
Thread Index |
Old Index