svn commit: r199340 - user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs

Kip Macy kmacy at FreeBSD.org
Tue Nov 17 00:49:42 UTC 2009


Author: kmacy
Date: Tue Nov 17 00:49:41 2009
New Revision: 199340
URL: http://svn.freebsd.org/changeset/base/199340

Log:
  - Only mark a buffer as newly valid on read and write completion
  - add comments to arc_gbincore_replace
  - don't treat cloned buffers as the newly valid mapping - this eliminates the need for arc_binval

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	Mon Nov 16 22:52:52 2009	(r199339)
+++ user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c	Tue Nov 17 00:49:41 2009	(r199340)
@@ -1319,20 +1319,30 @@ arc_gbincore_replace(struct vnode *vp, o
 			BO_UNLOCK(bo);
 			return (bp);
 		}
+
 		if (BUF_ISLOCKED(bp)) {
+			/*
+			 * buffer is currently referenced in the ARC with older birth txg
+			 *
+			 */
+			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 {
 				/*
-				 * We don't have a new buffer for which we're 
-				 * replacing the mapping, use this buffer
+				 * buffer is usable for this mapping
 				 */
 				if (bp->b_flags & B_INVAL)
 					bp->b_flags &= ~B_CACHE;
@@ -1404,21 +1414,15 @@ arc_getblk(arc_buf_t *buf)
 	    BUF_EMPTY(buf->b_hdr) ||
 		zfs_page_cache_disable) {
 		newbp = geteblk(size, flags);
-		data = newbp->b_data;		
+		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;
-		data = newbp->b_data;		
+		data = newbp->b_data;
 	}
 
-	if ((buf->b_hdr->b_flags & ARC_BUF_CLONING) &&
-	    (size >= PAGE_SIZE) &&
-	    (!BUF_EMPTY(buf->b_hdr)) &&
-		!zfs_page_cache_disable)
-		arc_binval(buf, blkno, vp, size, flags, newbp);
-	buf->b_hdr->b_flags &= ~ARC_BUF_CLONING;
-
 #ifdef LOGALL
 	/*
 	 * not useful for tracking down collisions
@@ -1456,42 +1460,6 @@ arc_brelse(arc_buf_t *buf, void *data, s
 	brelse(bp);
 }
 
-static void
-arc_binval(arc_buf_t *buf, off_t blkno, struct vnode *vp, size_t size,
-    int flags, struct buf *newbp) 
-{
-	arc_buf_t *tbuf;
-	int released = 0;
-	struct buf *bp = NULL;	
-	uint64_t birth;
-	struct bufobj *bo;
-
-	/*
-	 * disassociate backing buffers from the vnode
-	 *
-	 */
-	for (tbuf = buf; tbuf != NULL; 	tbuf = tbuf->b_next) {
-		if ((tbuf->b_bp != NULL) && (tbuf->b_bp->b_vp != NULL)) {
-			bp = tbuf->b_bp;
-			KASSERT((bp->b_xflags & (BX_VNCLEAN|BX_VNDIRTY)) == BX_VNCLEAN, ("brelvp() on buffer that is not in splay"));
-			
-			bp->b_flags |= B_INVAL;
-			bp->b_flags &= ~B_CACHE;
-			brelvp(bp);
-			released = 1;	
-		}
-	}
-	bo = newbp->b_bufobj = &vp->v_bufobj;
-	newbp->b_lblkno = blkno;
-	newbp->b_blkno = blkno;
-	newbp->b_offset = buf->b_hdr->b_birth;
-	newbp->b_flags &= ~B_INVAL;
-	newbp->b_flags |= B_CACHE;
-
-	if (!released) 
-		arc_gbincore_replace(vp, blkno, size, flags, newbp);
-}
-
 /*
  * Free the arc data buffer.  If it is an l2arc write in progress,
  * the buffer is placed on l2arc_free_on_write to be freed later.
@@ -2739,11 +2707,6 @@ arc_read_done(zio_t *zio)
 
 	arc_cksum_compute(buf, B_FALSE);
 
-	if (buf->b_bp != NULL) {
-		buf->b_bp->b_flags &= ~B_INVAL;
-		buf->b_bp->b_flags |= B_CACHE;
-	}
-	
 	/* create copies of the data buffer for the callers */
 	abuf = buf;
 	for (acb = callback_list; acb; acb = acb->acb_next) {
@@ -2771,6 +2734,16 @@ 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
@@ -3483,12 +3456,13 @@ arc_write_done(zio_t *zio)
 			arc_hdr_destroy(exists);
 			exists = buf_hash_insert(hdr, &hash_lock);
 			ASSERT3P(exists, ==, NULL);
-		} else if ((hdr->b_buf == buf) &&
-		    (bp != NULL) &&
+		} else if ((bp != NULL) &&
 		    (bp->b_bufobj == NULL) &&
 		    (bp->b_bcount >= PAGE_SIZE) &&
 			!zfs_page_cache_disable) {
-			arc_binval(buf, blkno, vp, bp->b_bcount, 0, bp);
+			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;


More information about the svn-src-user mailing list