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

Kip Macy kmacy at FreeBSD.org
Mon Nov 2 22:50:39 UTC 2009


Author: kmacy
Date: Mon Nov  2 22:50:39 2009
New Revision: 198830
URL: http://svn.freebsd.org/changeset/base/198830

Log:
  add separate function for evicting blocks from the page cache

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  2 22:33:04 2009	(r198829)
+++ user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c	Mon Nov  2 22:50:39 2009	(r198830)
@@ -491,8 +491,9 @@ static void arc_get_data_buf(arc_buf_t *
 static void arc_access(arc_buf_hdr_t *buf, kmutex_t *hash_lock);
 static int arc_evict_needed(arc_buf_contents_t type);
 static void arc_evict_ghost(arc_state_t *state, spa_t *spa, int64_t bytes);
+static void arc_binval(arc_buf_t *buf, off_t blkno, struct vnode *vp, size_t size);
 
-#define	GHOST_STATE(state)	\
+#define	GHOST_STATE(state)						\
 	((state) == arc_mru_ghost || (state) == arc_mfu_ghost ||	\
 	(state) == arc_l2c_only)
 
@@ -1307,31 +1308,21 @@ arc_getblk(arc_buf_t *buf)
 		ASSERT(type == ARC_BUFC_DATA);
 		flags = GB_NODUMP;
 		atomic_add_64(&arc_size, size);
-	}	
+	}
 
-	if (buf->b_hdr->b_flags & ARC_BUF_CLONING) {
+	if ((size < PAGE_SIZE) ||
+	    (buf->b_hdr->b_flags & ARC_BUF_CLONING) ||
+	    BUF_EMPTY(buf->b_hdr)) 
 		newbp = geteblk(size, flags);
-		tbuf = buf;
+	else 
+		newbp = getblk(spa_get_vnode(spa), blkno,
+		    size, 0, 0, flags);	
+
+	if (buf->b_hdr->b_flags & ARC_BUF_CLONING) {
 		vp = spa_get_vnode(spa);
 
-		bp = buf->b_bp;
-		bcopy(bp->b_data, newbp->b_data, size);
-		KASSERT((bp->b_blkno == bp->b_lblkno) &&
-		    (bp->b_blkno == blkno),
-		    ("blkno mismatch b_blkno %ld b_lblkno %ld blkno %ld",
-			bp->b_blkno, bp->b_lblkno, blkno));
-		while (tbuf->b_next != NULL) {
-			if (tbuf->b_bp->b_vp != NULL) {
-				KASSERT((bp->b_xflags & (BX_VNCLEAN|BX_VNDIRTY)) == BX_VNCLEAN, ("brelvp() on buffer that is not in splay"));
-
-				bp = tbuf->b_bp;
-				bp->b_flags |= B_INVAL;
-				bp->b_flags &= ~B_CACHE;
-				brelvp(bp);
-				break;
-			}
-			tbuf = tbuf->b_next;
-		}
+		arc_binval(buf, blkno, vp, size);
+		bcopy(buf->b_next->b_data, newbp->b_data, size);
 
 		newbp->b_bufobj = &vp->v_bufobj;
 		newbp->b_lblkno = blkno;
@@ -1343,15 +1334,16 @@ arc_getblk(arc_buf_t *buf)
 		BO_UNLOCK(&vp->v_bufobj);
 		newbp->b_flags &= ~B_INVAL;
 		newbp->b_flags |= B_CACHE;
-		buf->b_hdr->b_flags &= ~ARC_BUF_CLONING;
-		
-	} else if (BUF_EMPTY(buf->b_hdr)) {
-		newbp = geteblk(size, flags);
-	} else
-		newbp = getblk(spa_get_vnode(spa), blkno,
-		    size, 0, 0, flags);
+		buf->b_hdr->b_flags &= ~ARC_BUF_CLONING;		
+	} 
+#ifdef LOGALL
+	/*
+	 * not useful for tracking down collisions
+	 *
+	 */
 	CTR2(KTR_SPARE2, "arc_getblk() bp=%p flags %X",
 	    newbp, newbp->b_flags);
