Module Name: src Committed By: hannken Date: Wed May 17 12:46:14 UTC 2017
Modified Files: src/sys/kern: vfs_vnode.c Log Message: Suspend file system while revoking a vnode. This way no operations run on the mounted file system during revoke and all operations see the state before or after the revoke. To generate a diff of this commit: cvs rdiff -u -r1.87 -r1.88 src/sys/kern/vfs_vnode.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/vfs_vnode.c diff -u src/sys/kern/vfs_vnode.c:1.87 src/sys/kern/vfs_vnode.c:1.88 --- src/sys/kern/vfs_vnode.c:1.87 Mon Apr 17 08:32:01 2017 +++ src/sys/kern/vfs_vnode.c Wed May 17 12:46:14 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_vnode.c,v 1.87 2017/04/17 08:32:01 hannken Exp $ */ +/* $NetBSD: vfs_vnode.c,v 1.88 2017/05/17 12:46:14 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.87 2017/04/17 08:32:01 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.88 2017/05/17 12:46:14 hannken Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -950,31 +950,48 @@ vrecycle(vnode_t *vp) void vrevoke(vnode_t *vp) { + int error; + struct mount *mp; vnode_t *vq; enum vtype type; dev_t dev; KASSERT(vp->v_usecount > 0); + mp = vp->v_mount; + error = vfs_suspend(mp, 0); + KASSERT(error == 0 || error == EOPNOTSUPP); + if (error) + mp = NULL; + mutex_enter(vp->v_interlock); VSTATE_WAIT_STABLE(vp); if (VSTATE_GET(vp) == VS_RECLAIMED) { mutex_exit(vp->v_interlock); - return; } else if (vp->v_type != VBLK && vp->v_type != VCHR) { atomic_inc_uint(&vp->v_usecount); mutex_exit(vp->v_interlock); vgone(vp); - return; } else { dev = vp->v_rdev; type = vp->v_type; mutex_exit(vp->v_interlock); - } - while (spec_node_lookup_by_dev(type, dev, &vq) == 0) { - vgone(vq); + while (spec_node_lookup_by_dev(type, dev, &vq) == 0) { + if (mp != vq->v_mount) { + if (mp) + vfs_resume(mp); + mp = vp->v_mount; + error = vfs_suspend(mp, 0); + KASSERT(error == 0 || error == EOPNOTSUPP); + if (error) + mp = NULL; + } + vgone(vq); + } } + if (mp) + vfs_resume(mp); } /*