summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/ufs/ffs/ffs_inode.c2
-rw-r--r--sys/ufs/ffs/ffs_softdep.c13
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c10
-rw-r--r--sys/ufs/ffs/ffs_vnops.c10
4 files changed, 28 insertions, 7 deletions
diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c
index 61396a0..79586a8 100644
--- a/sys/ufs/ffs/ffs_inode.c
+++ b/sys/ufs/ffs/ffs_inode.c
@@ -478,11 +478,13 @@ done:
for (i = 0; i < NDADDR; i++)
if (newblks[i] != DIP(oip, i_db[i]))
panic("ffs_truncate2");
+ VI_LOCK(ovp);
if (length == 0 &&
(fs->fs_magic != FS_UFS2_MAGIC || oip->i_din2->di_extsize == 0) &&
(!TAILQ_EMPTY(&ovp->v_dirtyblkhd) ||
!TAILQ_EMPTY(&ovp->v_cleanblkhd)))
panic("ffs_truncate3");
+ VI_UNLOCK(ovp);
#endif /* DIAGNOSTIC */
/*
* Put back the real size.
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 1f99ccc..3c60df5 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -2047,11 +2047,13 @@ softdep_setup_freeblocks(ip, length, flags)
ACQUIRE_LOCK(&lk);
drain_output(vp, 1);
restart:
+ VI_LOCK(vp);
TAILQ_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs) {
if (((flags & IO_EXT) == 0 && (bp->b_xflags & BX_ALTDATA)) ||
((flags & IO_NORMAL) == 0 &&
(bp->b_xflags & BX_ALTDATA) == 0))
continue;
+ VI_UNLOCK(vp);
if (getdirtybuf(&bp, MNT_WAIT) == 0)
goto restart;
(void) inodedep_lookup(fs, ip->i_number, 0, &inodedep);
@@ -2062,6 +2064,7 @@ restart:
ACQUIRE_LOCK(&lk);
goto restart;
}
+ VI_UNLOCK(vp);
if (inodedep_lookup(fs, ip->i_number, 0, &inodedep) != 0)
(void) free_inodedep(inodedep);
FREE_LOCK(&lk);
@@ -4857,13 +4860,17 @@ softdep_fsync_mountdev(vp)
if (!vn_isdisk(vp, NULL))
panic("softdep_fsync_mountdev: vnode not a disk");
ACQUIRE_LOCK(&lk);
+ VI_LOCK(vp);
for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
nbp = TAILQ_NEXT(bp, b_vnbufs);
+ VI_UNLOCK(vp);
/*
* If it is already scheduled, skip to the next buffer.
*/
- if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT))
+ if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) {
+ VI_LOCK(vp);
continue;
+ }
if ((bp->b_flags & B_DELWRI) == 0) {
FREE_LOCK(&lk);
panic("softdep_fsync_mountdev: not dirty");
@@ -4876,6 +4883,7 @@ softdep_fsync_mountdev(vp)
wk->wk_type != D_BMSAFEMAP ||
(bp->b_xflags & BX_BKGRDINPROG)) {
BUF_UNLOCK(bp);
+ VI_LOCK(vp);
continue;
}
bremfree(bp);
@@ -4886,8 +4894,10 @@ softdep_fsync_mountdev(vp)
* Since we may have slept during the I/O, we need
* to start from a known point.
*/
+ VI_LOCK(vp);
nbp = TAILQ_FIRST(&vp->v_dirtyblkhd);
}
+ VI_UNLOCK(vp);
drain_output(vp, 1);
FREE_LOCK(&lk);
}
@@ -4962,6 +4972,7 @@ top:
FREE_LOCK(&lk);
return (0);
}
+ mp_fixme("The locking is somewhat complicated nonexistant here.");
bp = TAILQ_FIRST(&vp->v_dirtyblkhd);
/* While syncing snapshots, we must allow recursive lookups */
bp->b_lock.lk_flags |= LK_CANRECURSE;
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 9a9069b..dfecac7 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -411,6 +411,7 @@ ffs_reload(mp, cred, td)
if (vn_isdisk(devvp, NULL)) {
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
vfs_object_create(devvp, td, td->td_ucred);
+ /* XXX Why lock only to release immediately?? */
mtx_lock(&devvp->v_interlock);
VOP_UNLOCK(devvp, LK_INTERLOCK, td);
}
@@ -495,6 +496,7 @@ loop:
/*
* Step 5: invalidate all cached file data.
*/
+ /* XXX Why lock only to release immediately? */
mtx_lock(&vp->v_interlock);
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
goto loop;
@@ -580,6 +582,7 @@ ffs_mountfs(devvp, mp, td, malloctype)
if (vn_isdisk(devvp, NULL)) {
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
vfs_object_create(devvp, td, cred);
+ /* XXX Why lock only to release immediately?? */
mtx_lock(&devvp->v_interlock);
VOP_UNLOCK(devvp, LK_INTERLOCK, td);
}
@@ -1152,11 +1155,10 @@ loop:
qsync(mp);
#endif
devvp = ump->um_devvp;
- mtx_lock(&devvp->v_interlock);
+ VI_LOCK(devvp);
if (waitfor != MNT_LAZY &&
(devvp->v_numoutput > 0 || TAILQ_FIRST(&devvp->v_dirtyblkhd))) {
- mtx_unlock(&devvp->v_interlock);
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
+ vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY | LK_INTERLOCK, td);
if ((error = VOP_FSYNC(devvp, cred, waitfor, td)) != 0)
allerror = error;
VOP_UNLOCK(devvp, 0, td);
@@ -1165,7 +1167,7 @@ loop:
goto loop;
}
} else
- mtx_unlock(&devvp->v_interlock);
+ VI_UNLOCK(devvp);
/*
* Write back modified superblock.
*/
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index 9247515..8aa0baf 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -175,6 +175,7 @@ ffs_fsync(ap)
if (wait)
skipmeta = 1;
s = splbio();
+ VI_LOCK(vp);
loop:
TAILQ_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs)
bp->b_flags &= ~B_SCANNED;
@@ -199,8 +200,11 @@ loop:
bp->b_flags |= B_DEFERRED;
continue;
}
- if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT))
+ VI_UNLOCK(vp);
+ if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) {
+ VI_LOCK(vp);
continue;
+ }
if ((bp->b_flags & B_DELWRI) == 0)
panic("ffs_fsync: not dirty");
if (vp != bp->b_vp)
@@ -251,6 +255,7 @@ loop:
* Since we may have slept during the I/O, we need
* to start from a known point.
*/
+ VI_LOCK(vp);
nbp = TAILQ_FIRST(&vp->v_dirtyblkhd);
}
/*
@@ -263,7 +268,6 @@ loop:
}
if (wait) {
- VI_LOCK(vp);
while (vp->v_numoutput) {
vp->v_iflag |= VI_BWAIT;
msleep((caddr_t)&vp->v_numoutput, VI_MTX(vp),
@@ -280,6 +284,7 @@ loop:
return (error);
s = splbio();
+ VI_LOCK(vp);
if (!TAILQ_EMPTY(&vp->v_dirtyblkhd)) {
/*
* Block devices associated with filesystems may
@@ -299,6 +304,7 @@ loop:
#endif
}
}
+ VI_UNLOCK(vp);
splx(s);
return (UFS_UPDATE(vp, wait));
}
OpenPOWER on IntegriCloud