diff options
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ffs/ffs_inode.c | 9 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_rawread.c | 27 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_softdep.c | 134 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vfsops.c | 7 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vnops.c | 26 |
5 files changed, 99 insertions, 104 deletions
diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c index a6929f0..0a9bc9d 100644 --- a/sys/ufs/ffs/ffs_inode.c +++ b/sys/ufs/ffs/ffs_inode.c @@ -147,6 +147,7 @@ ffs_truncate(vp, length, flags, cred, td) ufs2_daddr_t bn, lbn, lastblock, lastiblock[NIADDR], indir_lbn[NIADDR]; ufs2_daddr_t oldblks[NDADDR + NIADDR], newblks[NDADDR + NIADDR]; ufs2_daddr_t count, blocksreleased = 0, datablocks; + struct bufobj *bo; struct fs *fs; struct buf *bp; struct ufsmount *ump; @@ -158,6 +159,7 @@ ffs_truncate(vp, length, flags, cred, td) ip = VTOI(vp); fs = ip->i_fs; ump = ip->i_ump; + bo = &vp->v_bufobj; ASSERT_VOP_LOCKED(vp, "ffs_truncate"); @@ -486,13 +488,12 @@ done: for (i = 0; i < NDADDR; i++) if (newblks[i] != DIP(ip, i_db[i])) panic("ffs_truncate2"); - VI_LOCK(vp); + BO_LOCK(bo); if (length == 0 && (fs->fs_magic != FS_UFS2_MAGIC || ip->i_din2->di_extsize == 0) && - (vp->v_bufobj.bo_dirty.bv_cnt > 0 || - vp->v_bufobj.bo_clean.bv_cnt > 0)) + (bo->bo_dirty.bv_cnt > 0 || bo->bo_clean.bv_cnt > 0)) panic("ffs_truncate3"); - VI_UNLOCK(vp); + BO_UNLOCK(bo); #endif /* INVARIANTS */ /* * Put back the real size. diff --git a/sys/ufs/ffs/ffs_rawread.c b/sys/ufs/ffs/ffs_rawread.c index f10e432..434c833 100644 --- a/sys/ufs/ffs/ffs_rawread.c +++ b/sys/ufs/ffs/ffs_rawread.c @@ -97,21 +97,20 @@ ffs_rawread_setup(void) static int ffs_rawread_sync(struct vnode *vp) { - int spl; int error; int upgraded; struct bufobj *bo; struct mount *mp; /* Check for dirty mmap, pending writes and dirty buffers */ - spl = splbio(); - VI_LOCK(vp); bo = &vp->v_bufobj; + BO_LOCK(bo); + VI_LOCK(vp); if (bo->bo_numoutput > 0 || bo->bo_dirty.bv_cnt > 0 || (vp->v_iflag & VI_OBJDIRTY) != 0) { - splx(spl); VI_UNLOCK(vp); + BO_UNLOCK(bo); if (vn_start_write(vp, &mp, V_NOWAIT) != 0) { if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) @@ -146,16 +145,15 @@ ffs_rawread_sync(struct vnode *vp) vm_object_page_clean(vp->v_object, 0, 0, OBJPC_SYNC); VM_OBJECT_UNLOCK(vp->v_object); } - VI_LOCK(vp); - } + } else + VI_UNLOCK(vp); /* Wait for pending writes to complete */ - spl = splbio(); + BO_LOCK(bo); error = bufobj_wwait(&vp->v_bufobj, 0, 0); if (error != 0) { /* XXX: can't happen with a zero timeout ??? */ - splx(spl); - VI_UNLOCK(vp); + BO_UNLOCK(bo); if (upgraded != 0) VOP_LOCK(vp, LK_DOWNGRADE); vn_finished_write(mp); @@ -163,27 +161,24 @@ ffs_rawread_sync(struct vnode *vp) } /* Flush dirty buffers */ if (bo->bo_dirty.bv_cnt > 0) { - splx(spl); - VI_UNLOCK(vp); + BO_UNLOCK(bo); if ((error = ffs_syncvnode(vp, MNT_WAIT)) != 0) { if (upgraded != 0) VOP_LOCK(vp, LK_DOWNGRADE); vn_finished_write(mp); return (error); } - VI_LOCK(vp); - spl = splbio(); + BO_LOCK(bo); if (bo->bo_numoutput > 0 || bo->bo_dirty.bv_cnt > 0) panic("ffs_rawread_sync: dirty bufs"); } - splx(spl); - VI_UNLOCK(vp); + BO_UNLOCK(bo); if (upgraded != 0) VOP_LOCK(vp, LK_DOWNGRADE); vn_finished_write(mp); } else { - splx(spl); VI_UNLOCK(vp); + BO_UNLOCK(bo); } return 0; } diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 41a6df8..7cb7b40 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -357,26 +357,16 @@ softdep_check_suspend(struct mount *mp, (void) softdep_deps, (void) softdep_accdeps; - ASSERT_VI_LOCKED(devvp, "softdep_check_suspend"); bo = &devvp->v_bufobj; + ASSERT_BO_LOCKED(bo); - for (;;) { - if (!MNT_ITRYLOCK(mp)) { - VI_UNLOCK(devvp); - MNT_ILOCK(mp); - MNT_IUNLOCK(mp); - VI_LOCK(devvp); - continue; - } - if (mp->mnt_secondary_writes != 0) { - VI_UNLOCK(devvp); - msleep(&mp->mnt_secondary_writes, - MNT_MTX(mp), - (PUSER - 1) | PDROP, "secwr", 0); - VI_LOCK(devvp); - continue; - } - break; + MNT_ILOCK(mp); + while (mp->mnt_secondary_writes != 0) { + BO_UNLOCK(bo); + msleep(&mp->mnt_secondary_writes, MNT_MTX(mp), + (PUSER - 1) | PDROP, "secwr", 0); + BO_LOCK(bo); + MNT_ILOCK(mp); } /* @@ -391,7 +381,7 @@ softdep_check_suspend(struct mount *mp, mp->mnt_secondary_writes != 0 || secondary_accwrites != mp->mnt_secondary_accwrites) error = EAGAIN; - VI_UNLOCK(devvp); + BO_UNLOCK(bo); return (error); } @@ -2189,6 +2179,7 @@ softdep_setup_freeblocks(ip, length, flags) struct freeblks *freeblks; struct inodedep *inodedep; struct allocdirect *adp; + struct bufobj *bo; struct vnode *vp; struct buf *bp; struct fs *fs; @@ -2314,27 +2305,28 @@ softdep_setup_freeblocks(ip, length, flags) * any dependencies. */ vp = ITOV(ip); - VI_LOCK(vp); + bo = &vp->v_bufobj; + BO_LOCK(bo); drain_output(vp); restart: - TAILQ_FOREACH(bp, &vp->v_bufobj.bo_dirty.bv_hd, b_bobufs) { + TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) { if (((flags & IO_EXT) == 0 && (bp->b_xflags & BX_ALTDATA)) || ((flags & IO_NORMAL) == 0 && (bp->b_xflags & BX_ALTDATA) == 0)) continue; - if ((bp = getdirtybuf(bp, VI_MTX(vp), MNT_WAIT)) == NULL) + if ((bp = getdirtybuf(bp, BO_MTX(bo), MNT_WAIT)) == NULL) goto restart; - VI_UNLOCK(vp); + BO_UNLOCK(bo); ACQUIRE_LOCK(&lk); (void) inodedep_lookup(mp, ip->i_number, 0, &inodedep); deallocate_dependencies(bp, inodedep); FREE_LOCK(&lk); bp->b_flags |= B_INVAL | B_NOCACHE; brelse(bp); - VI_LOCK(vp); + BO_LOCK(bo); goto restart; } - VI_UNLOCK(vp); + BO_UNLOCK(bo); ACQUIRE_LOCK(&lk); if (inodedep_lookup(mp, ip->i_number, 0, &inodedep) != 0) (void) free_inodedep(inodedep); @@ -5159,13 +5151,15 @@ softdep_fsync_mountdev(vp) { struct buf *bp, *nbp; struct worklist *wk; + struct bufobj *bo; if (!vn_isdisk(vp, NULL)) panic("softdep_fsync_mountdev: vnode not a disk"); + bo = &vp->v_bufobj; restart: + BO_LOCK(bo); ACQUIRE_LOCK(&lk); - VI_LOCK(vp); - TAILQ_FOREACH_SAFE(bp, &vp->v_bufobj.bo_dirty.bv_hd, b_bobufs, nbp) { + TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { /* * If it is already scheduled, skip to the next buffer. */ @@ -5184,15 +5178,15 @@ restart: BUF_UNLOCK(bp); continue; } - VI_UNLOCK(vp); FREE_LOCK(&lk); + BO_UNLOCK(bo); bremfree(bp); (void) bawrite(bp); goto restart; } FREE_LOCK(&lk); drain_output(vp); - VI_UNLOCK(vp); + BO_UNLOCK(bo); } /* @@ -5209,6 +5203,7 @@ softdep_sync_metadata(struct vnode *vp) struct allocindir *aip; struct buf *bp, *nbp; struct worklist *wk; + struct bufobj *bo; int i, error, waitfor; if (!DOINGSOFTDEP(vp)) @@ -5240,20 +5235,21 @@ softdep_sync_metadata(struct vnode *vp) * resolved. Thus the second pass is expected to end quickly. */ waitfor = MNT_NOWAIT; + bo = &vp->v_bufobj; top: /* * We must wait for any I/O in progress to finish so that * all potential buffers on the dirty list will be visible. */ - VI_LOCK(vp); + BO_LOCK(bo); drain_output(vp); - while ((bp = TAILQ_FIRST(&vp->v_bufobj.bo_dirty.bv_hd)) != NULL) { - bp = getdirtybuf(bp, VI_MTX(vp), MNT_WAIT); + while ((bp = TAILQ_FIRST(&bo->bo_dirty.bv_hd)) != NULL) { + bp = getdirtybuf(bp, BO_MTX(bo), MNT_WAIT); if (bp) break; } - VI_UNLOCK(vp); + BO_UNLOCK(bo); if (bp == NULL) return (0); loop: @@ -5405,13 +5401,13 @@ loop: return (error); } FREE_LOCK(&lk); - VI_LOCK(vp); + BO_LOCK(bo); while ((nbp = TAILQ_NEXT(bp, b_bobufs)) != NULL) { - nbp = getdirtybuf(nbp, VI_MTX(vp), MNT_WAIT); + nbp = getdirtybuf(nbp, BO_MTX(bo), MNT_WAIT); if (nbp) break; } - VI_UNLOCK(vp); + BO_UNLOCK(bo); BUF_NOREC(bp); bawrite(bp); if (nbp != NULL) { @@ -5435,9 +5431,9 @@ loop: * We must wait for any I/O in progress to finish so that * all potential buffers on the dirty list will be visible. */ - VI_LOCK(vp); + BO_LOCK(bo); drain_output(vp); - VI_UNLOCK(vp); + BO_UNLOCK(bo); return (0); } @@ -5544,6 +5540,7 @@ flush_pagedep_deps(pvp, mp, diraddhdp) struct ufsmount *ump; struct diradd *dap; struct vnode *vp; + struct bufobj *bo; int error = 0; struct buf *bp; ino_t inum; @@ -5590,7 +5587,8 @@ flush_pagedep_deps(pvp, mp, diraddhdp) vput(vp); break; } - VI_LOCK(vp); + bo = &vp->v_bufobj; + BO_LOCK(bo); drain_output(vp); /* * If first block is still dirty with a D_MKDIR @@ -5598,15 +5596,15 @@ flush_pagedep_deps(pvp, mp, diraddhdp) */ for (;;) { error = 0; - bp = gbincore(&vp->v_bufobj, 0); + bp = gbincore(bo, 0); if (bp == NULL) break; /* First block not present */ error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, - VI_MTX(vp)); - VI_LOCK(vp); + BO_MTX(bo)); + BO_LOCK(bo); if (error == ENOLCK) continue; /* Slept, retry */ if (error != 0) @@ -5628,14 +5626,14 @@ flush_pagedep_deps(pvp, mp, diraddhdp) * must write buffer to stable * storage. */ - VI_UNLOCK(vp); + BO_UNLOCK(bo); bremfree(bp); error = bwrite(bp); - VI_LOCK(vp); + BO_LOCK(bo); } break; } - VI_UNLOCK(vp); + BO_UNLOCK(bo); vput(vp); if (error != 0) break; /* Flushing of first block failed */ @@ -5904,6 +5902,7 @@ clear_remove(td) static int next = 0; struct mount *mp; struct vnode *vp; + struct bufobj *bo; int error, cnt; ino_t ino; @@ -5929,9 +5928,10 @@ clear_remove(td) } if ((error = ffs_syncvnode(vp, MNT_NOWAIT))) softdep_error("clear_remove: fsync", error); - VI_LOCK(vp); + bo = &vp->v_bufobj; + BO_LOCK(bo); drain_output(vp); - VI_UNLOCK(vp); + BO_UNLOCK(bo); vput(vp); vn_finished_write(mp); ACQUIRE_LOCK(&lk); @@ -6004,9 +6004,9 @@ clear_inodedeps(td) } else { if ((error = ffs_syncvnode(vp, MNT_NOWAIT))) softdep_error("clear_inodedeps: fsync2", error); - VI_LOCK(vp); + BO_LOCK(&vp->v_bufobj); drain_output(vp); - VI_UNLOCK(vp); + BO_UNLOCK(&vp->v_bufobj); } vput(vp); vn_finished_write(mp); @@ -6154,7 +6154,7 @@ getdirtybuf(bp, mtx, waitfor) */ #ifdef DEBUG_VFS_LOCKS if (bp->b_vp->v_type != VCHR) - ASSERT_VI_LOCKED(bp->b_vp, "getdirtybuf"); + ASSERT_BO_LOCKED(bp->b_bufobj); #endif bp->b_vflags |= BV_BKGRDWAIT; msleep(&bp->b_xflags, mtx, PRIBIO, "getbuf", 0); @@ -6187,33 +6187,26 @@ softdep_check_suspend(struct mount *mp, struct ufsmount *ump; int error; - ASSERT_VI_LOCKED(devvp, "softdep_check_suspend"); ump = VFSTOUFS(mp); bo = &devvp->v_bufobj; + ASSERT_BO_LOCKED(bo); for (;;) { if (!TRY_ACQUIRE_LOCK(&lk)) { - VI_UNLOCK(devvp); + BO_UNLOCK(bo); ACQUIRE_LOCK(&lk); FREE_LOCK(&lk); - VI_LOCK(devvp); - continue; - } - if (!MNT_ITRYLOCK(mp)) { - FREE_LOCK(&lk); - VI_UNLOCK(devvp); - MNT_ILOCK(mp); - MNT_IUNLOCK(mp); - VI_LOCK(devvp); + BO_LOCK(bo); continue; } + MNT_ILOCK(mp); if (mp->mnt_secondary_writes != 0) { FREE_LOCK(&lk); - VI_UNLOCK(devvp); + BO_UNLOCK(bo); msleep(&mp->mnt_secondary_writes, MNT_MTX(mp), (PUSER - 1) | PDROP, "secwr", 0); - VI_LOCK(devvp); + BO_LOCK(bo); continue; } break; @@ -6236,7 +6229,7 @@ softdep_check_suspend(struct mount *mp, secondary_accwrites != mp->mnt_secondary_accwrites) error = EAGAIN; FREE_LOCK(&lk); - VI_UNLOCK(devvp); + BO_UNLOCK(bo); return (error); } @@ -6270,13 +6263,16 @@ static void drain_output(vp) struct vnode *vp; { + struct bufobj *bo; + + bo = &vp->v_bufobj; ASSERT_VOP_LOCKED(vp, "drain_output"); - ASSERT_VI_LOCKED(vp, "drain_output"); + ASSERT_BO_LOCKED(bo); - while (vp->v_bufobj.bo_numoutput) { - vp->v_bufobj.bo_flag |= BO_WWAIT; - msleep((caddr_t)&vp->v_bufobj.bo_numoutput, - VI_MTX(vp), PRIBIO + 1, "drainvp", 0); + while (bo->bo_numoutput) { + bo->bo_flag |= BO_WWAIT; + msleep((caddr_t)&bo->bo_numoutput, + BO_MTX(bo), PRIBIO + 1, "drainvp", 0); } } diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 6a1dce3..cc13410 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -1267,11 +1267,12 @@ loop: qsync(mp); #endif devvp = ump->um_devvp; - VI_LOCK(devvp); bo = &devvp->v_bufobj; + BO_LOCK(bo); if (waitfor != MNT_LAZY && (bo->bo_numoutput > 0 || bo->bo_dirty.bv_cnt > 0)) { - vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY | LK_INTERLOCK); + BO_UNLOCK(bo); + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); if ((error = VOP_FSYNC(devvp, waitfor, td)) != 0) allerror = error; VOP_UNLOCK(devvp, 0); @@ -1292,7 +1293,7 @@ loop: MNT_IUNLOCK(mp); suspended = 1; } else - VI_UNLOCK(devvp); + BO_UNLOCK(bo); /* * Write back modified superblock. */ diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 7968662..dca262c 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -195,6 +195,7 @@ int ffs_syncvnode(struct vnode *vp, int waitfor) { struct inode *ip = VTOI(vp); + struct bufobj *bo; struct buf *bp; struct buf *nbp; int s, error, wait, passes, skipmeta; @@ -202,6 +203,7 @@ ffs_syncvnode(struct vnode *vp, int waitfor) wait = (waitfor == MNT_WAIT); lbn = lblkno(ip->i_fs, (ip->i_size + ip->i_fs->fs_bsize - 1)); + bo = &vp->v_bufobj; /* * Flush all dirty buffers associated with a vnode. @@ -211,11 +213,11 @@ ffs_syncvnode(struct vnode *vp, int waitfor) if (wait) skipmeta = 1; s = splbio(); - VI_LOCK(vp); + BO_LOCK(bo); loop: - TAILQ_FOREACH(bp, &vp->v_bufobj.bo_dirty.bv_hd, b_bobufs) + TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) bp->b_vflags &= ~BV_SCANNED; - TAILQ_FOREACH_SAFE(bp, &vp->v_bufobj.bo_dirty.bv_hd, b_bobufs, nbp) { + TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { /* * Reasons to skip this buffer: it has already been considered * on this pass, this pass is the first time through on a @@ -231,13 +233,13 @@ loop: continue; if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) continue; - VI_UNLOCK(vp); + BO_UNLOCK(bo); if (!wait && !LIST_EMPTY(&bp->b_dep) && (bp->b_flags & B_DEFERRED) == 0 && buf_countdeps(bp, 0)) { bp->b_flags |= B_DEFERRED; BUF_UNLOCK(bp); - VI_LOCK(vp); + BO_LOCK(bo); continue; } if ((bp->b_flags & B_DELWRI) == 0) @@ -286,8 +288,8 @@ 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_bufobj.bo_dirty.bv_hd); + BO_LOCK(bo); + nbp = TAILQ_FIRST(&bo->bo_dirty.bv_hd); } /* * If we were asked to do this synchronously, then go back for @@ -299,8 +301,8 @@ loop: } if (wait) { - bufobj_wwait(&vp->v_bufobj, 3, 0); - VI_UNLOCK(vp); + bufobj_wwait(bo, 3, 0); + BO_UNLOCK(bo); /* * Ensure that any filesystem metatdata associated @@ -311,8 +313,8 @@ loop: return (error); s = splbio(); - VI_LOCK(vp); - if (vp->v_bufobj.bo_dirty.bv_cnt > 0) { + BO_LOCK(bo); + if (bo->bo_dirty.bv_cnt > 0) { /* * Block devices associated with filesystems may * have new I/O requests posted for them even if @@ -331,7 +333,7 @@ loop: #endif } } - VI_UNLOCK(vp); + BO_UNLOCK(bo); splx(s); return (ffs_update(vp, wait)); } |