diff options
-rw-r--r-- | sys/ufs/ffs/ffs_inode.c | 2 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_softdep.c | 13 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vfsops.c | 10 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vnops.c | 10 |
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)); } |