Date: Sun, 15 Nov 2009 23:49:28 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r199301 - user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs Message-ID: <200911152349.nAFNnS6n051472@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kmacy Date: Sun Nov 15 23:49:28 2009 New Revision: 199301 URL: http://svn.freebsd.org/changeset/base/199301 Log: consolidate in-core buffer invalidation in to one function 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 Sun Nov 15 23:48:29 2009 (r199300) +++ user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c Sun Nov 15 23:49:28 2009 (r199301) @@ -494,7 +494,7 @@ static void arc_access(arc_buf_hdr_t *bu 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, struct buf *bp); + size_t size, int flags, struct buf *bp); #define GHOST_STATE(state) \ ((state) == arc_mru_ghost || (state) == arc_mfu_ghost || \ @@ -1298,6 +1298,67 @@ 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; + int associated = 0; + + /* + * 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)) { + BO_UNLOCK(bo); + brelvp(bp); + } else { + BUF_LOCK(bp, LK_EXCLUSIVE | LK_INTERLOCK, BO_MTX(bo)); + if (newbp != NULL) { + 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 + */ + 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) + allocbuf_flags(bp, size, flags); + associated = 1; + } + } + } + + if (!associated) { + if (newbp != NULL) { + if (bp != NULL) + BO_LOCK(bo); + bgetvp(vp, newbp); + BO_UNLOCK(bo); + bp = newbp; + } else + bp = getblk(vp, blkno, size, 0, 0, flags); + } + + return (bp); +} + static void arc_getblk(arc_buf_t *buf) { @@ -1332,33 +1393,7 @@ arc_getblk(arc_buf_t *buf) newbp = geteblk(size, flags); data = newbp->b_data; } else { - /* - * We need to be careful to handle the case where the buffer - * is already held in the ARC for a previous birth transaction - */ - BO_LOCK(bo); - bp = gbincore(bo, blkno); - if (bp != NULL) { - if (BUF_ISLOCKED(bp)) { - BO_UNLOCK(bo); - brelvp(bp); - } else { - BUF_LOCK(bp, LK_EXCLUSIVE | LK_INTERLOCK, BO_MTX(bo)); - 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) - allocbuf_flags(bp, size, flags); - newbp = bp; - } - - } else - BO_UNLOCK(bo); - - if (newbp == NULL) - newbp = getblk(vp, blkno, size, 0, 0, flags); + newbp = arc_gbincore_replace(vp, blkno, size, flags, NULL); newbp->b_offset = buf->b_hdr->b_birth; data = newbp->b_data; @@ -1368,7 +1403,7 @@ arc_getblk(arc_buf_t *buf) (size >= PAGE_SIZE) && (!BUF_EMPTY(buf->b_hdr)) && !page_cache_disable) - arc_binval(buf, blkno, vp, size, newbp); + arc_binval(buf, blkno, vp, size, flags, newbp); buf->b_hdr->b_flags &= ~ARC_BUF_CLONING; #ifdef LOGALL @@ -1409,7 +1444,8 @@ arc_brelse(arc_buf_t *buf, void *data, s } static void -arc_binval(arc_buf_t *buf, off_t blkno, struct vnode *vp, size_t size, struct buf *newbp) +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; @@ -1439,25 +1475,8 @@ arc_binval(arc_buf_t *buf, off_t blkno, newbp->b_flags &= ~B_INVAL; newbp->b_flags |= B_CACHE; - BO_LOCK(bo); - if (!released) { - bp = gbincore(bo, blkno); - if (bp != NULL) { - if (BUF_ISLOCKED(bp)) { - BO_UNLOCK(bo); - brelvp(bp); - } else { - BUF_LOCK(bp, LK_EXCLUSIVE | LK_INTERLOCK, BO_MTX(bo)); - bp->b_flags |= B_INVAL; - bp->b_flags &= ~B_CACHE; - bremfree(bp); - brelse(bp); - } - BO_LOCK(bo); - } - } - bgetvp(vp, newbp); - BO_UNLOCK(bo); + if (!released) + arc_gbincore_replace(vp, blkno, size, flags, newbp); } /* @@ -3456,7 +3475,7 @@ arc_write_done(zio_t *zio) (bp->b_bufobj == NULL) && (bp->b_bcount >= PAGE_SIZE) && !page_cache_disable) { - arc_binval(buf, blkno, vp, bp->b_bcount, bp); + arc_binval(buf, blkno, vp, bp->b_bcount, 0, bp); } hdr->b_flags &= ~ARC_IO_IN_PROGRESS;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911152349.nAFNnS6n051472>