+#endif
 
 	BUF_KERNPROC(newbp);
 	buf->b_bp = newbp;
@@ -1367,15 +1359,46 @@ arc_brelse(arc_buf_t *buf, void *data, s
 #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"));
-		brelvp(bp);
 	}
 #endif	
 	
-	CTR5(KTR_SPARE2, "arc_brelse() bp=%p flags %X size %ld lblkno=%ld blkno=%ld",
-	    bp, bp->b_flags, size, bp->b_lblkno, bp->b_blkno);
+	CTR4(KTR_SPARE2, "arc_brelse() bp=%p flags %X size %ld blkno=%ld",
+	    bp, bp->b_flags, size, bp->b_blkno);
 	brelse(bp);
 }
 
+static void
+arc_binval(arc_buf_t *buf, off_t blkno, struct vnode *vp, size_t size) 
+{
+	arc_buf_hdr_t *hdr;
+	arc_buf_t *tbuf;
+	int released = 0;
+	struct buf *bp = NULL;	
+
+	/*
+	 * 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;	
+		}
+	}
+
+	if (!released)
+		if ((bp = getblk(vp, blkno, size, 0, 0, GB_NOCREAT)) != NULL) {		
+			bp->b_flags |= B_INVAL;
+			brelse(bp);
+		}
+}
+
+
 /*
  * 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.
@@ -3335,8 +3358,8 @@ arc_write_done(zio_t *zio)
 		struct vnode *vp = spa_get_vnode(hdr->b_spa);
 		off_t blkno = hdr->b_dva.dva_word[1] & ~(1UL<<63);	
 
-		CTR2(KTR_SPARE2, "arc_write_done(%p) flags %X",
-		    bp, bp->b_flags);
+		CTR3(KTR_SPARE2, "arc_write_done() bp=%p flags %X blkno %ld",
+		    bp, bp->b_flags, blkno);
 
 		arc_cksum_verify(buf);
 
@@ -3360,15 +3383,11 @@ arc_write_done(zio_t *zio)
 			exists = buf_hash_insert(hdr, &hash_lock);
 			ASSERT3P(exists, ==, NULL);
 		} else if ((hdr->b_buf == buf) &&
-		    (bp->b_bufobj == NULL)) {
-			struct buf *oldbp;
+		    (bp->b_bufobj == NULL) &&
+		    (bp->b_bcount >= PAGE_SIZE)) {
 			struct bufobj *bo;
 
-			oldbp = getblk(vp, blkno, bp->b_bcount, 0, 0, GB_NOCREAT);
-			if (oldbp != NULL) {
-				oldbp->b_flags |= B_INVAL;
-				brelse(oldbp);
-			}
+			arc_binval(buf, blkno, vp, bp->b_bcount);
 			bo = bp->b_bufobj = &vp->v_bufobj;
 			bp->b_lblkno = blkno;
 			bp->b_blkno = blkno;
@@ -3691,6 +3710,10 @@ arc_shutdown(void *arg __unused, int how
 	struct mount *mp, *tmpmp;
 	int error;
 
+	/*
+	 * unmount all ZFS file systems - freeing any buffers
+	 * then free all space allocator resources
+	 */
 	TAILQ_FOREACH_SAFE(mp, &mountlist, mnt_list, tmpmp) {
 		if (strcmp(mp->mnt_vfc->vfc_name, "zfs") == 0) {
 			error = dounmount(mp, MNT_FORCE, curthread);
@@ -3708,7 +3731,10 @@ arc_shutdown(void *arg __unused, int how
 	}
 	arc_flush(NULL);
 
-#if 0	
+#ifdef NOTYET
+	/*
+	 * need corresponding includes
+	 */
 	zfsdev_fini();
 	zvol_fini();
 	zfs_fini();


More information about the svn-src-user mailing list