From owner-svn-src-user@FreeBSD.ORG Tue Nov 17 04:59:44 2009 Return-Path: <owner-svn-src-user@FreeBSD.ORG> Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4B6141065672; Tue, 17 Nov 2009 04:59:44 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 387D18FC12; Tue, 17 Nov 2009 04:59:44 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id nAH4xixo091873; Tue, 17 Nov 2009 04:59:44 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id nAH4xiTO091871; Tue, 17 Nov 2009 04:59:44 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <200911170459.nAH4xiTO091871@svn.freebsd.org> From: Kip Macy <kmacy@FreeBSD.org> Date: Tue, 17 Nov 2009 04:59:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r199343 - user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" <svn-src-user.freebsd.org> List-Unsubscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-user>, <mailto:svn-src-user-request@freebsd.org?subject=unsubscribe> List-Archive: <http://lists.freebsd.org/pipermail/svn-src-user> List-Post: <mailto:svn-src-user@freebsd.org> List-Help: <mailto:svn-src-user-request@freebsd.org?subject=help> List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-user>, <mailto:svn-src-user-request@freebsd.org?subject=subscribe> X-List-Received-Date: Tue, 17 Nov 2009 04:59:44 -0000 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 */