svn commit: r198838 -
user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Kip Macy
kmacy at FreeBSD.org
Tue Nov 3 03:20:14 UTC 2009
Author: kmacy
Date: Tue Nov 3 03:20:13 2009
New Revision: 198838
URL: http://svn.freebsd.org/changeset/base/198838
Log:
handle buf allocation in case where blkno is already cached for a previous birth transaction
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 3 01:49:06 2009 (r198837)
+++ user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Tue Nov 3 03:20:13 2009 (r198838)
@@ -1308,6 +1308,7 @@ arc_getblk(arc_buf_t *buf)
struct buf *newbp, *bp;
arc_buf_t *tbuf;
struct vnode *vp;
+ struct bufobj *bo;
int flags = 0;
if (type == ARC_BUFC_METADATA) {
@@ -1318,21 +1319,52 @@ arc_getblk(arc_buf_t *buf)
atomic_add_64(&arc_size, size);
}
+ vp = spa_get_vnode(spa);
+ bo = &vp->v_bufobj;
if ((size < PAGE_SIZE) ||
(buf->b_hdr->b_flags & ARC_BUF_CLONING) ||
- BUF_EMPTY(buf->b_hdr))
+ BUF_EMPTY(buf->b_hdr)) {
+
newbp = geteblk(size, flags);
- else
- newbp = getblk(spa_get_vnode(spa), blkno,
- size, 0, 0, flags);
+ } else {
+ /*
+ * We need to be careful to handle the case where the buffer
+ * is already held in the ARC for a previous birth transaction
+ */
+ BO_LOCK(bo);
+ bp = gbincore(bo, blkno);
+ if (bp != NULL) {
+ if (BUF_ISLOCKED(bp)) {
+ BO_UNLOCK(bo);
+ newbp = geteblk(size, flags);
+ arc_binval(buf, blkno, vp, size, newbp);
+ } else {
+ BUF_LOCK(bp, LK_EXCLUSIVE | LK_INTERLOCK, BO_MTX(bo));
+ 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) {
+ bp->b_flags |= B_INVAL;
+ bp->b_flags &= ~B_CACHE;
+ brelse(bp);
+ newbp = getblk(vp, blkno, size, 0, 0, flags);
+ } else
+ newbp = bp;
+ }
+
+ }
+ }
- if (buf->b_hdr->b_flags & ARC_BUF_CLONING) {
+ if ((size >= PAGE_SIZE) && (buf->b_hdr->b_flags & ARC_BUF_CLONING)) {
vp = spa_get_vnode(spa);
bcopy(buf->b_next->b_data, newbp->b_data, size);
arc_binval(buf, blkno, vp, size, newbp);
buf->b_hdr->b_flags &= ~ARC_BUF_CLONING;
}
+
#ifdef LOGALL
/*
* not useful for tracking down collisions
@@ -1408,6 +1440,7 @@ arc_binval(arc_buf_t *buf, off_t blkno,
BUF_LOCK(bp, LK_EXCLUSIVE | LK_INTERLOCK, BO_MTX(bo));
bp->b_flags |= B_INVAL;
bp->b_flags &= ~B_CACHE;
+ bremfree(bp);
brelse(bp);
BO_LOCK(bo);
}
More information about the svn-src-user
mailing list