From 2b14b99e0af107ce75981efc472db5350544b384 Mon Sep 17 00:00:00 2001 From: avg Date: Fri, 30 Oct 2015 12:00:34 +0000 Subject: [PATCH] l2arc: do not call trim_map_free() for blocks with zero b_asize b_asize can be zero if the block is compressed into an empty block (ZIO_COMPRESS_EMPTY) and the trim code asserts that meaningless zero-sized trimming is not attempted. The logic for calling trim_map_free() is extracted into a new function l2arc_trim() to minimize code duplication. PR: 203473 Reported by: Willem Jan Withagen Tested by: Willem Jan Withagen MFC after: 11 days --- .../opensolaris/uts/common/fs/zfs/arc.c | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index ba16dedcecdc..0123a799eea5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -1131,6 +1131,24 @@ static boolean_t l2arc_compress_buf(arc_buf_hdr_t *); static void l2arc_decompress_zio(zio_t *, arc_buf_hdr_t *, enum zio_compress); static void l2arc_release_cdata_buf(arc_buf_hdr_t *); +static void +l2arc_trim(const arc_buf_hdr_t *hdr) +{ + l2arc_dev_t *dev = hdr->b_l2hdr.b_dev; + + ASSERT(HDR_HAS_L2HDR(hdr)); + ASSERT(MUTEX_HELD(&dev->l2ad_mtx)); + + if (hdr->b_l2hdr.b_daddr == L2ARC_ADDR_UNSET) + return; + if (hdr->b_l2hdr.b_asize != 0) { + trim_map_free(dev->l2ad_vdev, hdr->b_l2hdr.b_daddr, + hdr->b_l2hdr.b_asize, 0); + } else { + ASSERT3U(hdr->b_l2hdr.b_compress, ==, ZIO_COMPRESS_EMPTY); + } +} + static uint64_t buf_hash(uint64_t spa, const dva_t *dva, uint64_t birth) { @@ -2403,10 +2421,7 @@ arc_hdr_destroy(arc_buf_hdr_t *hdr) * want to re-destroy the header's L2 portion. */ if (HDR_HAS_L2HDR(hdr)) { - if (hdr->b_l2hdr.b_daddr != L2ARC_ADDR_UNSET) - trim_map_free(dev->l2ad_vdev, - hdr->b_l2hdr.b_daddr, - hdr->b_l2hdr.b_asize, 0); + l2arc_trim(hdr); arc_hdr_l2hdr_destroy(hdr); } @@ -4776,10 +4791,7 @@ arc_release(arc_buf_t *buf, void *tag) * to acquire the l2ad_mtx. */ if (HDR_HAS_L2HDR(hdr)) { - if (hdr->b_l2hdr.b_daddr != L2ARC_ADDR_UNSET) - trim_map_free(hdr->b_l2hdr.b_dev->l2ad_vdev, - hdr->b_l2hdr.b_daddr, - hdr->b_l2hdr.b_asize, 0); + l2arc_trim(hdr); arc_hdr_l2hdr_destroy(hdr); } @@ -5966,8 +5978,7 @@ l2arc_write_done(zio_t *zio) * Error - drop L2ARC entry. */ list_remove(buflist, hdr); - trim_map_free(hdr->b_l2hdr.b_dev->l2ad_vdev, - hdr->b_l2hdr.b_daddr, hdr->b_l2hdr.b_asize, 0); + l2arc_trim(hdr); hdr->b_flags &= ~ARC_FLAG_HAS_L2HDR; ARCSTAT_INCR(arcstat_l2_asize, -hdr->b_l2hdr.b_asize);