Module Name: src Committed By: riastradh Date: Mon Mar 28 12:37:46 UTC 2022
Modified Files: src/sys/coda: coda_vfsops.c src/sys/kern: vfs_mount.c vfs_subr.c vfs_vnode.c src/sys/miscfs/specfs: spec_vnops.c specdev.h Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.89 -r1.90 src/sys/coda/coda_vfsops.c cvs rdiff -u -r1.91 -r1.92 src/sys/kern/vfs_mount.c cvs rdiff -u -r1.491 -r1.492 src/sys/kern/vfs_subr.c cvs rdiff -u -r1.139 -r1.140 src/sys/kern/vfs_vnode.c cvs rdiff -u -r1.207 -r1.208 src/sys/miscfs/specfs/spec_vnops.c cvs rdiff -u -r1.50 -r1.51 src/sys/miscfs/specfs/specdev.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/coda/coda_vfsops.c diff -u src/sys/coda/coda_vfsops.c:1.89 src/sys/coda/coda_vfsops.c:1.90 --- src/sys/coda/coda_vfsops.c:1.89 Fri Nov 20 10:08:47 2020 +++ src/sys/coda/coda_vfsops.c Mon Mar 28 12:37:46 2022 @@ -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 *devtomp(dev_t dev) 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 { Index: src/sys/kern/vfs_mount.c diff -u src/sys/kern/vfs_mount.c:1.91 src/sys/kern/vfs_mount.c:1.92 --- src/sys/kern/vfs_mount.c:1.91 Thu Mar 24 12:59:56 2022 +++ src/sys/kern/vfs_mount.c Mon Mar 28 12:37:46 2022 @@ -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 @@ vfs_mountedon(vnode_t *vp) 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); Index: src/sys/kern/vfs_subr.c diff -u src/sys/kern/vfs_subr.c:1.491 src/sys/kern/vfs_subr.c:1.492 --- src/sys/kern/vfs_subr.c:1.491 Sat Oct 16 07:12:01 2021 +++ src/sys/kern/vfs_subr.c Mon Mar 28 12:37:46 2022 @@ -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 @@ int 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 @@ vdevgone(int maj, int minl, int minh, en 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); } Index: src/sys/kern/vfs_vnode.c diff -u src/sys/kern/vfs_vnode.c:1.139 src/sys/kern/vfs_vnode.c:1.140 --- src/sys/kern/vfs_vnode.c:1.139 Sat Mar 19 13:53:32 2022 +++ src/sys/kern/vfs_vnode.c Mon Mar 28 12:37:46 2022 @@ -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 @@ vrevoke(vnode_t *vp) 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); } Index: src/sys/miscfs/specfs/spec_vnops.c diff -u src/sys/miscfs/specfs/spec_vnops.c:1.207 src/sys/miscfs/specfs/spec_vnops.c:1.208 --- src/sys/miscfs/specfs/spec_vnops.c:1.207 Mon Mar 28 12:37:35 2022 +++ src/sys/miscfs/specfs/spec_vnops.c Mon Mar 28 12:37:46 2022 @@ -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 @@ spec_node_init(vnode_t *vp, dev_t rdev) * 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); } } Index: src/sys/miscfs/specfs/specdev.h diff -u src/sys/miscfs/specfs/specdev.h:1.50 src/sys/miscfs/specfs/specdev.h:1.51 --- src/sys/miscfs/specfs/specdev.h:1.50 Mon Mar 28 12:37:09 2022 +++ src/sys/miscfs/specfs/specdev.h Mon Mar 28 12:37:46 2022 @@ -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 @@ typedef struct specdev { */ 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 *);