Module Name: src
Committed By: hannken
Date: Wed Mar 5 09:37:29 UTC 2014
Modified Files:
src/share/man/man9: vnode.9
src/sys/kern: vfs_mount.c vfs_vnode.c
src/sys/sys: mount.h param.h vnode.h
src/sys/ufs/ext2fs: ext2fs_vfsops.c
src/sys/ufs/ffs: ffs_vfsops.c
src/sys/ufs/lfs: lfs_syscalls.c
Log Message:
Current support for iterating over mnt_vnodelist is rudimentary. Every
caller has to care about list and vnode mutexes, reference count being zero,
intermediate vnode states like VI_CLEAN, VI_XLOCK, VI_MARKER and so on.
Add an interface to iterate over a vnode list:
void vfs_vnode_iterator_init(struct mount *mp, struct vnode_iterator **marker)
void vfs_vnode_iterator_destroy(struct vnode_iterator *marker)
bool vfs_vnode_iterator_next(struct vnode_iterator *marker, struct vnode **vpp)
vfs_vnode_iterator_next() returns either "false / *vpp == NULL" when done
or "true / *vpp != NULL" to return the next referenced vnode from the list.
To make vrecycle() work in this environment change it to
bool vrecycle(struct vnode *vp)
where "vp" is a referenced vnode to be destroyed if this is the last reference.
Discussed on tech-kern.
Welcome to 6.99.34
To generate a diff of this commit:
cvs rdiff -u -r1.59 -r1.60 src/share/man/man9/vnode.9
cvs rdiff -u -r1.26 -r1.27 src/sys/kern/vfs_mount.c
cvs rdiff -u -r1.32 -r1.33 src/sys/kern/vfs_vnode.c
cvs rdiff -u -r1.211 -r1.212 src/sys/sys/mount.h
cvs rdiff -u -r1.442 -r1.443 src/sys/sys/param.h
cvs rdiff -u -r1.243 -r1.244 src/sys/sys/vnode.h
cvs rdiff -u -r1.176 -r1.177 src/sys/ufs/ext2fs/ext2fs_vfsops.c
cvs rdiff -u -r1.292 -r1.293 src/sys/ufs/ffs/ffs_vfsops.c
cvs rdiff -u -r1.150 -r1.151 src/sys/ufs/lfs/lfs_syscalls.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/share/man/man9/vnode.9
diff -u src/share/man/man9/vnode.9:1.59 src/share/man/man9/vnode.9:1.60
--- src/share/man/man9/vnode.9:1.59 Sat Feb 22 11:28:18 2014
+++ src/share/man/man9/vnode.9 Wed Mar 5 09:37:29 2014
@@ -1,4 +1,4 @@
-.\" $NetBSD: vnode.9,v 1.59 2014/02/22 11:28:18 wiz Exp $
+.\" $NetBSD: vnode.9,v 1.60 2014/03/05 09:37:29 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 February 22, 2014
+.Dd March 5, 2014
.Dt VNODE 9
.Os
.Sh NAME
@@ -79,7 +79,7 @@
.Ft void
.Fn ungetnewvnode "struct vnode *vp"
.Ft int
-.Fn vrecycle "struct vnode *vp" "struct kmutex_t *inter_lkp"
+.Fn vrecycle "struct vnode *vp"
.Ft void
.Fn vgone "struct vnode *vp"
.Ft void
@@ -616,12 +616,12 @@ This function is needed for
.Xr VFS_VGET 9
which may need to push back a vnode in case of a locking race
condition.
-.It Fn vrecycle "vp" "inter_lkp"
-Recycle the unused vnode
+.It Fn vrecycle "vp"
+Recycle the referenced vnode
.Fa vp
-from the front of the freelist.
+if this is the last reference.
.Fn vrecycle
-is a null operation if the reference count is greater than zero.
+is a null operation if the reference count is greater than one.
.It Fn vgone "vp"
Eliminate all activity associated with the unlocked vnode
.Fa vp
Index: src/sys/kern/vfs_mount.c
diff -u src/sys/kern/vfs_mount.c:1.26 src/sys/kern/vfs_mount.c:1.27
--- src/sys/kern/vfs_mount.c:1.26 Thu Feb 27 13:00:06 2014
+++ src/sys/kern/vfs_mount.c Wed Mar 5 09:37:29 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_mount.c,v 1.26 2014/02/27 13:00:06 hannken Exp $ */
+/* $NetBSD: vfs_mount.c,v 1.27 2014/03/05 09:37:29 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.26 2014/02/27 13:00:06 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.27 2014/03/05 09:37:29 hannken Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -375,6 +375,82 @@ vunmark(vnode_t *mvp)
return vp;
}
+struct vnode_iterator {
+ struct vnode vi_vnode;
+};
+
+void
+vfs_vnode_iterator_init(struct mount *mp, struct vnode_iterator **vipp)
+{
+ struct vnode *vp;
+
+ vp = vnalloc(mp);
+
+ mutex_enter(&mntvnode_lock);
+ TAILQ_INSERT_HEAD(&mp->mnt_vnodelist, vp, v_mntvnodes);
+ vp->v_usecount = 1;
+ mutex_exit(&mntvnode_lock);
+
+ *vipp = (struct vnode_iterator *)vp;
+}
+
+void
+vfs_vnode_iterator_destroy(struct vnode_iterator *vi)
+{
+ struct vnode *mvp = &vi->vi_vnode;
+
+ mutex_enter(&mntvnode_lock);
+ KASSERT(ISSET(mvp->v_iflag, VI_MARKER));
+ if (mvp->v_usecount != 0)
+ TAILQ_REMOVE(&mvp->v_mount->mnt_vnodelist, mvp, v_mntvnodes);
+ mutex_exit(&mntvnode_lock);
+ vnfree(mvp);
+}
+
+bool
+vfs_vnode_iterator_next(struct vnode_iterator *vi, struct vnode **vpp)
+{
+ struct vnode *mvp = &vi->vi_vnode;
+ struct mount *mp = mvp->v_mount;
+ struct vnode *vp;
+ int error;
+
+ KASSERT(ISSET(mvp->v_iflag, VI_MARKER));
+
+ do {
+ mutex_enter(&mntvnode_lock);
+ vp = TAILQ_NEXT(mvp, v_mntvnodes);
+ TAILQ_REMOVE(&mp->mnt_vnodelist, mvp, v_mntvnodes);
+ mvp->v_usecount = 0;
+ if (vp == NULL) {
+ mutex_exit(&mntvnode_lock);
+ *vpp = NULL;
+ return false;
+ }
+
+ mutex_enter(vp->v_interlock);
+ while ((vp->v_iflag & VI_MARKER) != 0) {
+ mutex_exit(vp->v_interlock);
+ vp = TAILQ_NEXT(vp, v_mntvnodes);
+ if (vp == NULL) {
+ mutex_exit(&mntvnode_lock);
+ *vpp = NULL;
+ return false;
+ }
+ mutex_enter(vp->v_interlock);
+ }
+
+ TAILQ_INSERT_AFTER(&mp->mnt_vnodelist, vp, mvp, v_mntvnodes);
+ mvp->v_usecount = 1;
+ mutex_exit(&mntvnode_lock);
+ error = vget(vp, 0);
+ KASSERT(error == 0 || error == ENOENT);
+ } while (error != 0);
+
+ *vpp = vp;
+ return true;
+}
+
/*
* Move a vnode from one mount queue to another.
*/
@@ -426,99 +502,78 @@ struct ctldebug debug1 = { "busyprt", &b
#endif
static vnode_t *
-vflushnext(vnode_t *mvp, int *when)
+vflushnext(struct vnode_iterator *marker, int *when)
{
+ struct vnode *vp;
if (hardclock_ticks > *when) {
- mutex_exit(&mntvnode_lock);
yield();
- mutex_enter(&mntvnode_lock);
*when = hardclock_ticks + hz / 10;
}
- return vunmark(mvp);
+ if (vfs_vnode_iterator_next(marker, &vp))
+ return vp;
+ return NULL;
}
int
vflush(struct mount *mp, vnode_t *skipvp, int flags)
{
- vnode_t *vp, *mvp;
+ vnode_t *vp;
+ struct vnode_iterator *marker;
int busy = 0, when = 0;
/* First, flush out any vnode references from vrele_list. */
vrele_flush();
- /* Allocate a marker vnode. */
- mvp = vnalloc(mp);
-
- /*
- * NOTE: not using the TAILQ_FOREACH here since in this loop vgone()
- * and vclean() are called.
- */
- mutex_enter(&mntvnode_lock);
- for (vp = TAILQ_FIRST(&mp->mnt_vnodelist);
- vp != NULL;
- vp = vflushnext(mvp, &when)) {
- vmark(mvp, vp);
- if (vp->v_mount != mp || vismarker(vp))
- continue;
+ vfs_vnode_iterator_init(mp, &marker);
+ while ((vp = vflushnext(marker, &when)) != NULL) {
/*
* Skip over a selected vnode.
*/
- if (vp == skipvp)
- continue;
- /*
- * First try to recycle the vnode.
- */
- if (vrecycle(vp, &mntvnode_lock)) {
- mutex_enter(&mntvnode_lock);
- continue;
- }
- mutex_enter(vp->v_interlock);
- /*
- * Ignore clean but still referenced vnodes.
- */
- if ((vp->v_iflag & VI_CLEAN) != 0) {
- mutex_exit(vp->v_interlock);
+ if (vp == skipvp) {
+ vrele(vp);
continue;
}
/*
* Skip over a vnodes marked VSYSTEM.
*/
if ((flags & SKIPSYSTEM) && (vp->v_vflag & VV_SYSTEM)) {
- mutex_exit(vp->v_interlock);
+ vrele(vp);
continue;
}
/*
* If WRITECLOSE is set, only flush out regular file
* vnodes open for writing.
*/
- if ((flags & WRITECLOSE) &&
- (vp->v_writecount == 0 || vp->v_type != VREG)) {
+ 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);
- continue;
}
/*
+ * First try to recycle the vnode.
+ */
+ if (vrecycle(vp))
+ continue;
+ /*
* If FORCECLOSE is set, forcibly close the vnode.
- * For block or character devices, revert to an
- * anonymous device. For all other files, just
- * kill them.
*/
if (flags & FORCECLOSE) {
- mutex_exit(&mntvnode_lock);
- if (vget(vp, 0) == 0)
- vgone(vp);
- mutex_enter(&mntvnode_lock);
+ vgone(vp);
continue;
}
#ifdef DEBUG
if (busyprt)
vprint("vflush: busy vnode", vp);
#endif
- mutex_exit(vp->v_interlock);
+ vrele(vp);
busy++;
}
- mutex_exit(&mntvnode_lock);
- vnfree(mvp);
+ vfs_vnode_iterator_destroy(marker);
if (busy)
return (EBUSY);
return (0);
Index: src/sys/kern/vfs_vnode.c
diff -u src/sys/kern/vfs_vnode.c:1.32 src/sys/kern/vfs_vnode.c:1.33
--- src/sys/kern/vfs_vnode.c:1.32 Thu Feb 27 16:51:38 2014
+++ src/sys/kern/vfs_vnode.c Wed Mar 5 09:37:29 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_vnode.c,v 1.32 2014/02/27 16:51:38 hannken Exp $ */
+/* $NetBSD: vfs_vnode.c,v 1.33 2014/03/05 09:37:29 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.32 2014/02/27 16:51:38 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.33 2014/03/05 09:37:29 hannken Exp $");
#define _VFS_VNODE_PRIVATE
@@ -1029,30 +1029,33 @@ vclean(vnode_t *vp)
}
/*
- * Recycle an unused vnode to the front of the free list.
- * Release the passed interlock if the vnode will be recycled.
+ * Recycle an unused vnode if caller holds the last reference.
*/
-int
-vrecycle(vnode_t *vp, kmutex_t *inter_lkp)
+bool
+vrecycle(vnode_t *vp)
{
+ mutex_enter(vp->v_interlock);
+
KASSERT((vp->v_iflag & VI_MARKER) == 0);
- mutex_enter(vp->v_interlock);
- if (vp->v_usecount != 0 || (vp->v_iflag & (VI_CLEAN|VI_XLOCK)) != 0) {
+ if (vp->v_usecount != 1) {
mutex_exit(vp->v_interlock);
- return 0;
+ return false;
}
- if (inter_lkp) {
- mutex_exit(inter_lkp);
+ if ((vp->v_iflag & VI_CHANGING) != 0)
+ vwait(vp, VI_CHANGING);
+ if (vp->v_usecount != 1) {
+ mutex_exit(vp->v_interlock);
+ return false;
+ } else if ((vp->v_iflag & VI_CLEAN) != 0) {
+ mutex_exit(vp->v_interlock);
+ return true;
}
- vremfree(vp);
- vp->v_usecount = 1;
- KASSERT((vp->v_iflag & VI_CHANGING) == 0);
vp->v_iflag |= VI_CHANGING;
vclean(vp);
vrelel(vp, VRELEL_CHANGING_SET);
- return 1;
+ return true;
}
/*
Index: src/sys/sys/mount.h
diff -u src/sys/sys/mount.h:1.211 src/sys/sys/mount.h:1.212
--- src/sys/sys/mount.h:1.211 Thu Feb 27 13:00:06 2014
+++ src/sys/sys/mount.h Wed Mar 5 09:37:29 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: mount.h,v 1.211 2014/02/27 13:00:06 hannken Exp $ */
+/* $NetBSD: mount.h,v 1.212 2014/03/05 09:37:29 hannken Exp $ */
/*
* Copyright (c) 1989, 1991, 1993
@@ -433,6 +433,11 @@ int vfs_quotactl_cursorrewind(struct mou
int vfs_quotactl_quotaon(struct mount *, int, const char *);
int vfs_quotactl_quotaoff(struct mount *, int);
+struct vnode_iterator; /* Opaque. */
+void vfs_vnode_iterator_init(struct mount *, struct vnode_iterator **);
+void vfs_vnode_iterator_destroy(struct vnode_iterator *);
+bool vfs_vnode_iterator_next(struct vnode_iterator *, struct vnode **);
+
extern TAILQ_HEAD(mntlist, mount) mountlist; /* mounted filesystem list */
extern struct vfsops *vfssw[]; /* filesystem type table */
extern int nvfssw;
Index: src/sys/sys/param.h
diff -u src/sys/sys/param.h:1.442 src/sys/sys/param.h:1.443
--- src/sys/sys/param.h:1.442 Thu Feb 27 16:51:39 2014
+++ src/sys/sys/param.h Wed Mar 5 09:37:29 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: param.h,v 1.442 2014/02/27 16:51:39 hannken Exp $ */
+/* $NetBSD: param.h,v 1.443 2014/03/05 09:37:29 hannken Exp $ */
/*-
* Copyright (c) 1982, 1986, 1989, 1993
@@ -63,7 +63,7 @@
* 2.99.9 (299000900)
*/
-#define __NetBSD_Version__ 699003300 /* NetBSD 6.99.33 */
+#define __NetBSD_Version__ 699003400 /* NetBSD 6.99.34 */
#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.243 src/sys/sys/vnode.h:1.244
--- src/sys/sys/vnode.h:1.243 Sun Dec 1 17:29:40 2013
+++ src/sys/sys/vnode.h Wed Mar 5 09:37:29 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: vnode.h,v 1.243 2013/12/01 17:29:40 christos Exp $ */
+/* $NetBSD: vnode.h,v 1.244 2014/03/05 09:37:29 hannken Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -545,7 +545,7 @@ void vgone(struct vnode *);
int vinvalbuf(struct vnode *, int, kauth_cred_t, struct lwp *, bool, int);
void vprint(const char *, struct vnode *);
void vput(struct vnode *);
-int vrecycle(struct vnode *, kmutex_t *);
+bool vrecycle(struct vnode *);
void vrele(struct vnode *);
void vrele_async(struct vnode *);
void vrele_flush(void);
Index: src/sys/ufs/ext2fs/ext2fs_vfsops.c
diff -u src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.176 src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.177
--- src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.176 Tue Feb 25 18:30:13 2014
+++ src/sys/ufs/ext2fs/ext2fs_vfsops.c Wed Mar 5 09:37:29 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ext2fs_vfsops.c,v 1.176 2014/02/25 18:30:13 pooka Exp $ */
+/* $NetBSD: ext2fs_vfsops.c,v 1.177 2014/03/05 09:37:29 hannken Exp $ */
/*
* Copyright (c) 1989, 1991, 1993, 1994
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.176 2014/02/25 18:30:13 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.177 2014/03/05 09:37:29 hannken Exp $");
#if defined(_KERNEL_OPT)
#include "opt_compat_netbsd.h"
@@ -512,7 +512,7 @@ fail:
int
ext2fs_reload(struct mount *mp, kauth_cred_t cred, struct lwp *l)
{
- struct vnode *vp, *mvp, *devvp;
+ struct vnode *vp, *devvp;
struct inode *ip;
struct buf *bp;
struct m_ext2fs *fs;
@@ -520,6 +520,7 @@ ext2fs_reload(struct mount *mp, kauth_cr
int i, error;
void *cp;
struct ufsmount *ump;
+ struct vnode_iterator *marker;
if ((mp->mnt_flag & MNT_RDONLY) == 0)
return (EINVAL);
@@ -585,35 +586,19 @@ ext2fs_reload(struct mount *mp, kauth_cr
brelse(bp, 0);
}
- /* Allocate a marker vnode. */
- mvp = vnalloc(mp);
- /*
- * NOTE: not using the TAILQ_FOREACH here since in this loop vgone()
- * and vclean() can be called indirectly
- */
- mutex_enter(&mntvnode_lock);
-loop:
- for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) {
- vmark(mvp, vp);
- if (vp->v_mount != mp || vismarker(vp))
- continue;
+ vfs_vnode_iterator_init(mp, &marker);
+ while (vfs_vnode_iterator_next(marker, &vp)) {
/*
* Step 4: invalidate all inactive vnodes.
*/
- if (vrecycle(vp, &mntvnode_lock)) {
- mutex_enter(&mntvnode_lock);
- (void)vunmark(mvp);
- goto loop;
- }
+ if (vrecycle(vp))
+ continue;
/*
* Step 5: invalidate all cached file data.
*/
- mutex_enter(vp->v_interlock);
- mutex_exit(&mntvnode_lock);
- if (vget(vp, LK_EXCLUSIVE)) {
- mutex_enter(&mntvnode_lock);
- (void)vunmark(mvp);
- goto loop;
+ if (vn_lock(vp, LK_EXCLUSIVE)) {
+ vrele(vp);
+ continue;
}
if (vinvalbuf(vp, 0, cred, l, 0, 0))
panic("ext2fs_reload: dirty2");
@@ -625,8 +610,6 @@ loop:
(int)fs->e2fs_bsize, NOCRED, 0, &bp);
if (error) {
vput(vp);
- mutex_enter(&mntvnode_lock);
- (void)vunmark(mvp);
break;
}
cp = (char *)bp->b_data +
@@ -635,10 +618,8 @@ loop:
ext2fs_set_inode_guid(ip);
brelse(bp, 0);
vput(vp);
- mutex_enter(&mntvnode_lock);
}
- mutex_exit(&mntvnode_lock);
- vnfree(mvp);
+ vfs_vnode_iterator_destroy(marker);
return (error);
}
Index: src/sys/ufs/ffs/ffs_vfsops.c
diff -u src/sys/ufs/ffs/ffs_vfsops.c:1.292 src/sys/ufs/ffs/ffs_vfsops.c:1.293
--- src/sys/ufs/ffs/ffs_vfsops.c:1.292 Tue Feb 25 18:30:13 2014
+++ src/sys/ufs/ffs/ffs_vfsops.c Wed Mar 5 09:37:29 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_vfsops.c,v 1.292 2014/02/25 18:30:13 pooka Exp $ */
+/* $NetBSD: ffs_vfsops.c,v 1.293 2014/03/05 09:37:29 hannken Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.292 2014/02/25 18:30:13 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.293 2014/03/05 09:37:29 hannken Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@@ -636,7 +636,7 @@ fail:
int
ffs_reload(struct mount *mp, kauth_cred_t cred, struct lwp *l)
{
- struct vnode *vp, *mvp, *devvp;
+ struct vnode *vp, *devvp;
struct inode *ip;
void *space;
struct buf *bp;
@@ -646,6 +646,7 @@ ffs_reload(struct mount *mp, kauth_cred_
int32_t *lp;
struct ufsmount *ump;
daddr_t sblockloc;
+ struct vnode_iterator *marker;
if ((mp->mnt_flag & MNT_RDONLY) == 0)
return (EINVAL);
@@ -805,34 +806,19 @@ ffs_reload(struct mount *mp, kauth_cred_
*lp++ = fs->fs_contigsumsize;
}
- /* Allocate a marker vnode. */
- mvp = vnalloc(mp);
- /*
- * NOTE: not using the TAILQ_FOREACH here since in this loop vgone()
- * and vclean() can be called indirectly
- */
- mutex_enter(&mntvnode_lock);
- loop:
- for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = vunmark(mvp)) {
- vmark(mvp, vp);
- if (vp->v_mount != mp || vismarker(vp))
- continue;
+ vfs_vnode_iterator_init(mp, &marker);
+ while (vfs_vnode_iterator_next(marker, &vp)) {
/*
* Step 4: invalidate all inactive vnodes.
*/
- if (vrecycle(vp, &mntvnode_lock)) {
- mutex_enter(&mntvnode_lock);
- (void)vunmark(mvp);
- goto loop;
- }
+ if (vrecycle(vp))
+ continue;
/*
* Step 5: invalidate all cached file data.
*/
- mutex_enter(vp->v_interlock);
- mutex_exit(&mntvnode_lock);
- if (vget(vp, LK_EXCLUSIVE)) {
- (void)vunmark(mvp);
- goto loop;
+ if (vn_lock(vp, LK_EXCLUSIVE)) {
+ vrele(vp);
+ continue;
}
if (vinvalbuf(vp, 0, cred, l, 0, 0))
panic("ffs_reload: dirty2");
@@ -844,16 +830,13 @@ ffs_reload(struct mount *mp, kauth_cred_
(int)fs->fs_bsize, NOCRED, 0, &bp);
if (error) {
vput(vp);
- (void)vunmark(mvp);
break;
}
ffs_load_inode(bp, ip, fs, ip->i_number);
brelse(bp, 0);
vput(vp);
- mutex_enter(&mntvnode_lock);
}
- mutex_exit(&mntvnode_lock);
- vnfree(mvp);
+ vfs_vnode_iterator_destroy(marker);
return (error);
}
Index: src/sys/ufs/lfs/lfs_syscalls.c
diff -u src/sys/ufs/lfs/lfs_syscalls.c:1.150 src/sys/ufs/lfs/lfs_syscalls.c:1.151
--- src/sys/ufs/lfs/lfs_syscalls.c:1.150 Tue Oct 29 09:53:51 2013
+++ src/sys/ufs/lfs/lfs_syscalls.c Wed Mar 5 09:37:29 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_syscalls.c,v 1.150 2013/10/29 09:53:51 hannken Exp $ */
+/* $NetBSD: lfs_syscalls.c,v 1.151 2014/03/05 09:37:29 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.150 2013/10/29 09:53:51 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lfs_syscalls.c,v 1.151 2014/03/05 09:37:29 hannken Exp $");
#ifndef LFS
# define LFS /* for prototypes in syscallargs.h */
@@ -712,8 +712,13 @@ lfs_bmapv(struct proc *p, fsid_t *fsidp,
*/
if (v_daddr != LFS_UNUSED_DADDR) {
lfs_vunref(vp);
- if (VTOI(vp)->i_lfs_iflags & LFSI_BMAP)
- vrecycle(vp, NULL);
+ if (VTOI(vp)->i_lfs_iflags & LFSI_BMAP) {
+ mutex_enter(vp->v_interlock);
+ if (vget(vp, LK_NOWAIT) == 0) {
+ if (! vrecycle(vp))
+ vrele(vp);
+ }
+ }
numrefed--;
}
@@ -822,8 +827,13 @@ lfs_bmapv(struct proc *p, fsid_t *fsidp,
if (v_daddr != LFS_UNUSED_DADDR) {
lfs_vunref(vp);
/* Recycle as above. */
- if (ip->i_lfs_iflags & LFSI_BMAP)
- vrecycle(vp, NULL);
+ if (ip->i_lfs_iflags & LFSI_BMAP) {
+ mutex_enter(vp->v_interlock);
+ if (vget(vp, LK_NOWAIT) == 0) {
+ if (! vrecycle(vp))
+ vrele(vp);
+ }
+ }
numrefed--;
}