Date: Tue, 17 Nov 2009 04:59:44 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r199343 - user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs Message-ID: <200911170459.nAH4xiTO091871@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911170459.nAH4xiTO091871>