Date: Mon, 2 Nov 2009 22:50:39 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r198830 - user/kmacy/releng_8_fcs_buf/sys/cddl/contrib/opensolaris/uts/common/fs/zfs Message-ID: <200911022250.nA2Modg1072424@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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();
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911022250.nA2Modg1072424>