Change forced unmount to revert open device vnodes to anonymous devices.
This commit is contained in:
parent
7801661c06
commit
28650af9eb
@ -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.
|
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
|
||||||
@ -67,7 +67,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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/param.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
@ -558,9 +558,16 @@ vflush_one(vnode_t *vp, vnode_t *skipvp, int flags)
|
|||||||
return 0;
|
return 0;
|
||||||
/*
|
/*
|
||||||
* If FORCECLOSE is set, forcibly close the vnode.
|
* 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) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
vrele(vp);
|
vrele(vp);
|
||||||
|
@ -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.
|
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
|
||||||
@ -156,7 +156,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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/param.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
@ -225,6 +225,7 @@ static void vnpanic(vnode_t *, const char *, ...)
|
|||||||
/* Routines having to do with the management of the vnode table. */
|
/* Routines having to do with the management of the vnode table. */
|
||||||
extern struct mount *dead_rootmount;
|
extern struct mount *dead_rootmount;
|
||||||
extern int (**dead_vnodeop_p)(void *);
|
extern int (**dead_vnodeop_p)(void *);
|
||||||
|
extern int (**spec_vnodeop_p)(void *);
|
||||||
extern struct vfsops dead_vfsops;
|
extern struct vfsops dead_vfsops;
|
||||||
|
|
||||||
/* Vnode state operations and diagnostics. */
|
/* Vnode state operations and diagnostics. */
|
||||||
@ -1649,6 +1650,72 @@ vcache_reclaim(vnode_t *vp)
|
|||||||
KASSERT((vp->v_iflag & VI_ONWORKLST) == 0);
|
KASSERT((vp->v_iflag & VI_ONWORKLST) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
* Update outstanding I/O count and do wakeup if requested.
|
||||||
*/
|
*/
|
||||||
|
@ -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.
|
* Copyright (c) 2016 The NetBSD Foundation, Inc.
|
||||||
@ -119,6 +119,7 @@ vnode_t *
|
|||||||
vnalloc_marker(struct mount *);
|
vnalloc_marker(struct mount *);
|
||||||
void vnfree_marker(vnode_t *);
|
void vnfree_marker(vnode_t *);
|
||||||
bool vnis_marker(vnode_t *);
|
bool vnis_marker(vnode_t *);
|
||||||
|
void vcache_make_anon(vnode_t *);
|
||||||
int vcache_vget(vnode_t *);
|
int vcache_vget(vnode_t *);
|
||||||
int vcache_tryvget(vnode_t *);
|
int vcache_tryvget(vnode_t *);
|
||||||
int vfs_drainvnodes(void);
|
int vfs_drainvnodes(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user