summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ffs/ffs_vfsops.c
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2013-04-06 22:21:23 +0000
committerjeff <jeff@FreeBSD.org>2013-04-06 22:21:23 +0000
commitfa887dba7b511d88568bd53f128474c5635f9264 (patch)
treef92f1ee66b920b82d9dc8a70d926782646206139 /sys/ufs/ffs/ffs_vfsops.c
parent440815b543293719279de0cbf109c7ab03f7caa0 (diff)
downloadFreeBSD-src-fa887dba7b511d88568bd53f128474c5635f9264.zip
FreeBSD-src-fa887dba7b511d88568bd53f128474c5635f9264.tar.gz
Prepare to replace the buf splay with a trie:
- Don't insert BKGRDMARKER bufs into the splay or dirty/clean buf lists. No consumers need to find them there and it complicates the tree. These flags are all FFS specific and could be moved out of the buf cache. - Use pbgetvp() and pbrelvp() to associate the background and journal bufs with the vp. Not only is this much cheaper it makes more sense for these transient bufs. - Fix the assertions in pbget* and pbrel*. It's not safe to check list pointers which were never initialized. Use the BX flags instead. We also check B_PAGING in reassignbuf() so this should cover all cases. Discussed with: kib, mckusick, attilio Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'sys/ufs/ffs/ffs_vfsops.c')
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c28
1 files changed, 8 insertions, 20 deletions
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 8710862..d4c035f 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -2000,12 +2000,11 @@ ffs_backgroundwritedone(struct buf *bp)
BO_LOCK(bufobj);
if ((origbp = gbincore(bp->b_bufobj, bp->b_lblkno)) == NULL)
panic("backgroundwritedone: lost buffer");
- /* Grab an extra reference to be dropped by the bufdone() below. */
- bufobj_wrefl(bufobj);
BO_UNLOCK(bufobj);
/*
* Process dependencies then return any unfinished ones.
*/
+ pbrelvp(bp);
if (!LIST_EMPTY(&bp->b_dep))
buf_complete(bp);
#ifdef SOFTUPDATES
@@ -2051,8 +2050,8 @@ ffs_backgroundwritedone(struct buf *bp)
static int
ffs_bufwrite(struct buf *bp)
{
- int oldflags, s;
struct buf *newbp;
+ int oldflags;
CTR3(KTR_BUF, "bufwrite(%p) vp %p flags %X", bp, bp->b_vp, bp->b_flags);
if (bp->b_flags & B_INVAL) {
@@ -2064,7 +2063,6 @@ ffs_bufwrite(struct buf *bp)
if (!BUF_ISLOCKED(bp))
panic("bufwrite: buffer is not busy???");
- s = splbio();
/*
* If a background write is already in progress, delay
* writing this block if it is asynchronous. Otherwise
@@ -2074,7 +2072,6 @@ ffs_bufwrite(struct buf *bp)
if (bp->b_vflags & BV_BKGRDINPROG) {
if (bp->b_flags & B_ASYNC) {
BO_UNLOCK(bp->b_bufobj);
- splx(s);
bdwrite(bp);
return (0);
}
@@ -2105,25 +2102,19 @@ ffs_bufwrite(struct buf *bp)
if (newbp == NULL)
goto normal_write;
- /*
- * set it to be identical to the old block. We have to
- * set b_lblkno and BKGRDMARKER before calling bgetvp()
- * to avoid confusing the splay tree and gbincore().
- */
KASSERT((bp->b_flags & B_UNMAPPED) == 0, ("Unmapped cg"));
memcpy(newbp->b_data, bp->b_data, bp->b_bufsize);
- newbp->b_lblkno = bp->b_lblkno;
- newbp->b_xflags |= BX_BKGRDMARKER;
BO_LOCK(bp->b_bufobj);
bp->b_vflags |= BV_BKGRDINPROG;
- bgetvp(bp->b_vp, newbp);
BO_UNLOCK(bp->b_bufobj);
- newbp->b_bufobj = &bp->b_vp->v_bufobj;
+ newbp->b_xflags |= BX_BKGRDMARKER;
+ newbp->b_lblkno = bp->b_lblkno;
newbp->b_blkno = bp->b_blkno;
newbp->b_offset = bp->b_offset;
newbp->b_iodone = ffs_backgroundwritedone;
newbp->b_flags |= B_ASYNC;
newbp->b_flags &= ~B_INVAL;
+ pbgetvp(bp->b_vp, newbp);
#ifdef SOFTUPDATES
/*
@@ -2139,12 +2130,9 @@ ffs_bufwrite(struct buf *bp)
#endif
/*
- * Initiate write on the copy, release the original to
- * the B_LOCKED queue so that it cannot go away until
- * the background write completes. If not locked it could go
- * away and then be reconstituted while it was being written.
- * If the reconstituted buffer were written, we could end up
- * with two background copies being written at the same time.
+ * Initiate write on the copy, release the original. The
+ * BKGRDINPROG flag prevents it from going away until
+ * the background write completes.
*/
bqrelse(bp);
bp = newbp;
OpenPOWER on IntegriCloud