svn commit: r199687 - in
user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs:
. sys
Kip Macy
kmacy at FreeBSD.org
Mon Nov 23 01:59:13 UTC 2009
Author: kmacy
Date: Mon Nov 23 01:59:12 2009
New Revision: 199687
URL: http://svn.freebsd.org/changeset/base/199687
Log:
- extend arc_binval to invalidate pages in the vm object
- change arc_bgetvp to arc_bcache to cache freed buffers and their pages in the vm object
- close race between getblk and brelvp by passing GB_LOCK_NOWAIT to getblk
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/sys/arc.h
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 Mon Nov 23 01:53:27 2009 (r199686)
+++ user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Mon Nov 23 01:59:12 2009 (r199687)
@@ -1300,12 +1300,16 @@ arc_buf_add_ref(arc_buf_t *buf, void* ta
}
void
-arc_binval(spa_t *spa, dva_t *dva)
+arc_binval(spa_t *spa, dva_t *dva, uint64_t size)
{
uint64_t blkno;
struct vnode *vp;
struct bufobj *bo;
struct buf *bp;
+ vm_pindex_t start, end;
+ vm_object_t object;
+ vm_page_t m;
+ int i;
if (zfs_page_cache_disable)
return;
@@ -1328,18 +1332,57 @@ arc_binval(spa_t *spa, dva_t *dva)
bp->b_flags |= B_INVAL;
bp->b_birth = 0;
brelse(bp);
- } else
+ } else {
BO_UNLOCK(bo);
+ start = OFF_TO_IDX((blkno << 9));
+ end = start + OFF_TO_IDX(size);
+ object = vp->v_object;
+
+ if (size == 0)
+ return;
+ VM_OBJECT_LOCK(object);
+ vm_page_cache_free(object, start, end);
+ for (i = 0; i < OFF_TO_IDX(size); i++) {
+ if ((m = vm_page_lookup(object, start + i)) != NULL)
+ vm_page_free(m);
+ }
+ VM_OBJECT_UNLOCK(object);
+ }
}
static void
-arc_bgetvp(arc_buf_t *buf)
+arc_pcache(struct vnode *vp, struct buf *bp, uint64_t blkno)
+{
+ vm_pindex_t start = OFF_TO_IDX((blkno << 9));
+ vm_object_t object = vp->v_object;
+ struct bufobj *bo = &vp->v_bufobj;
+ vm_page_t m;
+ int i;
+
+ VM_OBJECT_LOCK(object);
+ vm_page_cache_free(object, start, start + bp->b_npages);
+ for (i = 0; i < bp->b_npages; i++) {
+ if ((m = vm_page_lookup(object, start + i)) != NULL)
+ vm_page_free(m);
+ m = bp->b_pages[i];
+ vm_page_insert(m, object, start + i);
+ }
+ VM_OBJECT_UNLOCK(object);
+ BO_LOCK(bo);
+ bgetvp(vp, bp);
+ BO_UNLOCK(bo);
+ bp->b_flags |= B_VMIO;
+}
+
+static void
+arc_bcache(arc_buf_t *buf)
{
uint64_t blkno = buf->b_hdr->b_dva.dva_word[1] & ~(1UL<<63);
struct buf *newbp, *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;
+ int cachebuf;
if (zfs_page_cache_disable)
return;
@@ -1348,17 +1391,19 @@ arc_bgetvp(arc_buf_t *buf)
return;
newbp = buf->b_bp;
- newbp->b_offset = newbp->b_birth = hdr->b_birth;
+ newbp->b_birth = hdr->b_birth;
newbp->b_blkno = newbp->b_lblkno = blkno;
+ newbp->b_offset = (blkno << 9);
+ cachebuf = ((hdr->b_datacnt == 1) &&
+ !(hdr->b_flags & ARC_IO_ERROR) &&
+ ((newbp->b_flags & (B_INVAL|B_CACHE)) == B_CACHE));
BO_LOCK(bo);
bp = gbincore(bo, blkno);
if (bp != NULL) {
- /*
- * XXX we have a race with getblk here
- */
BUF_LOCK(bp, LK_EXCLUSIVE | LK_INTERLOCK, BO_MTX(bo));
bremfree(bp);
+
/*
* buffer is not valid or is older
*/
@@ -1368,20 +1413,11 @@ arc_bgetvp(arc_buf_t *buf)
bp->b_birth = 0;
}
brelse(bp);
-
- if ((hdr->b_datacnt == 1) &&
- !(hdr->b_flags & ARC_IO_ERROR) &&
- (newbp->b_flags & (B_INVAL|B_CACHE)) == B_CACHE) {
- BO_LOCK(bo);
- bgetvp(vp, newbp);
- BO_UNLOCK(bo);
- }
- } else if ((hdr->b_datacnt == 1) &&
- !(hdr->b_flags & ARC_IO_ERROR) &&
- (newbp->b_flags & (B_INVAL|B_CACHE)) == B_CACHE) {
- bgetvp(vp, newbp);
- BO_UNLOCK(bo);
- } else
+ if (cachebuf)
+ arc_pcache(vp, newbp, blkno);
+ } else if (cachebuf)
+ arc_pcache(vp, newbp, blkno);
+ else
BO_UNLOCK(bo);
}
@@ -1397,7 +1433,9 @@ arc_getblk(arc_buf_t *buf)
arc_buf_t *tbuf;
struct vnode *vp;
struct bufobj *bo;
- int flags = 0;
+ int i, flags = 0;
+ vm_pindex_t start, end;
+ vm_object_t object;
if (type == ARC_BUFC_METADATA) {
arc_space_consume(size);
@@ -1419,11 +1457,26 @@ arc_getblk(arc_buf_t *buf)
data = newbp->b_data;
buf->b_hdr->b_flags &= ~ARC_BUF_CLONING;
} else {
- newbp = getblk(vp, blkno, size, 0, 0, flags | GB_NOCREAT);
+ newbp = getblk(vp, blkno, size, 0, 0, flags | GB_LOCK_NOWAIT);
if (newbp == NULL)
newbp = geteblk(size, flags);
- else
+ else {
+ vm_object_t object = vp->v_object;
+ vm_page_t m;
+
+ /*
+ * Strip the buffers pages from the object
+ */
+ VM_OBJECT_LOCK(object);
+ vm_page_lock_queues();
+ for (i = 0; i < newbp->b_npages; i++){
+ m = newbp->b_pages[i];
+ vm_page_remove(m);
+ }
+ vm_page_unlock_queues();
+ VM_OBJECT_UNLOCK(object);
brelvp(newbp);
+ }
data = newbp->b_data;
}
@@ -1453,11 +1506,20 @@ arc_brelse(arc_buf_t *buf, void *data, s
return;
}
- arc_bgetvp(buf);
- CTR4(KTR_SPARE2, "arc_brelse() bp=%p flags %X"
- " size %ld blkno=%ld",
- bp, bp->b_flags, size, bp->b_blkno);
+ arc_bcache(buf);
+
+ if (bp->b_vp == NULL)
+ KASSERT((bp->b_flags & B_VMIO) == 0, ("no vp but VMIO set!"));
+ else
+ CTR4(KTR_SPARE2, "arc_brelse() bp=%p flags %X"
+ " size %ld blkno=%ld",
+ bp, bp->b_flags, size, bp->b_blkno);
+
+ /*
+ * need to log path through here to determine why we're not ending up on the inactive queue
+ *
+ */
brelse(bp);
}
Modified: user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h
==============================================================================
--- user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h Mon Nov 23 01:53:27 2009 (r199686)
+++ user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h Mon Nov 23 01:59:12 2009 (r199687)
@@ -112,7 +112,7 @@ int arc_tryread(spa_t *spa, blkptr_t *bp
void arc_set_callback(arc_buf_t *buf, arc_evict_func_t *func, void *private);
int arc_buf_evict(arc_buf_t *buf);
-void arc_binval(spa_t *spa, dva_t *dva);
+void arc_binval(spa_t *spa, dva_t *dva, uint64_t size);
void arc_flush(spa_t *spa);
void arc_tempreserve_clear(uint64_t reserve);
int arc_tempreserve_space(uint64_t reserve, uint64_t txg);
More information about the svn-src-user
mailing list