Source-Changes-HG archive

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

[src/trunk]: src/sys specfs: Let spec_node_lookup_by_dev wait for reclaim to ...



details:   https://anonhg.NetBSD.org/src/rev/f1c45b242bc6
branches:  trunk
changeset: 364519:f1c45b242bc6
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Mon Mar 28 12:37:46 2022 +0000

description:
specfs: Let spec_node_lookup_by_dev wait for reclaim to finish.

vdevgone relies on this to ensure that if there is a concurrent
revoke in progress, it will wait for that revoke to finish -- that
way, it can guarantee all I/O operations have completed and the
device is closed.

diffstat:

 sys/coda/coda_vfsops.c         |   6 +++---
 sys/kern/vfs_mount.c           |   7 ++++---
 sys/kern/vfs_subr.c            |  13 +++++++++----
 sys/kern/vfs_vnode.c           |   7 ++++---
 sys/miscfs/specfs/spec_vnops.c |  25 +++++++++++++++++++++----
 sys/miscfs/specfs/specdev.h    |   4 ++--
 6 files changed, 43 insertions(+), 19 deletions(-)

diffs (198 lines):

diff -r 286f4fe04b28 -r f1c45b242bc6 sys/coda/coda_vfsops.c
--- a/sys/coda/coda_vfsops.c    Mon Mar 28 12:37:35 2022 +0000
+++ b/sys/coda/coda_vfsops.c    Mon Mar 28 12:37:46 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: coda_vfsops.c,v 1.89 2020/11/20 10:08:47 hannken Exp $ */
+/*     $NetBSD: coda_vfsops.c,v 1.90 2022/03/28 12:37:46 riastradh Exp $       */
 
 /*
  *
@@ -45,7 +45,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: coda_vfsops.c,v 1.89 2020/11/20 10:08:47 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: coda_vfsops.c,v 1.90 2022/03/28 12:37:46 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -636,7 +636,7 @@
     struct mount *mp;
     struct vnode *vp;
 
-    if (spec_node_lookup_by_dev(VBLK, dev, &vp) == 0) {
+    if (spec_node_lookup_by_dev(VBLK, dev, VDEAD_NOWAIT, &vp) == 0) {
        mp = spec_node_getmountedfs(vp);
        vrele(vp);
     } else {
diff -r 286f4fe04b28 -r f1c45b242bc6 sys/kern/vfs_mount.c
--- a/sys/kern/vfs_mount.c      Mon Mar 28 12:37:35 2022 +0000
+++ b/sys/kern/vfs_mount.c      Mon Mar 28 12:37:46 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_mount.c,v 1.91 2022/03/24 12:59:56 riastradh Exp $ */
+/*     $NetBSD: vfs_mount.c,v 1.92 2022/03/28 12:37:46 riastradh Exp $ */
 
 /*-
  * Copyright (c) 1997-2020 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.91 2022/03/24 12:59:56 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.92 2022/03/28 12:37:46 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -1376,7 +1376,8 @@
                return ENOTBLK;
        if (spec_node_getmountedfs(vp) != NULL)
                return EBUSY;
-       if (spec_node_lookup_by_dev(vp->v_type, vp->v_rdev, &vq) == 0) {
+       if (spec_node_lookup_by_dev(vp->v_type, vp->v_rdev, VDEAD_NOWAIT, &vq)
+           == 0) {
                if (spec_node_getmountedfs(vq) != NULL)
                        error = EBUSY;
                vrele(vq);
diff -r 286f4fe04b28 -r f1c45b242bc6 sys/kern/vfs_subr.c
--- a/sys/kern/vfs_subr.c       Mon Mar 28 12:37:35 2022 +0000
+++ b/sys/kern/vfs_subr.c       Mon Mar 28 12:37:46 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_subr.c,v 1.491 2021/10/16 07:12:01 simonb Exp $    */
+/*     $NetBSD: vfs_subr.c,v 1.492 2022/03/28 12:37:46 riastradh Exp $ */
 
 /*-
  * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008, 2019, 2020
@@ -69,7 +69,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.491 2021/10/16 07:12:01 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.492 2022/03/28 12:37:46 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -495,7 +495,7 @@
 vfinddev(dev_t dev, enum vtype type, vnode_t **vpp)
 {
 
-       return (spec_node_lookup_by_dev(type, dev, vpp) == 0);
+       return (spec_node_lookup_by_dev(type, dev, VDEAD_NOWAIT, vpp) == 0);
 }
 
 /*
@@ -511,7 +511,12 @@
 
        for (mn = minl; mn <= minh; mn++) {
                dev = makedev(maj, mn);
-               while (spec_node_lookup_by_dev(type, dev, &vp) == 0) {
+               /*
+                * Passing 0 as flags, instead of VDEAD_NOWAIT, means
+                * spec_node_lookup_by_dev will wait for vnodes it
+                * finds concurrently being revoked before returning.
+                */
+               while (spec_node_lookup_by_dev(type, dev, 0, &vp) == 0) {
                        VOP_REVOKE(vp, REVOKEALL);
                        vrele(vp);
                }
