diff options
author | phk <phk@FreeBSD.org> | 2004-10-21 15:53:54 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2004-10-21 15:53:54 +0000 |
commit | 3833976d1250bf118a46939f409012d87e558de6 (patch) | |
tree | 9d355bca75100170618443d740a1312fd842af5d /sys/kern/vfs_bio.c | |
parent | fdf614c0bad1564664cac5105be08477d1bcdd72 (diff) | |
download | FreeBSD-src-3833976d1250bf118a46939f409012d87e558de6.zip FreeBSD-src-3833976d1250bf118a46939f409012d87e558de6.tar.gz |
Move the VI_BWAIT flag into no bo_flag element of bufobj and call it BO_WWAIT
Add bufobj_wref(), bufobj_wdrop() and bufobj_wwait() to handle the write
count on a bufobj. Bufobj_wdrop() replaces vwakeup().
Use these functions all relevant places except in ffs_softdep.c where
the use if interlocked_sleep() makes this impossible.
Rename b_vnbufs to b_bobufs now that we touch all the relevant files anyway.
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r-- | sys/kern/vfs_bio.c | 74 |
1 files changed, 66 insertions, 8 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 5d4f170..170cffb 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -880,9 +880,7 @@ ibwrite(struct buf *bp) bp->b_flags |= B_CACHE; bp->b_iocmd = BIO_WRITE; - VI_LOCK(bp->b_vp); - bp->b_vp->v_numoutput++; - VI_UNLOCK(bp->b_vp); + bufobj_wref(&bp->b_vp->v_bufobj); vfs_busy_pages(bp, 1); /* @@ -965,7 +963,7 @@ vfs_backgroundwritedone(struct buf *bp) /* * This buffer is marked B_NOCACHE, so when it is released * by biodone, it will be tossed. We mark it with BIO_READ - * to avoid biodone doing a second vwakeup. + * to avoid biodone doing a second bufobj_wakeup. */ bp->b_flags |= B_NOCACHE; bp->b_iocmd = BIO_READ; @@ -1020,7 +1018,7 @@ bdwrite(struct buf *bp) /* * Try to find a buffer to flush. */ - TAILQ_FOREACH(nbp, &vp->v_dirtyblkhd, b_vnbufs) { + TAILQ_FOREACH(nbp, &vp->v_dirtyblkhd, b_bobufs) { if ((nbp->b_vflags & BV_BKGRDINPROG) || buf_countdeps(nbp, 0) || BUF_LOCK(nbp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) @@ -3155,9 +3153,8 @@ bufdone(struct buf *bp) bp->b_flags |= B_DONE; runningbufwakeup(bp); - if (bp->b_iocmd == BIO_WRITE) { - vwakeup(bp); - } + if (bp->b_iocmd == BIO_WRITE && bp->b_vp != NULL) + bufobj_wdrop(&bp->b_vp->v_bufobj); /* call optional completion function if requested */ if (bp->b_iodone != NULL) { @@ -3795,6 +3792,67 @@ bwait(struct buf *bp, u_char pri, const char *wchan) mtx_unlock(&bdonelock); } +#if 0 /* this is here to unconfuse p4 diff */ + +void +bufstrategy(struct bufobj *bo, struct buf *bp) +{ + int i = 0; + struct vnode *vp; + + vp = bp->b_vp; + KASSERT(vp == bo->bo_vnode, ("Inconsistent vnode bufstrategy")); + KASSERT(vp->v_type != VCHR && vp->v_type != VBLK, + ("Wrong vnode in bufstrategy(bp=%p, vp=%p)", bp, vp)); + i = VOP_STRATEGY(vp, bp); + KASSERT(i == 0, ("VOP_STRATEGY failed bp=%p vp=%p", bp, bp->b_vp)); +} + +#endif + +void +bufobj_wref(struct bufobj *bo) +{ + + KASSERT(bo != NULL, ("NULL bo in bufobj_wref")); + BO_LOCK(bo); + bo->bo_numoutput++; + BO_UNLOCK(bo); +} + +void +bufobj_wdrop(struct bufobj *bo) +{ + + KASSERT(bo != NULL, ("NULL bo in bufobj_wdrop")); + BO_LOCK(bo); + KASSERT(bo->bo_numoutput > 0, ("bufobj_wdrop non-positive count")); + if ((--bo->bo_numoutput == 0) && (bo->bo_flag & BO_WWAIT)) { + bo->bo_flag &= ~BO_WWAIT; + wakeup(&bo->bo_numoutput); + } + BO_UNLOCK(bo); +} + +int +bufobj_wwait(struct bufobj *bo, int slpflag, int timeo) +{ + int error; + + KASSERT(bo != NULL, ("NULL bo in bufobj_wwait")); + ASSERT_BO_LOCKED(bo); + error = 0; + while (bo->bo_numoutput) { + bo->bo_flag |= BO_WWAIT; + error = msleep(&bo->bo_numoutput, BO_MTX(bo), + slpflag | (PRIBIO + 1), "bo_wwait", timeo); + if (error) + break; + } + return (error); +} + + #include "opt_ddb.h" #ifdef DDB #include <ddb/ddb.h> |