summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/fs/coda/coda_subr.c9
-rw-r--r--sys/fs/ext2fs/ext2_vfsops.c26
-rw-r--r--sys/fs/msdosfs/msdosfs_vfsops.c11
-rw-r--r--sys/fs/nfsclient/nfs_clsubs.c11
-rw-r--r--sys/fs/nfsclient/nfs_clvfsops.c12
-rw-r--r--sys/kern/vfs_default.c15
-rw-r--r--sys/kern/vfs_mount.c10
-rw-r--r--sys/kern/vfs_subr.c109
-rw-r--r--sys/nfsclient/nfs_subs.c10
-rw-r--r--sys/nfsclient/nfs_vfsops.c11
-rw-r--r--sys/sys/mount.h24
-rw-r--r--sys/ufs/ffs/ffs_snapshot.c36
-rw-r--r--sys/ufs/ffs/ffs_softdep.c12
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c60
-rw-r--r--sys/ufs/ufs/ufs_quota.c34
15 files changed, 178 insertions, 212 deletions
diff --git a/sys/fs/coda/coda_subr.c b/sys/fs/coda/coda_subr.c
index 08c03cb..ecdd927 100644
--- a/sys/fs/coda/coda_subr.c
+++ b/sys/fs/coda/coda_subr.c
@@ -365,13 +365,7 @@ coda_checkunmounting(struct mount *mp)
struct cnode *cp;
int count = 0, bad = 0;
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH(vp, mp, nvp) {
- VI_LOCK(vp);
- if (vp->v_iflag & VI_DOOMED) {
- VI_UNLOCK(vp);
- continue;
- }
+ MNT_VNODE_FOREACH_ALL(vp, mp, nvp) {
cp = VTOC(vp);
count++;
if (!(cp->c_flags & C_UNMOUNTING)) {
@@ -381,7 +375,6 @@ coda_checkunmounting(struct mount *mp)
}
VI_UNLOCK(vp);
}
- MNT_IUNLOCK(mp);
}
void
diff --git a/sys/fs/ext2fs/ext2_vfsops.c b/sys/fs/ext2fs/ext2_vfsops.c
index 48d5cb2..10ba705 100644
--- a/sys/fs/ext2fs/ext2_vfsops.c
+++ b/sys/fs/ext2fs/ext2_vfsops.c
@@ -480,19 +480,12 @@ ext2_reload(struct mount *mp, struct thread *td)
}
loop:
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH(vp, mp, mvp) {
- VI_LOCK(vp);
- if (vp->v_iflag & VI_DOOMED) {
- VI_UNLOCK(vp);
- continue;
- }
- MNT_IUNLOCK(mp);
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
/*
* Step 4: invalidate all cached file data.
*/
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
- MNT_VNODE_FOREACH_ABORT(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
goto loop;
}
if (vinvalbuf(vp, 0, 0, 0))
@@ -507,7 +500,7 @@ loop:
if (error) {
VOP_UNLOCK(vp, 0);
vrele(vp);
- MNT_VNODE_FOREACH_ABORT(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
return (error);
}
ext2_ei2i((struct ext2fs_dinode *) ((char *)bp->b_data +
@@ -515,9 +508,7 @@ loop:
brelse(bp);
VOP_UNLOCK(vp, 0);
vrele(vp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
return (0);
}
@@ -841,27 +832,24 @@ ext2_sync(struct mount *mp, int waitfor)
*/
MNT_ILOCK(mp);
loop:
- MNT_VNODE_FOREACH(vp, mp, mvp) {
- VI_LOCK(vp);
- if (vp->v_type == VNON || (vp->v_iflag & VI_DOOMED)) {
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
+ if (vp->v_type == VNON) {
VI_UNLOCK(vp);
continue;
}
- MNT_IUNLOCK(mp);
ip = VTOI(vp);
if ((ip->i_flag &
(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
(vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
waitfor == MNT_LAZY)) {
VI_UNLOCK(vp);
- MNT_ILOCK(mp);
continue;
}
error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, td);
if (error) {
MNT_ILOCK(mp);
if (error == ENOENT) {
- MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
goto loop;
}
continue;
@@ -870,9 +858,7 @@ loop:
allerror = error;
VOP_UNLOCK(vp, 0);
vrele(vp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
/*
* Force stale file system control information to be flushed.
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
index f8eb317..d2f49d9 100644
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -923,27 +923,22 @@ msdosfs_sync(struct mount *mp, int waitfor)
/*
* Write back each (modified) denode.
*/
- MNT_ILOCK(mp);
loop:
- MNT_VNODE_FOREACH(vp, mp, nvp) {
- VI_LOCK(vp);
- if (vp->v_type == VNON || (vp->v_iflag & VI_DOOMED)) {
+ MNT_VNODE_FOREACH_ALL(vp, mp, nvp) {
+ if (vp->v_type == VNON) {
VI_UNLOCK(vp);
continue;
}
- MNT_IUNLOCK(mp);
dep = VTODE(vp);
if ((dep->de_flag &
(DE_ACCESS | DE_CREATE | DE_UPDATE | DE_MODIFIED)) == 0 &&
(vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
waitfor == MNT_LAZY)) {
VI_UNLOCK(vp);
- MNT_ILOCK(mp);
continue;
}
error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, td);
if (error) {
- MNT_ILOCK(mp);
if (error == ENOENT)
goto loop;
continue;
@@ -953,9 +948,7 @@ loop:
allerror = error;
VOP_UNLOCK(vp, 0);
vrele(vp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
/*
* Flush filesystem control info.
diff --git a/sys/fs/nfsclient/nfs_clsubs.c b/sys/fs/nfsclient/nfs_clsubs.c
index f64cf2d..1629cf3 100644
--- a/sys/fs/nfsclient/nfs_clsubs.c
+++ b/sys/fs/nfsclient/nfs_clsubs.c
@@ -367,17 +367,10 @@ ncl_clearcommit(struct mount *mp)
struct buf *bp, *nbp;
struct bufobj *bo;
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH(vp, mp, nvp) {
+ MNT_VNODE_FOREACH_ALL(vp, mp, nvp) {
bo = &vp->v_bufobj;
- VI_LOCK(vp);
- if (vp->v_iflag & VI_DOOMED) {
- VI_UNLOCK(vp);
- continue;
- }
vholdl(vp);
VI_UNLOCK(vp);
- MNT_IUNLOCK(mp);
BO_LOCK(bo);
TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) {
if (!BUF_ISLOCKED(bp) &&
@@ -387,9 +380,7 @@ ncl_clearcommit(struct mount *mp)
}
BO_UNLOCK(bo);
vdrop(vp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
}
/*
diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c
index 04d8e67..af0e33b 100644
--- a/sys/fs/nfsclient/nfs_clvfsops.c
+++ b/sys/fs/nfsclient/nfs_clvfsops.c
@@ -1508,24 +1508,21 @@ nfs_sync(struct mount *mp, int waitfor)
MNT_IUNLOCK(mp);
return (EBADF);
}
+ MNT_IUNLOCK(mp);
/*
* Force stale buffer cache information to be flushed.
*/
loop:
- MNT_VNODE_FOREACH(vp, mp, mvp) {
- VI_LOCK(vp);
- MNT_IUNLOCK(mp);
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
/* XXX Racy bv_cnt check. */
if (NFSVOPISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
waitfor == MNT_LAZY) {
VI_UNLOCK(vp);
- MNT_ILOCK(mp);
continue;
}
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
goto loop;
}
error = VOP_FSYNC(vp, waitfor, td);
@@ -1533,10 +1530,7 @@ loop:
allerror = error;
NFSVOPUNLOCK(vp, 0);
vrele(vp);
-
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
return (allerror);
}
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 25278c8..4e62765 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -1114,18 +1114,15 @@ vfs_stdsync(mp, waitfor)
/*
* Force stale buffer cache information to be flushed.
*/
- MNT_ILOCK(mp);
loop:
- MNT_VNODE_FOREACH(vp, mp, mvp) {
- /* bv_cnt is an acceptable race here. */
- if (vp->v_bufobj.bo_dirty.bv_cnt == 0)
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
+ if (vp->v_bufobj.bo_dirty.bv_cnt == 0) {
+ VI_UNLOCK(vp);
continue;
- VI_LOCK(vp);
- MNT_IUNLOCK(mp);
+ }
if ((error = vget(vp, lockreq, td)) != 0) {
- MNT_ILOCK(mp);
if (error == ENOENT) {
- MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
goto loop;
}
continue;
@@ -1134,9 +1131,7 @@ loop:
if (error)
allerror = error;
vput(vp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
return (allerror);
}
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 657fa92..6a5dfb0 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -81,7 +81,6 @@ SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0,
"Unprivileged users may mount and unmount file systems");
MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure");
-static MALLOC_DEFINE(M_VNODE_MARKER, "vnodemarker", "vnode marker");
static uma_zone_t mount_zone;
/* List of mounted filesystems. */
@@ -1720,10 +1719,14 @@ vfs_copyopt(opts, name, dest, len)
}
/*
- * This is a helper function for filesystems to traverse their
- * vnodes. See MNT_VNODE_FOREACH() in sys/mount.h
+ * These are helper functions for filesystems to traverse all
+ * their vnodes. See MNT_VNODE_FOREACH() in sys/mount.h.
+ *
+ * This interface has been deprecated in favor of MNT_VNODE_FOREACH_ALL.
*/
+MALLOC_DECLARE(M_VNODE_MARKER);
+
struct vnode *
__mnt_vnode_next(struct vnode **mvp, struct mount *mp)
{
@@ -1812,7 +1815,6 @@ __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp)
MNT_REL(mp);
}
-
int
__vfs_statfs(struct mount *mp, struct statfs *sbp)
{
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 051f8f7..14f8528 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -2467,17 +2467,13 @@ vflush(struct mount *mp, int rootrefs, int flags, struct thread *td)
}
vput(rootvp);
}
- MNT_ILOCK(mp);
loop:
- MNT_VNODE_FOREACH(vp, mp, mvp) {
- VI_LOCK(vp);
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
vholdl(vp);
- MNT_IUNLOCK(mp);
error = vn_lock(vp, LK_INTERLOCK | LK_EXCLUSIVE);
if (error) {
vdrop(vp);
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
goto loop;
}
/*
@@ -2486,7 +2482,6 @@ loop:
if ((flags & SKIPSYSTEM) && (vp->v_vflag & VV_SYSTEM)) {
VOP_UNLOCK(vp, 0);
vdrop(vp);
- MNT_ILOCK(mp);
continue;
}
/*
@@ -2504,7 +2499,7 @@ loop:
if (error != 0) {
VOP_UNLOCK(vp, 0);
vdrop(vp);
- MNT_VNODE_FOREACH_ABORT(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
return (error);
}
error = VOP_GETATTR(vp, &vattr, td->td_ucred);
@@ -2515,7 +2510,6 @@ loop:
(vp->v_writecount == 0 || vp->v_type != VREG)) {
VOP_UNLOCK(vp, 0);
vdropl(vp);
- MNT_ILOCK(mp);
continue;
}
} else
@@ -2540,9 +2534,7 @@ loop:
}
VOP_UNLOCK(vp, 0);
vdropl(vp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
if (rootrefs > 0 && (flags & FORCECLOSE) == 0) {
/*
* If just the root vnode is busy, and if its refcount
@@ -3279,19 +3271,15 @@ vfs_msync(struct mount *mp, int flags)
struct vm_object *obj;
CTR2(KTR_VFS, "%s: mp %p", __func__, mp);
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH(vp, mp, mvp) {
- VI_LOCK(vp);
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
obj = vp->v_object;
if (obj != NULL && (obj->flags & OBJ_MIGHTBEDIRTY) != 0 &&
(flags == MNT_WAIT || VOP_ISLOCKED(vp) == 0)) {
- MNT_IUNLOCK(mp);
if (!vget(vp,
LK_EXCLUSIVE | LK_RETRY | LK_INTERLOCK,
curthread)) {
if (vp->v_vflag & VV_NOSYNC) { /* unlinked */
vput(vp);
- MNT_ILOCK(mp);
continue;
}
@@ -3305,11 +3293,9 @@ vfs_msync(struct mount *mp, int flags)
}
vput(vp);
}
- MNT_ILOCK(mp);
} else
VI_UNLOCK(vp);
}
- MNT_IUNLOCK(mp);
}
/*
@@ -4504,3 +4490,90 @@ vfs_unixify_accmode(accmode_t *accmode)
return (0);
}
+
+/*
+ * These are helper functions for filesystems to traverse all
+ * their vnodes. See MNT_VNODE_FOREACH_ALL() in sys/mount.h.
+ *
+ * This interface replaces MNT_VNODE_FOREACH.
+ */
+
+MALLOC_DEFINE(M_VNODE_MARKER, "vnodemarker", "vnode marker");
+
+struct vnode *
+__mnt_vnode_next_all(struct vnode **mvp, struct mount *mp)
+{
+ struct vnode *vp;
+
+ if (should_yield())
+ kern_yield(PRI_UNCHANGED);
+ MNT_ILOCK(mp);
+ KASSERT((*mvp)->v_mount == mp, ("marker vnode mount list mismatch"));
+ vp = TAILQ_NEXT(*mvp, v_nmntvnodes);
+ while (vp != NULL && (vp->v_type == VMARKER ||
+ (vp->v_iflag & VI_DOOMED) != 0))
+ vp = TAILQ_NEXT(vp, v_nmntvnodes);
+
+ /* Check if we are done */
+ if (vp == NULL) {
+ __mnt_vnode_markerfree_all(mvp, mp);
+ /* MNT_IUNLOCK(mp); -- done in above function */
+ mtx_assert(MNT_MTX(mp), MA_NOTOWNED);
+ return (NULL);
+ }
+ TAILQ_REMOVE(&mp->mnt_nvnodelist, *mvp, v_nmntvnodes);
+ TAILQ_INSERT_AFTER(&mp->mnt_nvnodelist, vp, *mvp, v_nmntvnodes);
+ VI_LOCK(vp);
+ MNT_IUNLOCK(mp);
+ return (vp);
+}
+
+struct vnode *
+__mnt_vnode_first_all(struct vnode **mvp, struct mount *mp)
+{
+ struct vnode *vp;
+
+ *mvp = malloc(sizeof(struct vnode), M_VNODE_MARKER, M_WAITOK | M_ZERO);
+ MNT_ILOCK(mp);
+ MNT_REF(mp);
+ (*mvp)->v_type = VMARKER;
+
+ vp = TAILQ_FIRST(&mp->mnt_nvnodelist);
+ while (vp != NULL && (vp->v_type == VMARKER ||
+ (vp->v_iflag & VI_DOOMED) != 0))
+ vp = TAILQ_NEXT(vp, v_nmntvnodes);
+
+ /* Check if we are done */
+ if (vp == NULL) {
+ *mvp = NULL;
+ MNT_REL(mp);
+ MNT_IUNLOCK(mp);
+ free(*mvp, M_VNODE_MARKER);
+ return (NULL);
+ }
+ (*mvp)->v_mount = mp;
+ TAILQ_INSERT_AFTER(&mp->mnt_nvnodelist, vp, *mvp, v_nmntvnodes);
+ VI_LOCK(vp);
+ MNT_IUNLOCK(mp);
+ return (vp);
+}
+
+
+void
+__mnt_vnode_markerfree_all(struct vnode **mvp, struct mount *mp)
+{
+
+ if (*mvp == NULL) {
+ MNT_IUNLOCK(mp);
+ return;
+ }
+
+ mtx_assert(MNT_MTX(mp), MA_OWNED);
+
+ KASSERT((*mvp)->v_mount == mp, ("marker vnode mount list mismatch"));
+ TAILQ_REMOVE(&mp->mnt_nvnodelist, *mvp, v_nmntvnodes);
+ MNT_REL(mp);
+ MNT_IUNLOCK(mp);
+ free(*mvp, M_VNODE_MARKER);
+ *mvp = NULL;
+}
diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c
index d00a025..0d306c0 100644
--- a/sys/nfsclient/nfs_subs.c
+++ b/sys/nfsclient/nfs_subs.c
@@ -866,16 +866,10 @@ nfs_clearcommit(struct mount *mp)
struct bufobj *bo;
MNT_ILOCK(mp);
- MNT_VNODE_FOREACH(vp, mp, nvp) {
+ MNT_VNODE_FOREACH_ALL(vp, mp, nvp) {
bo = &vp->v_bufobj;
- VI_LOCK(vp);
- if (vp->v_iflag & VI_DOOMED) {
- VI_UNLOCK(vp);
- continue;
- }
vholdl(vp);
VI_UNLOCK(vp);
- MNT_IUNLOCK(mp);
BO_LOCK(bo);
TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) {
if (!BUF_ISLOCKED(bp) &&
@@ -885,9 +879,7 @@ nfs_clearcommit(struct mount *mp)
}
BO_UNLOCK(bo);
vdrop(vp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
}
/*
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index 8f1be3a..b2586c3 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -1457,19 +1457,15 @@ nfs_sync(struct mount *mp, int waitfor)
* Force stale buffer cache information to be flushed.
*/
loop:
- MNT_VNODE_FOREACH(vp, mp, mvp) {
- VI_LOCK(vp);
- MNT_IUNLOCK(mp);
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
/* XXX Racy bv_cnt check. */
if (VOP_ISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
waitfor == MNT_LAZY) {
VI_UNLOCK(vp);
- MNT_ILOCK(mp);
continue;
}
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
goto loop;
}
error = VOP_FSYNC(vp, waitfor, td);
@@ -1477,10 +1473,7 @@ loop:
allerror = error;
VOP_UNLOCK(vp, 0);
vrele(vp);
-
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
return (allerror);
}
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 56848d9..79740fb 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -187,6 +187,30 @@ struct mount {
struct lock mnt_explock; /* vfs_export walkers lock */
};
+/*
+ * Definitions for MNT_VNODE_FOREACH_ALL.
+ */
+struct vnode *__mnt_vnode_next_all(struct vnode **mvp, struct mount *mp);
+struct vnode *__mnt_vnode_first_all(struct vnode **mvp, struct mount *mp);
+void __mnt_vnode_markerfree_all(struct vnode **mvp, struct mount *mp);
+
+#define MNT_VNODE_FOREACH_ALL(vp, mp, mvp) \
+ for (vp = __mnt_vnode_first_all(&(mvp), (mp)); \
+ (vp) != NULL; vp = __mnt_vnode_next_all(&(mvp), (mp)))
+
+#define MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp) \
+ do { \
+ MNT_ILOCK(mp); \
+ __mnt_vnode_markerfree_all(&(mvp), (mp)); \
+ /* MNT_IUNLOCK(mp); -- done in above function */ \
+ mtx_assert(MNT_MTX(mp), MA_NOTOWNED); \
+ } while (0)
+
+/*
+ * Definitions for MNT_VNODE_FOREACH.
+ *
+ * This interface has been deprecated in favor of MNT_VNODE_FOREACH_ALL.
+ */
struct vnode *__mnt_vnode_next(struct vnode **mvp, struct mount *mp);
struct vnode *__mnt_vnode_first(struct vnode **mvp, struct mount *mp);
void __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp);
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c
index 4f90ef6..c7449f0 100644
--- a/sys/ufs/ffs/ffs_snapshot.c
+++ b/sys/ufs/ffs/ffs_snapshot.c
@@ -522,17 +522,14 @@ restart:
FSMAXSNAP + 1 /* superblock */ + 1 /* last block */ + 1 /* size */;
MNT_ILOCK(mp);
mp->mnt_kern_flag &= ~MNTK_SUSPENDED;
+ MNT_IUNLOCK(mp);
loop:
- MNT_VNODE_FOREACH(xvp, mp, mvp) {
- VI_LOCK(xvp);
- MNT_IUNLOCK(mp);
- if ((xvp->v_iflag & VI_DOOMED) ||
- (xvp->v_usecount == 0 &&
+ MNT_VNODE_FOREACH_ALL(xvp, mp, mvp) {
+ if ((xvp->v_usecount == 0 &&
(xvp->v_iflag & (VI_OWEINACT | VI_DOINGINACT)) == 0) ||
xvp->v_type == VNON ||
IS_SNAPSHOT(VTOI(xvp))) {
VI_UNLOCK(xvp);
- MNT_ILOCK(mp);
continue;
}
/*
@@ -541,13 +538,11 @@ loop:
*/
if (xvp == nd.ni_dvp) {
VI_UNLOCK(xvp);
- MNT_ILOCK(mp);
continue;
}
vholdl(xvp);
if (vn_lock(xvp, LK_EXCLUSIVE | LK_INTERLOCK) != 0) {
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
vdrop(xvp);
goto loop;
}
@@ -557,7 +552,6 @@ loop:
VI_UNLOCK(xvp);
VOP_UNLOCK(xvp, 0);
vdrop(xvp);
- MNT_ILOCK(mp);
continue;
}
VI_UNLOCK(xvp);
@@ -567,14 +561,12 @@ loop:
vat.va_nlink > 0) {
VOP_UNLOCK(xvp, 0);
vdrop(xvp);
- MNT_ILOCK(mp);
continue;
}
xp = VTOI(xvp);
if (ffs_checkfreefile(copy_fs, vp, xp->i_number)) {
VOP_UNLOCK(xvp, 0);
vdrop(xvp);
- MNT_ILOCK(mp);
continue;
}
/*
@@ -610,12 +602,10 @@ loop:
free(copy_fs->fs_csp, M_UFSMNT);
free(copy_fs, M_UFSMNT);
copy_fs = NULL;
- MNT_VNODE_FOREACH_ABORT(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
goto out1;
}
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
/*
* Erase the journal file from the snapshot.
*/
@@ -2532,31 +2522,26 @@ process_deferred_inactive(struct mount *mp)
td = curthread;
(void) vn_start_secondary_write(NULL, &mp, V_WAIT);
- MNT_ILOCK(mp);
loop:
- MNT_VNODE_FOREACH(vp, mp, mvp) {
- VI_LOCK(vp);
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
/*
* IN_LAZYACCESS is checked here without holding any
* vnode lock, but this flag is set only while holding
* vnode interlock.
*/
- if (vp->v_type == VNON || (vp->v_iflag & VI_DOOMED) != 0 ||
+ if (vp->v_type == VNON ||
((VTOI(vp)->i_flag & IN_LAZYACCESS) == 0 &&
- ((vp->v_iflag & VI_OWEINACT) == 0 ||
- vp->v_usecount > 0))) {
+ ((vp->v_iflag & VI_OWEINACT) == 0 || vp->v_usecount > 0))) {
VI_UNLOCK(vp);
continue;
}
- MNT_IUNLOCK(mp);
vholdl(vp);
error = vn_lock(vp, LK_EXCLUSIVE | LK_INTERLOCK);
if (error != 0) {
vdrop(vp);
- MNT_ILOCK(mp);
if (error == ENOENT)
continue; /* vnode recycled */
- MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
goto loop;
}
ip = VTOI(vp);
@@ -2569,7 +2554,6 @@ process_deferred_inactive(struct mount *mp)
VI_UNLOCK(vp);
VOP_UNLOCK(vp, 0);
vdrop(vp);
- MNT_ILOCK(mp);
continue;
}
vinactive(vp, td);
@@ -2578,9 +2562,7 @@ process_deferred_inactive(struct mount *mp)
VI_UNLOCK(vp);
VOP_UNLOCK(vp, 0);
vdrop(vp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
vn_finished_secondary_write(mp);
}
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index a435738..dcf9622 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -12642,29 +12642,21 @@ retry:
fs->fs_cstotal.cs_nbfree <= needed) ||
(resource == FLUSH_INODES_WAIT && fs->fs_pendinginodes > 0 &&
fs->fs_cstotal.cs_nifree <= needed)) {
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH(lvp, mp, mvp) {
- VI_LOCK(lvp);
+ MNT_VNODE_FOREACH_ALL(lvp, mp, mvp) {
if (TAILQ_FIRST(&lvp->v_bufobj.bo_dirty.bv_hd) == 0) {
VI_UNLOCK(lvp);
continue;
}
- MNT_IUNLOCK(mp);
if (vget(lvp, LK_EXCLUSIVE | LK_INTERLOCK | LK_NOWAIT,
- curthread)) {
- MNT_ILOCK(mp);
+ curthread))
continue;
- }
if (lvp->v_vflag & VV_NOSYNC) { /* unlinked */
vput(lvp);
- MNT_ILOCK(mp);
continue;
}
(void) ffs_syncvnode(lvp, MNT_NOWAIT, 0);
vput(lvp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
lvp = ump->um_devvp;
if (vn_lock(lvp, LK_EXCLUSIVE | LK_NOWAIT) == 0) {
VOP_FSYNC(lvp, MNT_NOWAIT, curthread);
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 936445a..7faf018 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -705,19 +705,12 @@ ffs_reload(struct mount *mp, struct thread *td)
}
loop:
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH(vp, mp, mvp) {
- VI_LOCK(vp);
- if (vp->v_iflag & VI_DOOMED) {
- VI_UNLOCK(vp);
- continue;
- }
- MNT_IUNLOCK(mp);
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
/*
* Step 4: invalidate all cached file data.
*/
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
- MNT_VNODE_FOREACH_ABORT(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
goto loop;
}
if (vinvalbuf(vp, 0, 0, 0))
@@ -732,7 +725,7 @@ loop:
if (error) {
VOP_UNLOCK(vp, 0);
vrele(vp);
- MNT_VNODE_FOREACH_ABORT(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
return (error);
}
ffs_load_inode(bp, ip, fs, ip->i_number);
@@ -740,9 +733,7 @@ loop:
brelse(bp);
VOP_UNLOCK(vp, 0);
vrele(vp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
return (0);
}
@@ -1441,10 +1432,8 @@ ffs_sync_lazy(mp)
td = curthread;
if ((mp->mnt_flag & MNT_NOATIME) != 0)
goto qupdate;
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH(vp, mp, mvp) {
- VI_LOCK(vp);
- if (vp->v_iflag & VI_DOOMED || vp->v_type == VNON) {
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
+ if (vp->v_type == VNON) {
VI_UNLOCK(vp);
continue;
}
@@ -1462,19 +1451,14 @@ ffs_sync_lazy(mp)
VI_UNLOCK(vp);
continue;
}
- MNT_IUNLOCK(mp);
if ((error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK,
- td)) != 0) {
- MNT_ILOCK(mp);
+ td)) != 0)
continue;
- }
error = ffs_update(vp, 0);
if (error != 0)
allerror = error;
vput(vp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
qupdate:
#ifdef QUOTA
@@ -1538,41 +1522,37 @@ ffs_sync(mp, waitfor)
lockreq = LK_EXCLUSIVE;
}
lockreq |= LK_INTERLOCK | LK_SLEEPFAIL;
- MNT_ILOCK(mp);
loop:
/* Grab snapshot of secondary write counts */
+ MNT_ILOCK(mp);
secondary_writes = mp->mnt_secondary_writes;
secondary_accwrites = mp->mnt_secondary_accwrites;
+ MNT_IUNLOCK(mp);
/* Grab snapshot of softdep dependency counts */
- MNT_IUNLOCK(mp);
softdep_get_depcounts(mp, &softdep_deps, &softdep_accdeps);
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH(vp, mp, mvp) {
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
/*
* Depend on the vnode interlock to keep things stable enough
* for a quick test. Since there might be hundreds of
* thousands of vnodes, we cannot afford even a subroutine
* call unless there's a good chance that we have work to do.
*/
- VI_LOCK(vp);
- if (vp->v_iflag & VI_DOOMED) {
+ if (vp->v_type == VNON) {
VI_UNLOCK(vp);
continue;
}
ip = VTOI(vp);
- if (vp->v_type == VNON || ((ip->i_flag &
+ if ((ip->i_flag &
(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
- vp->v_bufobj.bo_dirty.bv_cnt == 0)) {
+ vp->v_bufobj.bo_dirty.bv_cnt == 0) {
VI_UNLOCK(vp);
continue;
}
- MNT_IUNLOCK(mp);
if ((error = vget(vp, lockreq, td)) != 0) {
- MNT_ILOCK(mp);
if (error == ENOENT || error == ENOLCK) {
- MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
goto loop;
}
continue;
@@ -1580,9 +1560,7 @@ loop:
if ((error = ffs_syncvnode(vp, waitfor, 0)) != 0)
allerror = error;
vput(vp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
/*
* Force stale filesystem control information to be flushed.
*/
@@ -1590,10 +1568,8 @@ loop:
if ((error = softdep_flushworklist(ump->um_mountp, &count, td)))
allerror = error;
/* Flushed work items may create new vnodes to clean */
- if (allerror == 0 && count) {
- MNT_ILOCK(mp);
+ if (allerror == 0 && count)
goto loop;
- }
}
#ifdef QUOTA
qsync(mp);
@@ -1608,18 +1584,18 @@ loop:
if ((error = VOP_FSYNC(devvp, waitfor, td)) != 0)
allerror = error;
VOP_UNLOCK(devvp, 0);
- if (allerror == 0 && waitfor == MNT_WAIT) {
- MNT_ILOCK(mp);
+ if (allerror == 0 && waitfor == MNT_WAIT)
goto loop;
- }
} else if (suspend != 0) {
if (softdep_check_suspend(mp,
devvp,
softdep_deps,
softdep_accdeps,
secondary_writes,
- secondary_accwrites) != 0)
+ secondary_accwrites) != 0) {
+ MNT_IUNLOCK(mp);
goto loop; /* More work needed */
+ }
mtx_assert(MNT_MTX(mp), MA_OWNED);
mp->mnt_kern_flag |= MNTK_SUSPEND2 | MNTK_SUSPENDED;
MNT_IUNLOCK(mp);
diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c
index c98662a..30c28c4e 100644
--- a/sys/ufs/ufs/ufs_quota.c
+++ b/sys/ufs/ufs/ufs_quota.c
@@ -598,32 +598,25 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname)
* adding references to quota file being opened.
* NB: only need to add dquot's for inodes being modified.
*/
- MNT_ILOCK(mp);
again:
- MNT_VNODE_FOREACH(vp, mp, mvp) {
- VI_LOCK(vp);
- MNT_IUNLOCK(mp);
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
goto again;
}
if (vp->v_type == VNON || vp->v_writecount == 0) {
VOP_UNLOCK(vp, 0);
vrele(vp);
- MNT_ILOCK(mp);
continue;
}
error = getinoquota(VTOI(vp));
VOP_UNLOCK(vp, 0);
vrele(vp);
- MNT_ILOCK(mp);
if (error) {
- MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
break;
}
}
- MNT_IUNLOCK(mp);
if (error)
quotaoff_inchange(td, mp, type);
@@ -669,19 +662,14 @@ quotaoff1(struct thread *td, struct mount *mp, int type)
* Search vnodes associated with this mount point,
* deleting any references to quota file being closed.
*/
- MNT_ILOCK(mp);
again:
- MNT_VNODE_FOREACH(vp, mp, mvp) {
- VI_LOCK(vp);
- MNT_IUNLOCK(mp);
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
if (vp->v_type == VNON) {
VI_UNLOCK(vp);
- MNT_ILOCK(mp);
continue;
}
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
- MNT_ILOCK(mp);
- MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
goto again;
}
ip = VTOI(vp);
@@ -690,9 +678,7 @@ again:
dqrele(vp, dq);
VOP_UNLOCK(vp, 0);
vrele(vp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
dqflush(qvp);
/* Clear um_quotas before closing the quota vnode to prevent
@@ -1057,20 +1043,16 @@ qsync(struct mount *mp)
* Search vnodes associated with this mount point,
* synchronizing any modified dquot structures.
*/
- MNT_ILOCK(mp);
again:
- MNT_VNODE_FOREACH(vp, mp, mvp) {
- VI_LOCK(vp);
+ MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
if (vp->v_type == VNON) {
VI_UNLOCK(vp);
continue;
}
- MNT_IUNLOCK(mp);
error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td);
if (error) {
- MNT_ILOCK(mp);
if (error == ENOENT) {
- MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
+ MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
goto again;
}
continue;
@@ -1081,9 +1063,7 @@ again:
dqsync(vp, dq);
}
vput(vp);
- MNT_ILOCK(mp);
}
- MNT_IUNLOCK(mp);
return (0);
}
OpenPOWER on IntegriCloud