svn commit: r199343 -
user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Kip Macy
kmacy at FreeBSD.org
Tue Nov 17 04:59:44 UTC 2009
Author: kmacy
Date: Tue Nov 17 04:59:43 2009
New Revision: 199343
URL: http://svn.freebsd.org/changeset/base/199343
Log:
only update the page cache when freeing the last buffer belonging to a buffer header
Modified:
user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
Modified: user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
==============================================================================
--- user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Tue Nov 17 03:37:24 2009 (r199342)
+++ user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Tue Nov 17 04:59:43 2009 (r199343)
@@ -1300,86 +1300,45 @@ arc_buf_add_ref(arc_buf_t *buf, void* ta
data, metadata, hits);
}
-static struct buf *
-arc_gbincore_replace(struct vnode *vp, off_t blkno, size_t size, int flags,
- struct buf *newbp)
-{
- struct buf *bp;
- struct bufobj *bo;
+static void
+arc_bgetvp(arc_buf_t *buf)
+{
+ off_t blkno = buf->b_hdr->b_dva.dva_word[1] & ~(1UL<<63);
+ struct buf *bp = buf->b_bp;
+ struct vnode *vp = spa_get_vnode(buf->b_hdr->b_spa);
+ struct bufobj *bo = &vp->v_bufobj;
+ arc_buf_hdr_t *hdr = buf->b_hdr;
- /*
- * We need to be careful to handle the case where the buffer
- * is already held in the ARC for a previous birth transaction
- */
- bo = &vp->v_bufobj;
BO_LOCK(bo);
bp = gbincore(bo, blkno);
if (bp != NULL) {
- if (bp == newbp) {
- BO_UNLOCK(bo);
- return (bp);
- }
- if (BUF_ISLOCKED(bp)) {
- /*
- * buffer is currently referenced in the ARC with older birth txg
- *
- */
+ /*
+ * XXX we have a race with getblk here
+ */
+ BUF_LOCK(bp, LK_EXCLUSIVE | LK_INTERLOCK, BO_MTX(bo));
+ bremfree(bp);
+ /*
+ * buffer is usable for this mapping
+ */
+ if (!(hdr->b_flags & ARC_IO_ERROR) &&
+ (bp->b_offset <= hdr->b_birth) &&
+ (bp->b_flags & (B_CACHE|B_INVAL)) == B_CACHE) {
bp->b_flags |= B_INVAL;
bp->b_flags &= ~B_CACHE;
- BO_UNLOCK(bo);
- brelvp(bp);
- } else {
- BUF_LOCK(bp, LK_EXCLUSIVE | LK_INTERLOCK, BO_MTX(bo));
- if (newbp != NULL) {
- /*
- * mapping exists but we wish to replace it with
- * newbp
- */
- bp->b_flags |= B_INVAL;
- bp->b_flags &= ~B_CACHE;
- bremfree(bp);
- brelse(bp);
- } else {
- /*
- * buffer is usable for this mapping
- */
- if (bp->b_flags & B_INVAL)
- bp->b_flags &= ~B_CACHE;
- else if ((bp->b_flags & (B_VMIO | B_INVAL)) == 0)
- bp->b_flags |= B_CACHE;
- bremfree(bp);
- if ((bp->b_bcount != size) && (buf->b_kvasize >= size)) {
- allocbuf_flags(bp, size, flags);
- goto done;
- } else {
- bp->b_flags |= B_INVAL;
- brelse(bp);
- }
- }
- }
- }
- /*
- * !bp brelvp(bp) brelse(bp) associated
- * !newbp unlock()/getblk getblk XXX no-op
- *
- * newbp bgetvp()/ul l/bgetvp()/ul l/bgetvp()/ul XXX
- */
- if (newbp != NULL) {
- if (bp != NULL)
+ brelse(bp);
+ buf->b_bp->b_offset = hdr->b_birth;
+ buf->b_bp->b_flags |= B_CACHE;
+ buf->b_bp->b_flags &= ~B_INVAL;
+
BO_LOCK(bo);
- bgetvp(vp, newbp);
- BO_UNLOCK(bo);
- bp = newbp;
- } else {
- if (bp == NULL)
+ bgetvp(vp, buf->b_bp);
BO_UNLOCK(bo);
- bp = getblk(vp, blkno, size, 0, 0, flags);
- }
-
-done:
- return (bp);
+ } else
+ brelse(bp);
+ } else
+ BO_UNLOCK(bo);
}
static void
@@ -1411,15 +1370,14 @@ arc_getblk(arc_buf_t *buf)
if ((size < PAGE_SIZE)) {
data = zio_buf_alloc(size);
} else if ((buf->b_hdr->b_flags & ARC_BUF_CLONING) ||
- BUF_EMPTY(buf->b_hdr) ||
- zfs_page_cache_disable) {
+ BUF_EMPTY(buf->b_hdr)) {
newbp = geteblk(size, flags);
data = newbp->b_data;
buf->b_hdr->b_flags &= ~ARC_BUF_CLONING;
} else {
- newbp = arc_gbincore_replace(vp, blkno, size, flags, NULL);
-
- newbp->b_offset = buf->b_hdr->b_birth;
+ newbp = getblk(vp, blkno, size, 0, 0, flags);
+ if (newbp->b_vp != NULL)
+ brelvp(newbp);
data = newbp->b_data;
}
@@ -1441,20 +1399,16 @@ arc_getblk(arc_buf_t *buf)
static void
arc_brelse(arc_buf_t *buf, void *data, size_t size)
{
- struct buf *bp;
+ struct buf *bp = buf->b_bp;
+ arc_buf_hdr_t *hdr = buf->b_hdr;
- bp = buf->b_bp;
if (bp == NULL) {
zio_buf_free(buf->b_data, size);
return;
}
-#ifdef INVARIANTS
- if (bp->b_vp) {
- KASSERT((buf->b_bp->b_xflags & (BX_VNCLEAN|BX_VNDIRTY)) == BX_VNCLEAN, ("brelse() on buffer that is not clean"));
- }
-#endif
-
+ if (hdr->b_datacnt == 1)
+ arc_bgetvp(buf);
CTR4(KTR_SPARE2, "arc_brelse() bp=%p flags %X size %ld blkno=%ld",
bp, bp->b_flags, size, bp->b_blkno);
brelse(bp);
@@ -2734,16 +2688,6 @@ arc_read_done(zio_t *zio)
freeable = refcount_is_zero(&hdr->b_refcnt);
}
- if ((freeable == FALSE) && !zfs_page_cache_disable) {
- off_t blkno = hdr->b_dva.dva_word[1] & ~(1UL<<63);
- struct buf *bp = buf->b_bp;
-
- bp->b_flags |= B_CACHE;
- bp->b_flags &= ~B_INVAL;
- arc_gbincore_replace(spa_get_vnode(hdr->b_spa),
- blkno, bp->b_bcount, 0, bp);
- }
-
/*
* Broadcast before we drop the hash_lock to avoid the possibility
* that the hdr (and hence the cv) might be freed before we get to
@@ -2985,7 +2929,6 @@ top:
mutex_exit(hash_lock);
goto top;
}
- buf->b_bp->b_offset = bp->blk_birth;
}
acb = kmem_zalloc(sizeof (arc_callback_t), KM_SLEEP);
@@ -3456,14 +3399,7 @@ arc_write_done(zio_t *zio)
arc_hdr_destroy(exists);
exists = buf_hash_insert(hdr, &hash_lock);
ASSERT3P(exists, ==, NULL);
- } else if ((bp != NULL) &&
- (bp->b_bufobj == NULL) &&
- (bp->b_bcount >= PAGE_SIZE) &&
- !zfs_page_cache_disable) {
- bp->b_flags |= B_CACHE;
- bp->b_flags &= ~B_INVAL;
- arc_gbincore_replace(vp, blkno, bp->b_bcount, 0, bp);
- }
+ }
hdr->b_flags &= ~ARC_IO_IN_PROGRESS;
/* if it's not anon, we are doing a scrub */
More information about the svn-src-user
mailing list