Index: vfs_mount.c =================================================================== RCS file: /cvsroot/src/sys/kern/vfs_mount.c,v retrieving revision 1.28 diff -u -p -u -r1.28 vfs_mount.c --- vfs_mount.c 18 Mar 2014 10:21:47 -0000 1.28 +++ vfs_mount.c 22 May 2014 00:29:10 -0000 @@ -371,8 +371,9 @@ vfs_vnode_iterator_destroy(struct vnode_ vnfree(mvp); } -bool -vfs_vnode_iterator_next(struct vnode_iterator *vi, struct vnode **vpp) +static struct vnode * +vfs_vnode_iterator_next1(struct vnode_iterator *vi, + const struct vnode *skipvp, int flags) { struct vnode *mvp = &vi->vi_vnode; struct mount *mp = mvp->v_mount; @@ -386,10 +387,34 @@ vfs_vnode_iterator_next(struct vnode_ite vp = TAILQ_NEXT(mvp, v_mntvnodes); TAILQ_REMOVE(&mp->mnt_vnodelist, mvp, v_mntvnodes); mvp->v_usecount = 0; +again: if (vp == NULL) { mutex_exit(&mntvnode_lock); - *vpp = NULL; - return false; + return NULL; + } + /* + * Skip over a selected vnode. + */ + if (vp == skipvp) + goto getnext; + /* + * Skip over a vnodes marked VSYSTEM. + */ + if ((flags & SKIPSYSTEM) && (vp->v_vflag & VV_SYSTEM)) + goto getnext; + + /* + * If WRITECLOSE is set, only flush out regular file + * vnodes open for writing. + */ + if ((flags & WRITECLOSE) && vp->v_type == VREG) { + mutex_enter(vp->v_interlock); + if (vp->v_writecount == 0) { + mutex_exit(vp->v_interlock); +getnext: vp = TAILQ_NEXT(mvp, v_mntvnodes); + goto again; + } + mutex_exit(vp->v_interlock); } mutex_enter(vp->v_interlock); @@ -398,8 +423,7 @@ vfs_vnode_iterator_next(struct vnode_ite vp = TAILQ_NEXT(vp, v_mntvnodes); if (vp == NULL) { mutex_exit(&mntvnode_lock); - *vpp = NULL; - return false; + return NULL; } mutex_enter(vp->v_interlock); } @@ -411,6 +435,15 @@ vfs_vnode_iterator_next(struct vnode_ite KASSERT(error == 0 || error == ENOENT); } while (error != 0); + return vp; +} + +bool +vfs_vnode_iterator_next(struct vnode_iterator *vi, struct vnode **vpp) +{ + struct vnode *vp = vfs_vnode_iterator_next1(vi, NULL, 0); + if (vp == NULL) + return false; *vpp = vp; return true; } @@ -466,17 +499,14 @@ struct ctldebug debug1 = { "busyprt", &b #endif static vnode_t * -vflushnext(struct vnode_iterator *marker, int *when) +vflushnext(struct vnode_iterator *marker, const struct vnode *skipvp, int flags, + int *when) { - struct vnode *vp; - if (hardclock_ticks > *when) { yield(); *when = hardclock_ticks + hz / 10; } - if (vfs_vnode_iterator_next(marker, &vp)) - return vp; - return NULL; + return vfs_vnode_iterator_next1(marker, skipvp, flags); } int @@ -490,34 +520,7 @@ vflush(struct mount *mp, vnode_t *skipvp vrele_flush(); vfs_vnode_iterator_init(mp, &marker); - while ((vp = vflushnext(marker, &when)) != NULL) { - /* - * Skip over a selected vnode. - */ - if (vp == skipvp) { - vrele(vp); - continue; - } - /* - * Skip over a vnodes marked VSYSTEM. - */ - if ((flags & SKIPSYSTEM) && (vp->v_vflag & VV_SYSTEM)) { - vrele(vp); - continue; - } - /* - * If WRITECLOSE is set, only flush out regular file - * vnodes open for writing. - */ - if ((flags & WRITECLOSE) && vp->v_type == VREG) { - mutex_enter(vp->v_interlock); - if (vp->v_writecount == 0) { - mutex_exit(vp->v_interlock); - vrele(vp); - continue; - } - mutex_exit(vp->v_interlock); - } + while ((vp = vflushnext(marker, skipvp, flags, &when)) != NULL) { /* * First try to recycle the vnode. */