Module Name: src Committed By: hannken Date: Mon Mar 24 13:42:41 UTC 2014
Modified Files: src/distrib/sets/lists/comp: mi src/share/man/man9: Makefile vnode.9 src/sys/fs/puffs: puffs_vnops.c src/sys/fs/union: union_vnops.c src/sys/kern: vfs_vnode.c src/sys/miscfs/genfs: genfs_vnops.c layer_vnops.c src/sys/miscfs/specfs: spec_vnops.c src/sys/sys: param.h vnode.h src/sys/ufs/ext2fs: ext2fs_vnops.c src/sys/ufs/ffs: ffs_vnops.c src/sys/ufs/lfs: lfs_segment.c lfs_syscalls.c lfs_vfsops.c lfs_vnops.c src/usr.sbin/pstat: pstat.8 pstat.c Log Message: - Make VI_XLOCK, VI_CLEAN and VI_LOCKSHARE private to kern/vfs_*.c. - Make vwait() static. - Add vdead_check() to check a vnode for being or becoming dead. Discussed on tech-kern. Welcome to 6.99.38 To generate a diff of this commit: cvs rdiff -u -r1.1885 -r1.1886 src/distrib/sets/lists/comp/mi cvs rdiff -u -r1.376 -r1.377 src/share/man/man9/Makefile cvs rdiff -u -r1.60 -r1.61 src/share/man/man9/vnode.9 cvs rdiff -u -r1.180 -r1.181 src/sys/fs/puffs/puffs_vnops.c cvs rdiff -u -r1.58 -r1.59 src/sys/fs/union/union_vnops.c cvs rdiff -u -r1.34 -r1.35 src/sys/kern/vfs_vnode.c cvs rdiff -u -r1.191 -r1.192 src/sys/miscfs/genfs/genfs_vnops.c cvs rdiff -u -r1.56 -r1.57 src/sys/miscfs/genfs/layer_vnops.c cvs rdiff -u -r1.142 -r1.143 src/sys/miscfs/specfs/spec_vnops.c cvs rdiff -u -r1.446 -r1.447 src/sys/sys/param.h cvs rdiff -u -r1.245 -r1.246 src/sys/sys/vnode.h cvs rdiff -u -r1.110 -r1.111 src/sys/ufs/ext2fs/ext2fs_vnops.c cvs rdiff -u -r1.123 -r1.124 src/sys/ufs/ffs/ffs_vnops.c cvs rdiff -u -r1.235 -r1.236 src/sys/ufs/lfs/lfs_segment.c cvs rdiff -u -r1.151 -r1.152 src/sys/ufs/lfs/lfs_syscalls.c cvs rdiff -u -r1.319 -r1.320 src/sys/ufs/lfs/lfs_vfsops.c cvs rdiff -u -r1.261 -r1.262 src/sys/ufs/lfs/lfs_vnops.c cvs rdiff -u -r1.39 -r1.40 src/usr.sbin/pstat/pstat.8 cvs rdiff -u -r1.122 -r1.123 src/usr.sbin/pstat/pstat.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/comp/mi diff -u src/distrib/sets/lists/comp/mi:1.1885 src/distrib/sets/lists/comp/mi:1.1886 --- src/distrib/sets/lists/comp/mi:1.1885 Sat Mar 22 11:24:35 2014 +++ src/distrib/sets/lists/comp/mi Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.1885 2014/03/22 11:24:35 skrll Exp $ +# $NetBSD: mi,v 1.1886 2014/03/24 13:42:40 hannken Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -10977,6 +10977,7 @@ ./usr/share/man/cat9/vdevgone.0 comp-sys-catman .cat ./usr/share/man/cat9/veriexec.0 comp-sys-catman .cat ./usr/share/man/cat9/vfinddev.0 comp-sys-catman .cat +./usr/share/man/cat9/vdead_check.0 comp-sys-catman .cat ./usr/share/man/cat9/vflush.0 comp-sys-catman .cat ./usr/share/man/cat9/vflushbuf.0 comp-sys-catman .cat ./usr/share/man/cat9/vfs.0 comp-sys-catman .cat @@ -17630,6 +17631,7 @@ ./usr/share/man/html9/vdevgone.html comp-sys-htmlman html ./usr/share/man/html9/veriexec.html comp-sys-htmlman html ./usr/share/man/html9/vfinddev.html comp-sys-htmlman html +./usr/share/man/html9/vdead_check.html comp-sys-htmlman html ./usr/share/man/html9/vflush.html comp-sys-htmlman html ./usr/share/man/html9/vflushbuf.html comp-sys-htmlman html ./usr/share/man/html9/vfs.html comp-sys-htmlman html @@ -24522,6 +24524,7 @@ ./usr/share/man/man9/vdevgone.9 comp-sys-man .man ./usr/share/man/man9/veriexec.9 comp-sys-man .man ./usr/share/man/man9/vfinddev.9 comp-sys-man .man +./usr/share/man/man9/vdead_check.9 comp-sys-man .man ./usr/share/man/man9/vflush.9 comp-sys-man .man ./usr/share/man/man9/vflushbuf.9 comp-sys-man .man ./usr/share/man/man9/vfs.9 comp-sys-man .man Index: src/share/man/man9/Makefile diff -u src/share/man/man9/Makefile:1.376 src/share/man/man9/Makefile:1.377 --- src/share/man/man9/Makefile:1.376 Sat Mar 22 11:24:36 2014 +++ src/share/man/man9/Makefile Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.376 2014/03/22 11:24:36 skrll Exp $ +# $NetBSD: Makefile,v 1.377 2014/03/24 13:42:40 hannken Exp $ # Makefile for section 9 (kernel function and variable) manual pages. @@ -898,6 +898,7 @@ MLINKS+=vnode.9 vref.9 \ vnode.9 vrecycle.9 \ vnode.9 vgone.9 \ vnode.9 vgonel.9 \ + vnode.9 vdead_check.9 \ vnode.9 vflush.9 \ vnode.9 vaccess.9 \ vnode.9 bdevvp.9 \ Index: src/share/man/man9/vnode.9 diff -u src/share/man/man9/vnode.9:1.60 src/share/man/man9/vnode.9:1.61 --- src/share/man/man9/vnode.9:1.60 Wed Mar 5 09:37:29 2014 +++ src/share/man/man9/vnode.9 Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -.\" $NetBSD: vnode.9,v 1.60 2014/03/05 09:37:29 hannken Exp $ +.\" $NetBSD: vnode.9,v 1.61 2014/03/24 13:42:40 hannken Exp $ .\" .\" Copyright (c) 2001, 2005, 2006 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd March 5, 2014 +.Dd March 24, 2014 .Dt VNODE 9 .Os .Sh NAME @@ -44,6 +44,7 @@ .Nm vrecycle , .Nm vgone , .Nm vgonel , +.Nm vdead_check , .Nm vflush , .Nm vaccess , .Nm bdevvp , @@ -85,6 +86,8 @@ .Ft void .Fn vgonel "struct vnode *vp" "struct lwp *l" .Ft int +.Fn vdead_check "struct vnode *vp" "int flags" +.Ft int .Fn vflush "struct mount *mp" "struct vnode *skipvp" "int flags" .Ft int .Fn vaccess "enum vtype type" "mode_t file_mode" "uid_t uid" "gid_t gid" "mode_t acc_mode" "kauth_cred_t cred" @@ -630,6 +633,25 @@ in preparation for recycling. Eliminate all activity associated with the locked vnode .Fa vp in preparation for recycling. +.It Fn vdead_check "vp" "flags" +Check the vnode +.Fa vp +for being or becoming dead. +Returns +.Er ENOENT +for a dead vnode and zero otherwise. +If +.Fa flags +is +.Dv VDEAD_NOWAIT +it will return +.Er EBUSY +if the vnode is becoming dead and the function will not sleep. +.Pp +Whenever this function returns a non-zero value all future calls +for this +.Fa vp +will also return a non-zero value. .It Fn vflush "mp" "skipvp" "flags" Remove any vnodes in the vnode table belonging to mount point .Fa mp . Index: src/sys/fs/puffs/puffs_vnops.c diff -u src/sys/fs/puffs/puffs_vnops.c:1.180 src/sys/fs/puffs/puffs_vnops.c:1.181 --- src/sys/fs/puffs/puffs_vnops.c:1.180 Fri Feb 7 15:29:21 2014 +++ src/sys/fs/puffs/puffs_vnops.c Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_vnops.c,v 1.180 2014/02/07 15:29:21 hannken Exp $ */ +/* $NetBSD: puffs_vnops.c,v 1.181 2014/03/24 13:42:40 hannken Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.180 2014/02/07 15:29:21 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.181 2014/03/24 13:42:40 hannken Exp $"); #include <sys/param.h> #include <sys/buf.h> @@ -1692,7 +1692,7 @@ puffs_vnop_fsync(void *v) */ if (dofaf == 0) { mutex_enter(vp->v_interlock); - if (vp->v_iflag & VI_XLOCK) + if (vdead_check(vp, VDEAD_NOWAIT) != 0) dofaf = 1; mutex_exit(vp->v_interlock); } @@ -2601,7 +2601,7 @@ puffs_vnop_strategy(void *v) */ if (BUF_ISWRITE(bp)) { mutex_enter(vp->v_interlock); - if (vp->v_iflag & VI_XLOCK) + if (vdead_check(vp, VDEAD_NOWAIT) != 0) dofaf = 1; if (pn->pn_stat & PNODE_FAF) dofaf = 1; Index: src/sys/fs/union/union_vnops.c diff -u src/sys/fs/union/union_vnops.c:1.58 src/sys/fs/union/union_vnops.c:1.59 --- src/sys/fs/union/union_vnops.c:1.58 Wed Mar 12 09:40:05 2014 +++ src/sys/fs/union/union_vnops.c Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: union_vnops.c,v 1.58 2014/03/12 09:40:05 hannken Exp $ */ +/* $NetBSD: union_vnops.c,v 1.59 2014/03/24 13:42:40 hannken Exp $ */ /* * Copyright (c) 1992, 1993, 1994, 1995 @@ -72,7 +72,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.58 2014/03/12 09:40:05 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.59 2014/03/24 13:42:40 hannken Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1636,12 +1636,7 @@ union_lock(void *v) if (error) return error; if (mutex_tryenter(vp->v_interlock)) { - if (ISSET(vp->v_iflag, VI_XLOCK)) - error = EBUSY; - else if (ISSET(vp->v_iflag, VI_CLEAN)) - error = ENOENT; - else - error = 0; + error = vdead_check(vp, VDEAD_NOWAIT); mutex_exit(vp->v_interlock); } else error = EBUSY; @@ -1665,15 +1660,14 @@ union_lock(void *v) mutex_exit(&un->un_lock); mutex_enter(vp->v_interlock); - if (ISSET(vp->v_iflag, VI_XLOCK) || ISSET(vp->v_iflag, VI_CLEAN)) { + error = vdead_check(vp, VDEAD_NOWAIT); + if (error) { union_unlock1(vp, lockvp); - vwait(vp, VI_XLOCK); - KASSERT(ISSET(vp->v_iflag, VI_CLEAN)); - mutex_exit(vp->v_interlock); - return ENOENT; + error = vdead_check(vp, 0); + KASSERT(error == ENOENT); } mutex_exit(vp->v_interlock); - return 0; + return error; } int Index: src/sys/kern/vfs_vnode.c diff -u src/sys/kern/vfs_vnode.c:1.34 src/sys/kern/vfs_vnode.c:1.35 --- src/sys/kern/vfs_vnode.c:1.34 Mon Mar 17 09:27:37 2014 +++ src/sys/kern/vfs_vnode.c Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_vnode.c,v 1.34 2014/03/17 09:27:37 hannken Exp $ */ +/* $NetBSD: vfs_vnode.c,v 1.35 2014/03/24 13:42:40 hannken Exp $ */ /*- * Copyright (c) 1997-2011 The NetBSD Foundation, Inc. @@ -116,7 +116,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.34 2014/03/17 09:27:37 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.35 2014/03/24 13:42:40 hannken Exp $"); #define _VFS_VNODE_PRIVATE @@ -176,6 +176,7 @@ static void vdrain_thread(void *); static void vrele_thread(void *); static void vnpanic(vnode_t *, const char *, ...) __printflike(2, 3); +static void vwait(vnode_t *, int); /* Routines having to do with the management of the vnode table. */ extern int (**dead_vnodeop_p)(void *); @@ -1140,10 +1141,35 @@ vwakeup(struct buf *bp) } /* + * Test a vnode for being or becoming dead. Returns one of: + * EBUSY: vnode is becoming dead, with "flags == VDEAD_NOWAIT" only. + * ENOENT: vnode is dead. + * 0: otherwise. + * + * Whenever this function returns a non-zero value all future + * calls will also return a non-zero value. + */ +int +vdead_check(struct vnode *vp, int flags) +{ + + KASSERT(mutex_owned(vp->v_interlock)); + if (ISSET(vp->v_iflag, VI_XLOCK)) { + if (ISSET(flags, VDEAD_NOWAIT)) + return EBUSY; + vwait(vp, VI_XLOCK); + KASSERT(ISSET(vp->v_iflag, VI_CLEAN)); + } + if (ISSET(vp->v_iflag, VI_CLEAN)) + return ENOENT; + return 0; +} + +/* * Wait for a vnode (typically with VI_XLOCK set) to be cleaned or * recycled. */ -void +static void vwait(vnode_t *vp, int flags) { Index: src/sys/miscfs/genfs/genfs_vnops.c diff -u src/sys/miscfs/genfs/genfs_vnops.c:1.191 src/sys/miscfs/genfs/genfs_vnops.c:1.192 --- src/sys/miscfs/genfs/genfs_vnops.c:1.191 Wed Mar 12 09:38:51 2014 +++ src/sys/miscfs/genfs/genfs_vnops.c Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: genfs_vnops.c,v 1.191 2014/03/12 09:38:51 hannken Exp $ */ +/* $NetBSD: genfs_vnops.c,v 1.192 2014/03/24 13:42:40 hannken Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -57,7 +57,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.191 2014/03/12 09:38:51 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.192 2014/03/24 13:42:40 hannken Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -297,12 +297,9 @@ genfs_deadlock(void *v) if (! rw_tryenter(&vp->v_lock, op)) return EBUSY; if (mutex_tryenter(vp->v_interlock)) { - if (ISSET(vp->v_iflag, VI_XLOCK)) - error = EBUSY; - else { - KASSERT(ISSET(vp->v_iflag, VI_CLEAN)); - error = (ISSET(flags, LK_RETRY) ? 0 : ENOENT); - } + error = vdead_check(vp, VDEAD_NOWAIT); + if (error == ENOENT && ISSET(flags, LK_RETRY)) + error = 0; mutex_exit(vp->v_interlock); } else error = EBUSY; @@ -313,14 +310,16 @@ genfs_deadlock(void *v) rw_enter(&vp->v_lock, op); mutex_enter(vp->v_interlock); - if (ISSET(vp->v_iflag, VI_XLOCK)) { + error = vdead_check(vp, VDEAD_NOWAIT); + if (error == EBUSY) { rw_exit(&vp->v_lock); - vwait(vp, VI_XLOCK); + error = vdead_check(vp, 0); + KASSERT(error == ENOENT); mutex_exit(vp->v_interlock); rw_enter(&vp->v_lock, op); mutex_enter(vp->v_interlock); } - KASSERT(ISSET(vp->v_iflag, VI_CLEAN)); + KASSERT(error == ENOENT); mutex_exit(vp->v_interlock); if (! ISSET(flags, LK_RETRY)) { rw_exit(&vp->v_lock); @@ -370,12 +369,7 @@ genfs_lock(void *v) return EBUSY; } if (mutex_tryenter(vp->v_interlock)) { - if (ISSET(vp->v_iflag, VI_XLOCK)) - error = EBUSY; - else if (ISSET(vp->v_iflag, VI_CLEAN)) - error = ENOENT; - else - error = 0; + error = vdead_check(vp, VDEAD_NOWAIT); mutex_exit(vp->v_interlock); } else error = EBUSY; @@ -389,16 +383,15 @@ genfs_lock(void *v) fstrans_start(mp, FSTRANS_SHARED); rw_enter(&vp->v_lock, op); mutex_enter(vp->v_interlock); - if (ISSET(vp->v_iflag, VI_XLOCK) || ISSET(vp->v_iflag, VI_CLEAN)) { + error = vdead_check(vp, VDEAD_NOWAIT); + if (error) { rw_exit(&vp->v_lock); fstrans_done(mp); - vwait(vp, VI_XLOCK); - KASSERT(ISSET(vp->v_iflag, VI_CLEAN)); - mutex_exit(vp->v_interlock); - return ENOENT; + error = vdead_check(vp, 0); + KASSERT(error == ENOENT); } mutex_exit(vp->v_interlock); - return 0; + return error; } /* Index: src/sys/miscfs/genfs/layer_vnops.c diff -u src/sys/miscfs/genfs/layer_vnops.c:1.56 src/sys/miscfs/genfs/layer_vnops.c:1.57 --- src/sys/miscfs/genfs/layer_vnops.c:1.56 Wed Mar 12 09:39:23 2014 +++ src/sys/miscfs/genfs/layer_vnops.c Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: layer_vnops.c,v 1.56 2014/03/12 09:39:23 hannken Exp $ */ +/* $NetBSD: layer_vnops.c,v 1.57 2014/03/24 13:42:40 hannken Exp $ */ /* * Copyright (c) 1999 National Aeronautics & Space Administration @@ -170,7 +170,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: layer_vnops.c,v 1.56 2014/03/12 09:39:23 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: layer_vnops.c,v 1.57 2014/03/24 13:42:40 hannken Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -723,12 +723,7 @@ layer_lock(void *v) if (error) return error; if (mutex_tryenter(vp->v_interlock)) { - if (ISSET(vp->v_iflag, VI_XLOCK)) - error = EBUSY; - else if (ISSET(vp->v_iflag, VI_CLEAN)) - error = ENOENT; - else - error = 0; + error = vdead_check(vp, VDEAD_NOWAIT); mutex_exit(vp->v_interlock); } else error = EBUSY; @@ -742,16 +737,15 @@ layer_lock(void *v) return error; mutex_enter(vp->v_interlock); - if (ISSET(vp->v_iflag, VI_XLOCK) || ISSET(vp->v_iflag, VI_CLEAN)) { + error = vdead_check(vp, VDEAD_NOWAIT); + if (error) { VOP_UNLOCK(lowervp); - vwait(vp, VI_XLOCK); - KASSERT(ISSET(vp->v_iflag, VI_CLEAN)); - mutex_exit(vp->v_interlock); - return ENOENT; + error = vdead_check(vp, 0); + KASSERT(error == ENOENT); } mutex_exit(vp->v_interlock); - return 0; + return error; } /* Index: src/sys/miscfs/specfs/spec_vnops.c diff -u src/sys/miscfs/specfs/spec_vnops.c:1.142 src/sys/miscfs/specfs/spec_vnops.c:1.143 --- src/sys/miscfs/specfs/spec_vnops.c:1.142 Fri Feb 7 15:29:22 2014 +++ src/sys/miscfs/specfs/spec_vnops.c Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: spec_vnops.c,v 1.142 2014/02/07 15:29:22 hannken Exp $ */ +/* $NetBSD: spec_vnops.c,v 1.143 2014/03/24 13:42:40 hannken 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.142 2014/02/07 15:29:22 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.143 2014/03/24 13:42:40 hannken Exp $"); #include <sys/param.h> #include <sys/proc.h> @@ -288,7 +288,7 @@ spec_node_lookup_by_dev(enum vtype type, if (type == vp->v_type && dev == vp->v_rdev) { mutex_enter(vp->v_interlock); /* If clean or being cleaned, then ignore it. */ - if ((vp->v_iflag & (VI_CLEAN | VI_XLOCK)) == 0) + if (vdead_check(vp, VDEAD_NOWAIT) == 0) break; mutex_exit(vp->v_interlock); } @@ -392,7 +392,6 @@ spec_node_revoke(vnode_t *vp) KASSERT(vp->v_type == VBLK || vp->v_type == VCHR); KASSERT(vp->v_specnode != NULL); - KASSERT((vp->v_iflag & VI_XLOCK) != 0); KASSERT(sn->sn_gone == false); mutex_enter(&device_lock); @@ -863,7 +862,7 @@ spec_ioctl(void *v) vp = ap->a_vp; dev = NODEV; mutex_enter(vp->v_interlock); - if ((vp->v_iflag & VI_XLOCK) == 0 && vp->v_specnode) { + if (vdead_check(vp, VDEAD_NOWAIT) == 0 && vp->v_specnode) { dev = vp->v_rdev; } mutex_exit(vp->v_interlock); @@ -907,7 +906,7 @@ spec_poll(void *v) vp = ap->a_vp; dev = NODEV; mutex_enter(vp->v_interlock); - if ((vp->v_iflag & VI_XLOCK) == 0 && vp->v_specnode) { + if (vdead_check(vp, VDEAD_NOWAIT) == 0 && vp->v_specnode) { dev = vp->v_rdev; } mutex_exit(vp->v_interlock); @@ -1082,13 +1081,21 @@ spec_close(void *v) struct vnode *vp = ap->a_vp; struct session *sess; dev_t dev = vp->v_rdev; - int mode, error, flags, flags1, count; + int flags = ap->a_fflag; + int mode, error, count; specnode_t *sn; specdev_t *sd; - flags = vp->v_iflag; + mutex_enter(vp->v_interlock); sn = vp->v_specnode; sd = sn->sn_dev; + /* + * If we're going away soon, make this non-blocking. + * Also ensures that we won't wedge in vn_lock below. + */ + if (vdead_check(vp, VDEAD_NOWAIT) != 0) + flags |= FNONBLOCK; + mutex_exit(vp->v_interlock); switch (vp->v_type) { @@ -1170,30 +1177,20 @@ spec_close(void *v) if (count != 0) return 0; - flags1 = ap->a_fflag; - - /* - * if VI_XLOCK is set, then we're going away soon, so make this - * non-blocking. Also ensures that we won't wedge in vn_lock below. - */ - if (flags & VI_XLOCK) - flags1 |= FNONBLOCK; - /* * If we're able to block, release the vnode lock & reacquire. We * might end up sleeping for someone else who wants our queues. They - * won't get them if we hold the vnode locked. Also, if VI_XLOCK is - * set, don't release the lock as we won't be able to regain it. + * won't get them if we hold the vnode locked. */ - if (!(flags1 & FNONBLOCK)) + if (!(flags & FNONBLOCK)) VOP_UNLOCK(vp); if (vp->v_type == VBLK) - error = bdev_close(dev, flags1, mode, curlwp); + error = bdev_close(dev, flags, mode, curlwp); else - error = cdev_close(dev, flags1, mode, curlwp); + error = cdev_close(dev, flags, mode, curlwp); - if (!(flags1 & FNONBLOCK)) + if (!(flags & FNONBLOCK)) vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); return (error); Index: src/sys/sys/param.h diff -u src/sys/sys/param.h:1.446 src/sys/sys/param.h:1.447 --- src/sys/sys/param.h:1.446 Tue Mar 18 10:21:47 2014 +++ src/sys/sys/param.h Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: param.h,v 1.446 2014/03/18 10:21:47 hannken Exp $ */ +/* $NetBSD: param.h,v 1.447 2014/03/24 13:42:40 hannken Exp $ */ /*- * Copyright (c) 1982, 1986, 1989, 1993 @@ -63,7 +63,7 @@ * 2.99.9 (299000900) */ -#define __NetBSD_Version__ 699003700 /* NetBSD 6.99.37 */ +#define __NetBSD_Version__ 699003800 /* NetBSD 6.99.38 */ #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \ (m) * 1000000) + (p) * 100) <= __NetBSD_Version__) Index: src/sys/sys/vnode.h diff -u src/sys/sys/vnode.h:1.245 src/sys/sys/vnode.h:1.246 --- src/sys/sys/vnode.h:1.245 Tue Mar 18 10:21:47 2014 +++ src/sys/sys/vnode.h Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: vnode.h,v 1.245 2014/03/18 10:21:47 hannken Exp $ */ +/* $NetBSD: vnode.h,v 1.246 2014/03/24 13:42:40 hannken Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -199,15 +199,17 @@ typedef struct vnode vnode_t; #define VI_EXECMAP 0x00000200 /* might have PROT_EXEC mappings */ #define VI_WRMAP 0x00000400 /* might have PROT_WRITE u. mappings */ #define VI_WRMAPDIRTY 0x00000800 /* might have dirty pages */ +#ifdef _VFS_VNODE_PRIVATE #define VI_XLOCK 0x00001000 /* vnode is locked to change type */ +#endif /* _VFS_VNODE_PRIVATE */ #define VI_ONWORKLST 0x00004000 /* On syncer work-list */ #ifdef _VFS_VNODE_PRIVATE #define VI_MARKER 0x00008000 /* Dummy marker vnode */ #endif /* _VFS_VNODE_PRIVATE */ #define VI_LAYER 0x00020000 /* vnode is on a layer filesystem */ +#ifdef _VFS_VNODE_PRIVATE #define VI_LOCKSHARE 0x00040000 /* v_interlock is shared */ #define VI_CLEAN 0x00080000 /* has been reclaimed */ -#ifdef _VFS_VNODE_PRIVATE #define VI_CHANGING 0x00100000 /* vnode changes state */ #endif /* _VFS_VNODE_PRIVATE */ @@ -332,6 +334,8 @@ extern const int vttoif_tab[]; #define UPDATE_DIROP 0x0002 /* update: hint to fs to wait or not */ #define UPDATE_CLOSE 0x0004 /* update: clean up on close */ +#define VDEAD_NOWAIT 0x0001 /* vdead_check: do not sleep */ + void holdrelel(struct vnode *); void vholdl(struct vnode *); void vref(struct vnode *); @@ -546,7 +550,7 @@ void vrele_async(struct vnode *); void vrele_flush(void); int vtruncbuf(struct vnode *, daddr_t, bool, int); void vwakeup(struct buf *); -void vwait(struct vnode *, int); +int vdead_check(struct vnode *, int); void vrevoke(struct vnode *); struct vnode * vnalloc(struct mount *); Index: src/sys/ufs/ext2fs/ext2fs_vnops.c diff -u src/sys/ufs/ext2fs/ext2fs_vnops.c:1.110 src/sys/ufs/ext2fs/ext2fs_vnops.c:1.111 --- src/sys/ufs/ext2fs/ext2fs_vnops.c:1.110 Thu Jan 23 10:13:57 2014 +++ src/sys/ufs/ext2fs/ext2fs_vnops.c Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_vnops.c,v 1.110 2014/01/23 10:13:57 hannken Exp $ */ +/* $NetBSD: ext2fs_vnops.c,v 1.111 2014/03/24 13:42:40 hannken Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -65,7 +65,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.110 2014/01/23 10:13:57 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.111 2014/03/24 13:42:40 hannken Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1116,7 +1116,7 @@ ext2fs_reclaim(void *v) /* * The inode must be freed and updated before being removed * from its hash chain. Other threads trying to gain a hold - * on the inode will be stalled because it is locked (VI_XLOCK). + * or lock on the inode will be stalled. */ if (ip->i_omode == 1 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) ext2fs_vfree(vp, ip->i_number, ip->i_e2fs_mode); Index: src/sys/ufs/ffs/ffs_vnops.c diff -u src/sys/ufs/ffs/ffs_vnops.c:1.123 src/sys/ufs/ffs/ffs_vnops.c:1.124 --- src/sys/ufs/ffs/ffs_vnops.c:1.123 Sun Jun 23 07:28:37 2013 +++ src/sys/ufs/ffs/ffs_vnops.c Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_vnops.c,v 1.123 2013/06/23 07:28:37 dholland Exp $ */ +/* $NetBSD: ffs_vnops.c,v 1.124 2014/03/24 13:42:40 hannken Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.123 2013/06/23 07:28:37 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.124 2014/03/24 13:42:40 hannken Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -560,7 +560,7 @@ ffs_reclaim(void *v) /* * The inode must be freed and updated before being removed * from its hash chain. Other threads trying to gain a hold - * on the inode will be stalled because it is locked (VI_XLOCK). + * or lock on the inode will be stalled. */ error = UFS_WAPBL_BEGIN(mp); if (error) { Index: src/sys/ufs/lfs/lfs_segment.c diff -u src/sys/ufs/lfs/lfs_segment.c:1.235 src/sys/ufs/lfs/lfs_segment.c:1.236 --- src/sys/ufs/lfs/lfs_segment.c:1.235 Tue Mar 18 10:21:47 2014 +++ src/sys/ufs/lfs/lfs_segment.c Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_segment.c,v 1.235 2014/03/18 10:21:47 hannken Exp $ */ +/* $NetBSD: lfs_segment.c,v 1.236 2014/03/24 13:42:40 hannken Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.235 2014/03/18 10:21:47 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.236 2014/03/24 13:42:40 hannken Exp $"); #define _VFS_VNODE_PRIVATE /* XXX: check for VI_MARKER, this has to go */ @@ -281,11 +281,12 @@ lfs_vflush(struct vnode *vp) ivndebug(vp,"vflush/writeinprog"); cv_wait(&vp->v_cv, vp->v_interlock); } + error = vdead_check(vp, VDEAD_NOWAIT); mutex_exit(vp->v_interlock); - /* Protect against VI_XLOCK deadlock in vinvalbuf() */ - lfs_seglock(fs, SEGM_SYNC | ((vp->v_iflag & VI_XLOCK) ? SEGM_RECLAIM : 0)); - if (vp->v_iflag & VI_XLOCK) { + /* Protect against deadlock in vinvalbuf() */ + lfs_seglock(fs, SEGM_SYNC | ((error != 0) ? SEGM_RECLAIM : 0)); + if (error != 0) { fs->lfs_reclino = ip->i_number; } @@ -511,7 +512,7 @@ lfs_writevnodes(struct lfs *fs, struct m mutex_enter(vp->v_interlock); if (vp->v_type == VNON || (vp->v_iflag & VI_MARKER) || - (vp->v_iflag & VI_CLEAN) != 0) { + vdead_check(vp, VDEAD_NOWAIT) != 0) { mutex_exit(vp->v_interlock); continue; } @@ -2755,7 +2756,7 @@ lfs_shellsort(struct buf **bp_array, int } /* - * Call vget with LK_NOWAIT. If we are the one who holds VI_XLOCK, + * Call vget with LK_NOWAIT. If we are the one who is dead, * however, we must press on. Just fake success in that case. */ int Index: src/sys/ufs/lfs/lfs_syscalls.c diff -u src/sys/ufs/lfs/lfs_syscalls.c:1.151 src/sys/ufs/lfs/lfs_syscalls.c:1.152 --- src/sys/ufs/lfs/lfs_syscalls.c:1.151 Wed Mar 5 09:37:29 2014 +++ src/sys/ufs/lfs/lfs_syscalls.c Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_syscalls.c,v 1.151 2014/03/05 09:37:29 hannken Exp $ */ +/* $NetBSD: lfs_syscalls.c,v 1.152 2014/03/24 13:42:40 hannken Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2007, 2007, 2008 @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lfs_syscalls.c,v 1.151 2014/03/05 09:37:29 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_syscalls.c,v 1.152 2014/03/24 13:42:40 hannken Exp $"); #ifndef LFS # define LFS /* for prototypes in syscallargs.h */ @@ -743,7 +743,7 @@ lfs_bmapv(struct proc *p, fsid_t *fsidp, */ mutex_enter(&ulfs_ihash_lock); vp = ulfs_ihashlookup(ump->um_dev, blkp->bi_inode); - if (vp != NULL && !(vp->v_iflag & VI_XLOCK)) { + if (vp != NULL && vdead_check(vp, VDEAD_NOWAIT) == 0) { ip = VTOI(vp); mutex_enter(vp->v_interlock); mutex_exit(&ulfs_ihash_lock); @@ -1050,8 +1050,8 @@ lfs_fasthashget(dev_t dev, ino_t ino, st if ((vp = ulfs_ihashlookup(dev, ino)) != NULL) { mutex_enter(vp->v_interlock); mutex_exit(&ulfs_ihash_lock); - if (vp->v_iflag & VI_XLOCK) { - DLOG((DLOG_CLEAN, "lfs_fastvget: ino %d VI_XLOCK\n", + if (vdead_check(vp, VDEAD_NOWAIT) != 0) { + DLOG((DLOG_CLEAN, "lfs_fastvget: ino %d dead\n", ino)); lfs_stats.clean_vnlocked++; mutex_exit(vp->v_interlock); Index: src/sys/ufs/lfs/lfs_vfsops.c diff -u src/sys/ufs/lfs/lfs_vfsops.c:1.319 src/sys/ufs/lfs/lfs_vfsops.c:1.320 --- src/sys/ufs/lfs/lfs_vfsops.c:1.319 Sun Mar 23 15:21:17 2014 +++ src/sys/ufs/lfs/lfs_vfsops.c Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_vfsops.c,v 1.319 2014/03/23 15:21:17 hannken Exp $ */ +/* $NetBSD: lfs_vfsops.c,v 1.320 2014/03/24 13:42:40 hannken Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2007, 2007 @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.319 2014/03/23 15:21:17 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.320 2014/03/24 13:42:40 hannken Exp $"); #if defined(_KERNEL_OPT) #include "opt_lfs.h" @@ -239,7 +239,7 @@ lfs_sysctl_setup(struct sysctllog **clog { "write_exceeded", "Number of times writer invoked flush" }, { "flush_invoked", "Number of times flush was invoked" }, { "vflush_invoked", "Number of time vflush was called" }, - { "clean_inlocked", "Number of vnodes skipped for VI_XLOCK" }, + { "clean_inlocked", "Number of vnodes skipped for being dead" }, { "clean_vnlocked", "Number of vnodes skipped for vget failure" }, { "segs_reclaimed", "Number of segments reclaimed" }, }; @@ -1755,10 +1755,13 @@ lfs_gop_write(struct vnode *vp, struct v * We must write everything, however, if our vnode is being * reclaimed. */ - if (LFS_STARVED_FOR_SEGS(fs) && !(vp->v_iflag & VI_XLOCK)) { + mutex_enter(vp->v_interlock); + if (LFS_STARVED_FOR_SEGS(fs) && vdead_check(vp, VDEAD_NOWAIT) == 0) { + mutex_exit(vp->v_interlock); failreason = "Starved for segs and not flushing vp"; goto tryagain; } + mutex_exit(vp->v_interlock); /* * Sometimes things slip past the filters in lfs_putpages, Index: src/sys/ufs/lfs/lfs_vnops.c diff -u src/sys/ufs/lfs/lfs_vnops.c:1.261 src/sys/ufs/lfs/lfs_vnops.c:1.262 --- src/sys/ufs/lfs/lfs_vnops.c:1.261 Thu Jan 23 10:13:57 2014 +++ src/sys/ufs/lfs/lfs_vnops.c Mon Mar 24 13:42:40 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_vnops.c,v 1.261 2014/01/23 10:13:57 hannken Exp $ */ +/* $NetBSD: lfs_vnops.c,v 1.262 2014/03/24 13:42:40 hannken Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.261 2014/01/23 10:13:57 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.262 2014/03/24 13:42:40 hannken Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -633,7 +633,7 @@ lfs_mknod(void *v) /* * Call fsync to write the vnode so that we don't have to deal with - * flushing it when it's marked VU_DIROP|VI_XLOCK. + * flushing it when it's marked VU_DIROP or reclaiming. * * XXX KS - If we can't flush we also can't call vgone(), so must * return. But, that leaves this vnode in limbo, also not good. @@ -984,7 +984,7 @@ lfs_reclaim(void *v) /* * The inode must be freed and updated before being removed * from its hash chain. Other threads trying to gain a hold - * on the inode will be stalled because it is locked (VI_XLOCK). + * or lock on the inode will be stalled. */ if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) lfs_vfree(vp, ip->i_number, ip->i_omode); @@ -1203,10 +1203,11 @@ lfs_flush_dirops(struct lfs *fs) nip = TAILQ_NEXT(ip, i_lfs_dchain); mutex_exit(&lfs_lock); vp = ITOV(ip); + mutex_enter(vp->v_interlock); KASSERT((ip->i_flag & IN_ADIROP) == 0); KASSERT(vp->v_uflag & VU_DIROP); - KASSERT(!(vp->v_iflag & VI_XLOCK)); + KASSERT(vdead_check(vp, VDEAD_NOWAIT) == 0); /* * All writes to directories come from dirops; all @@ -1216,10 +1217,12 @@ lfs_flush_dirops(struct lfs *fs) * directory blocks inodes and file inodes. So we don't * really need to lock. */ - if (vp->v_iflag & VI_XLOCK) { + if (vdead_check(vp, VDEAD_NOWAIT) != 0) { + mutex_exit(vp->v_interlock); mutex_enter(&lfs_lock); continue; } + mutex_exit(vp->v_interlock); /* XXX see below * waslocked = VOP_ISLOCKED(vp); */ @@ -1324,7 +1327,8 @@ lfs_flush_pchain(struct lfs *fs) goto top; mutex_enter(vp->v_interlock); - if ((vp->v_iflag & VI_XLOCK) || (vp->v_uflag & VU_DIROP) != 0) { + if (vdead_check(vp, VDEAD_NOWAIT) != 0 || + (vp->v_uflag & VU_DIROP) != 0) { mutex_exit(vp->v_interlock); continue; } @@ -2268,7 +2272,7 @@ lfs_putpages(void *v) sp->vp = vp; /* Note segments written by reclaim; only for debugging */ - if ((vp->v_iflag & VI_XLOCK) != 0) { + if (vdead_check(vp, VDEAD_NOWAIT) != 0) { sp->seg_flags |= SEGM_RECLAIM; fs->lfs_reclino = ip->i_number; } Index: src/usr.sbin/pstat/pstat.8 diff -u src/usr.sbin/pstat/pstat.8:1.39 src/usr.sbin/pstat/pstat.8:1.40 --- src/usr.sbin/pstat/pstat.8:1.39 Sat Dec 5 20:11:18 2009 +++ src/usr.sbin/pstat/pstat.8 Mon Mar 24 13:42:41 2014 @@ -1,4 +1,4 @@ -.\" $NetBSD: pstat.8,v 1.39 2009/12/05 20:11:18 pooka Exp $ +.\" $NetBSD: pstat.8,v 1.40 2014/03/24 13:42:41 hannken Exp $ .\" .\" Copyright (c) 1980, 1991, 1993, 1994 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" from: @(#)pstat.8 8.5 (Berkeley) 5/13/94 .\" -.Dd December 5, 2009 +.Dd March 24, 2014 .Dt PSTAT 8 .Os .Sh NAME @@ -270,14 +270,6 @@ VSYSTEM vnode being used by kernel. VISTTY vnode is a tty. .It E VEXECMAP vnode has PROT_EXEC mappings. -.It L -VXLOCK locked to change underlying type. -.It W -VXWANT process is waiting for vnode. -.It B -VBWAIT waiting for output to complete. -.It A -VALIASED vnode has an alias. .It D VDIROP lfs vnode involved in directory op. .It Y Index: src/usr.sbin/pstat/pstat.c diff -u src/usr.sbin/pstat/pstat.c:1.122 src/usr.sbin/pstat/pstat.c:1.123 --- src/usr.sbin/pstat/pstat.c:1.122 Sun Nov 24 13:13:12 2013 +++ src/usr.sbin/pstat/pstat.c Mon Mar 24 13:42:41 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: pstat.c,v 1.122 2013/11/24 13:13:12 mlelstv Exp $ */ +/* $NetBSD: pstat.c,v 1.123 2014/03/24 13:42:41 hannken Exp $ */ /*- * Copyright (c) 1980, 1991, 1993, 1994 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 19 #if 0 static char sccsid[] = "@(#)pstat.c 8.16 (Berkeley) 5/9/95"; #else -__RCSID("$NetBSD: pstat.c,v 1.122 2013/11/24 13:13:12 mlelstv Exp $"); +__RCSID("$NetBSD: pstat.c,v 1.123 2014/03/24 13:42:41 hannken Exp $"); #endif #endif /* not lint */ @@ -384,7 +384,6 @@ const struct flagbit_desc vnode_flags[] { VV_SYSTEM, 'S' }, { VV_ISTTY, 'I' }, { VI_EXECMAP, 'E' }, - { VI_XLOCK, 'L' }, { VU_DIROP, 'D' }, { VI_LAYER, 'Y' }, { VI_ONWORKLST, 'O' },