Module Name: src
Committed By: hannken
Date: Wed Aug 19 08:40:02 UTC 2015
Modified Files:
src/sys/kern: vfs_mount.c
Log Message:
Redo Rev. 1.30: Change vfs_vnode_iterator_next() to skip reclaiming
vnodes (VI_XLOCK set) without waiting and change vflush() to wait for
these vnodes.
To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/sys/kern/vfs_mount.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_mount.c
diff -u src/sys/kern/vfs_mount.c:1.36 src/sys/kern/vfs_mount.c:1.37
--- src/sys/kern/vfs_mount.c:1.36 Sun Aug 2 03:29:22 2015
+++ src/sys/kern/vfs_mount.c Wed Aug 19 08:40:02 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_mount.c,v 1.36 2015/08/02 03:29:22 manu Exp $ */
+/* $NetBSD: vfs_mount.c,v 1.37 2015/08/19 08:40:02 hannken Exp $ */
/*-
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.36 2015/08/02 03:29:22 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.37 2015/08/19 08:40:02 hannken Exp $");
#define _VFS_VNODE_PRIVATE
@@ -394,7 +394,8 @@ again:
}
mutex_enter(vp->v_interlock);
if (ISSET(vp->v_iflag, VI_MARKER) ||
- (f && !ISSET(vp->v_iflag, VI_XLOCK) && !(*f)(cl, vp))) {
+ ISSET(vp->v_iflag, VI_XLOCK) ||
+ (f && !(*f)(cl, vp))) {
mutex_exit(vp->v_interlock);
vp = TAILQ_NEXT(vp, v_mntvnodes);
goto again;
@@ -507,7 +508,7 @@ vflush(struct mount *mp, vnode_t *skipvp
{
vnode_t *vp;
struct vnode_iterator *marker;
- int busy = 0, when = 0;
+ int error, busy = 0, when = 0;
struct vflush_ctx ctx;
/* First, flush out any vnode references from vrele_list. */
@@ -540,7 +541,31 @@ vflush(struct mount *mp, vnode_t *skipvp
vfs_vnode_iterator_destroy(marker);
if (busy)
return (EBUSY);
- return (0);
+
+ /* Wait for all vnodes to be reclaimed. */
+ for (;;) {
+ mutex_enter(&mntvnode_lock);
+ TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
+ if (vp == skipvp)
+ continue;
+ if ((flags & SKIPSYSTEM) && (vp->v_vflag & VV_SYSTEM))
+ continue;
+ break;
+ }
+ if (vp != NULL) {
+ mutex_enter(vp->v_interlock);
+ mutex_exit(&mntvnode_lock);
+ error = vget(vp, 0, true /* wait */);
+ if (error == ENOENT)
+ continue;
+ else if (error == 0)
+ vrele(vp);
+ return EBUSY;
+ } else {
+ mutex_exit(&mntvnode_lock);
+ return 0;
+ }
+ }
}
/*