Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-8]: src/sys Pull up following revision(s) (requested by hannken i...



details:   https://anonhg.NetBSD.org/src/rev/e03fde9d9c68
branches:  netbsd-8
changeset: 850951:e03fde9d9c68
user:      snj <snj%NetBSD.org@localhost>
date:      Fri Aug 25 05:46:46 2017 +0000

description:
Pull up following revision(s) (requested by hannken in ticket #227):
        sys/sys/vnode_impl.h: revision 1.16
        sys/kern/vfs_vnode.c: revision 1.97
        sys/kern/vfs_vnode.c: revision 1.98
        sys/kern/vfs_mount.c: revision 1.67
        sys/miscfs/deadfs/dead_vfsops.c: revision 1.8
No need to cache anonymous device vnodes, they will never be looked up.
Set key to (dead_rootmount, 0, NULL) and add assertions.
--
Change forced unmount to revert open device vnodes to anonymous devices.

diffstat:

 sys/kern/vfs_mount.c            |   13 +++-
 sys/kern/vfs_vnode.c            |  129 ++++++++++++++++++++++++++++++++-------
 sys/miscfs/deadfs/dead_vfsops.c |    8 +-
 sys/sys/vnode_impl.h            |    3 +-
 4 files changed, 120 insertions(+), 33 deletions(-)

diffs (272 lines):

diff -r 77f6a6d7f187 -r e03fde9d9c68 sys/kern/vfs_mount.c
--- a/sys/kern/vfs_mount.c      Fri Aug 25 05:44:48 2017 +0000
+++ b/sys/kern/vfs_mount.c      Fri Aug 25 05:46:46 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_mount.c,v 1.65.2.1 2017/06/04 20:35:01 bouyer Exp $        */
+/*     $NetBSD: vfs_mount.c,v 1.65.2.2 2017/08/25 05:46:46 snj 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.65.2.1 2017/06/04 20:35:01 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.65.2.2 2017/08/25 05:46:46 snj 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 77f6a6d7f187 -r e03fde9d9c68 sys/kern/vfs_vnode.c
--- a/sys/kern/vfs_vnode.c      Fri Aug 25 05:44:48 2017 +0000
+++ b/sys/kern/vfs_vnode.c      Fri Aug 25 05:46:46 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_vnode.c,v 1.93.2.1 2017/06/04 20:35:01 bouyer Exp $        */
+/*     $NetBSD: vfs_vnode.c,v 1.93.2.2 2017/08/25 05:46:46 snj 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.93.2.1 2017/06/04 20:35:01 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.93.2.2 2017/08/25 05:46:46 snj 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. */
@@ -1028,6 +1029,8 @@
 {
        uint32_t hash = HASH32_BUF_INIT;
 
+       KASSERT(key->vk_key_len > 0);
+
        hash = hash32_buf(&key->vk_mount, sizeof(struct mount *), hash);
        hash = hash32_buf(key->vk_key, key->vk_key_len, hash);
        return hash;
@@ -1381,23 +1384,29 @@
                KASSERT(*vpp == NULL);
                return error;
        }
-       KASSERT(vip->vi_key.vk_key != NULL);
        KASSERT(vp->v_op != NULL);
-       hash = vcache_hash(&vip->vi_key);
+       KASSERT((vip->vi_key.vk_key_len == 0) == (mp == dead_rootmount));
+       if (vip->vi_key.vk_key_len > 0) {
+               KASSERT(vip->vi_key.vk_key != NULL);
+               hash = vcache_hash(&vip->vi_key);
 
-       /* Wait for previous instance to be reclaimed, then insert new node. */
-       mutex_enter(&vcache_lock);
-       while ((ovip = vcache_hash_lookup(&vip->vi_key, hash))) {
-               ovp = VIMPL_TO_VNODE(ovip);
-               mutex_enter(ovp->v_interlock);
+               /*
+                * Wait for previous instance to be reclaimed,
+                * then insert new node.
+                */
+               mutex_enter(&vcache_lock);
+               while ((ovip = vcache_hash_lookup(&vip->vi_key, hash))) {
+                       ovp = VIMPL_TO_VNODE(ovip);
+                       mutex_enter(ovp->v_interlock);
+                       mutex_exit(&vcache_lock);
+                       error = vcache_vget(ovp);
+                       KASSERT(error == ENOENT);
+                       mutex_enter(&vcache_lock);
+               }
+               SLIST_INSERT_HEAD(&vcache_hashtab[hash & vcache_hashmask],
+                   vip, vi_hash);
                mutex_exit(&vcache_lock);
-               error = vcache_vget(ovp);
-               KASSERT(error == ENOENT);
-               mutex_enter(&vcache_lock);
        }
-       SLIST_INSERT_HEAD(&vcache_hashtab[hash & vcache_hashmask],
-           vip, vi_hash);
-       mutex_exit(&vcache_lock);
        vfs_insmntque(vp, mp);
        if ((mp->mnt_iflag & IMNT_MPSAFE) != 0)
                vp->v_vflag |= VV_MPSAFE;
@@ -1556,10 +1565,12 @@
        } else {
                temp_key = temp_buf;
        }
-       mutex_enter(&vcache_lock);
-       memcpy(temp_key, vip->vi_key.vk_key, temp_key_len);
-       vip->vi_key.vk_key = temp_key;
-       mutex_exit(&vcache_lock);
+       if (vip->vi_key.vk_key_len > 0) {
+               mutex_enter(&vcache_lock);
+               memcpy(temp_key, vip->vi_key.vk_key, temp_key_len);
+               vip->vi_key.vk_key = temp_key;
+               mutex_exit(&vcache_lock);
+       }
 
        fstrans_start(mp);
 
@@ -1604,13 +1615,15 @@
        /* Purge name cache. */
        cache_purge(vp);
 
+       if (vip->vi_key.vk_key_len > 0) {
        /* 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);
-       mutex_exit(&vcache_lock);
+               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);
+               mutex_exit(&vcache_lock);
+       }
        if (temp_key != temp_buf)
                kmem_free(temp_key, temp_key_len);
 
@@ -1638,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 77f6a6d7f187 -r e03fde9d9c68 sys/miscfs/deadfs/dead_vfsops.c
--- a/sys/miscfs/deadfs/dead_vfsops.c   Fri Aug 25 05:44:48 2017 +0000
+++ b/sys/miscfs/deadfs/dead_vfsops.c   Fri Aug 25 05:46:46 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dead_vfsops.c,v 1.7 2015/07/01 08:13:53 hannken Exp $  */
+/*     $NetBSD: dead_vfsops.c,v 1.7.10.1 2017/08/25 05:46:46 snj Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dead_vfsops.c,v 1.7 2015/07/01 08:13:53 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dead_vfsops.c,v 1.7.10.1 2017/08/25 05:46:46 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -108,8 +108,8 @@
        uvm_vnp_setsize(vp, 0);
        spec_node_init(vp, vap->va_rdev);
 
-       *key_len = sizeof(vp->v_interlock);
-       *new_key = &vp->v_interlock;
+       *key_len = 0;
+       *new_key = NULL;
 
        return 0;
 }
diff -r 77f6a6d7f187 -r e03fde9d9c68 sys/sys/vnode_impl.h
--- a/sys/sys/vnode_impl.h      Fri Aug 25 05:44:48 2017 +0000
+++ b/sys/sys/vnode_impl.h      Fri Aug 25 05:46:46 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vnode_impl.h,v 1.13.6.1 2017/06/04 20:35:01 bouyer Exp $       */
+/*     $NetBSD: vnode_impl.h,v 1.13.6.2 2017/08/25 05:46:46 snj 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