diff -r 286f4fe04b28 -r f1c45b242bc6 sys/kern/vfs_vnode.c
--- a/sys/kern/vfs_vnode.c      Mon Mar 28 12:37:35 2022 +0000
+++ b/sys/kern/vfs_vnode.c      Mon Mar 28 12:37:46 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_vnode.c,v 1.139 2022/03/19 13:53:32 hannken Exp $  */
+/*     $NetBSD: vfs_vnode.c,v 1.140 2022/03/28 12:37:46 riastradh Exp $        */
 
 /*-
  * Copyright (c) 1997-2011, 2019, 2020 The NetBSD Foundation, Inc.
@@ -148,7 +148,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.139 2022/03/19 13:53:32 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.140 2022/03/28 12:37:46 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pax.h"
@@ -1231,7 +1231,8 @@
                type = vp->v_type;
                mutex_exit(vp->v_interlock);
 
-               while (spec_node_lookup_by_dev(type, dev, &vq) == 0) {
+               while (spec_node_lookup_by_dev(type, dev, VDEAD_NOWAIT, &vq)
+                   == 0) {
                        mp = vrevoke_suspend_next(mp, vq->v_mount);
                        vgone(vq);
                }
diff -r 286f4fe04b28 -r f1c45b242bc6 sys/miscfs/specfs/spec_vnops.c
--- a/sys/miscfs/specfs/spec_vnops.c    Mon Mar 28 12:37:35 2022 +0000
+++ b/sys/miscfs/specfs/spec_vnops.c    Mon Mar 28 12:37:46 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: spec_vnops.c,v 1.207 2022/03/28 12:37:35 riastradh Exp $       */
+/*     $NetBSD: spec_vnops.c,v 1.208 2022/03/28 12:37:46 riastradh Exp $       */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.207 2022/03/28 12:37:35 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.208 2022/03/28 12:37:46 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -424,18 +424,35 @@
  * Lookup a vnode by device number and return it referenced.
  */
 int
-spec_node_lookup_by_dev(enum vtype type, dev_t dev, vnode_t **vpp)
+spec_node_lookup_by_dev(enum vtype type, dev_t dev, int flags, vnode_t **vpp)
 {
        int error;
        vnode_t *vp;
 
-       mutex_enter(&device_lock);
+top:   mutex_enter(&device_lock);
        for (vp = specfs_hash[SPECHASH(dev)]; vp; vp = vp->v_specnext) {
                if (type == vp->v_type && dev == vp->v_rdev) {
                        mutex_enter(vp->v_interlock);
                        /* If clean or being cleaned, then ignore it. */
                        if (vdead_check(vp, VDEAD_NOWAIT) == 0)
                                break;
+                       if ((flags & VDEAD_NOWAIT) == 0) {
+                               mutex_exit(&device_lock);
+                               /*
+                                * It may be being revoked as we speak,
+                                * and the caller wants to wait until
+                                * all revocation has completed.  Let
+                                * vcache_vget wait for it to finish
+                                * dying; as a side effect, vcache_vget
+                                * releases vp->v_interlock.  Note that
+                                * vcache_vget cannot succeed at this
+                                * point because vdead_check already
+                                * failed.
+                                */
+                               error = vcache_vget(vp);
+                               KASSERT(error);
+                               goto top;
+                       }
                        mutex_exit(vp->v_interlock);
                }
        }
diff -r 286f4fe04b28 -r f1c45b242bc6 sys/miscfs/specfs/specdev.h
--- a/sys/miscfs/specfs/specdev.h       Mon Mar 28 12:37:35 2022 +0000
+++ b/sys/miscfs/specfs/specdev.h       Mon Mar 28 12:37:46 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: specdev.h,v 1.50 2022/03/28 12:37:09 riastradh Exp $   */
+/*     $NetBSD: specdev.h,v 1.51 2022/03/28 12:37:46 riastradh Exp $   */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -95,7 +95,7 @@
  */
 void   spec_node_init(vnode_t *, dev_t);
 void   spec_node_destroy(vnode_t *);
-int    spec_node_lookup_by_dev(enum vtype, dev_t, vnode_t **);
+int    spec_node_lookup_by_dev(enum vtype, dev_t, int, vnode_t **);
 int    spec_node_lookup_by_mount(struct mount *, vnode_t **);
 struct mount *spec_node_getmountedfs(vnode_t *);
 void   spec_node_setmountedfs(vnode_t *, struct mount *);



Home | Main Index | Thread Index | Old Index