From 4c1f8e17843d8b5e05474575ab7d8a0984b19af3 Mon Sep 17 00:00:00 2001 From: Etienne Dechamps Date: Tue, 25 Sep 2012 14:28:53 +0200 Subject: [PATCH] TRIM cache devices on export and remove. With this patch: - L2ARC vdevs are trimmed on export, except the labels which are preserved to keep import working. - L2ARC vdevs are trimmed entirely on remove and pool destroy. --- include/sys/arc.h | 2 +- include/sys/zio.h | 2 +- module/zfs/arc.c | 7 ++++++- module/zfs/spa.c | 7 +++++-- module/zfs/trim_map.c | 2 +- module/zfs/vdev_label.c | 2 +- module/zfs/zio.c | 6 ++++-- 7 files changed, 19 insertions(+), 9 deletions(-) diff --git a/include/sys/arc.h b/include/sys/arc.h index dd9b128bc1ea..7096216823bb 100644 --- a/include/sys/arc.h +++ b/include/sys/arc.h @@ -143,7 +143,7 @@ void arc_fini(void); */ void l2arc_add_vdev(spa_t *spa, vdev_t *vd); -void l2arc_remove_vdev(vdev_t *vd); +void l2arc_remove_vdev(vdev_t *vd, int trim); boolean_t l2arc_vdev_present(vdev_t *vd); void l2arc_init(void); void l2arc_fini(void); diff --git a/include/sys/zio.h b/include/sys/zio.h index 8cb939d46916..6d15edbea55e 100644 --- a/include/sys/zio.h +++ b/include/sys/zio.h @@ -517,7 +517,7 @@ extern int zio_alloc_zil(spa_t *spa, uint64_t txg, blkptr_t *new_bp, extern void zio_free_zil(spa_t *spa, uint64_t txg, blkptr_t *bp); extern void zio_flush(zio_t *zio, vdev_t *vd); extern zio_t *zio_trim(zio_t *zio, spa_t *spa, vdev_t *vd, - uint64_t offset, uint64_t size); + uint64_t offset, uint64_t size, enum zio_flag flags); extern void zio_shrink(zio_t *zio, uint64_t size); extern int zio_wait(zio_t *zio); diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 203586193cf1..70e9f530a359 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -4856,7 +4856,7 @@ l2arc_add_vdev(spa_t *spa, vdev_t *vd) * Remove a vdev from the L2ARC. */ void -l2arc_remove_vdev(vdev_t *vd) +l2arc_remove_vdev(vdev_t *vd, int trim) { l2arc_dev_t *dev, *nextdev, *remdev = NULL; @@ -4886,6 +4886,11 @@ l2arc_remove_vdev(vdev_t *vd) */ l2arc_evict(remdev, 0, B_TRUE); list_destroy(remdev->l2ad_buflist); + if (trim && spa_writeable(vd->vdev_spa)) + zio_wait(zio_trim(NULL, vd->vdev_spa, vd, + remdev->l2ad_start, + remdev->l2ad_end - remdev->l2ad_start, + ZIO_FLAG_CONFIG_WRITER)); kmem_free(remdev->l2ad_buflist, sizeof (list_t)); kmem_free(remdev, sizeof (l2arc_dev_t)); } diff --git a/module/zfs/spa.c b/module/zfs/spa.c index 16df287acb7f..581924d79c97 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -1311,7 +1311,10 @@ spa_load_l2cache(spa_t *spa) if (spa_l2cache_exists(vd->vdev_guid, &pool) && pool != 0ULL && l2arc_vdev_present(vd)) - l2arc_remove_vdev(vd); + l2arc_remove_vdev(vd, 0); + if (!zfs_notrim && spa_writeable(spa)) + zio_wait(zio_trim(NULL, spa, vd, 0, + vd->vdev_psize, ZIO_FLAG_CONFIG_WRITER)); vdev_clear_stats(vd); vdev_free(vd); } @@ -2935,7 +2938,7 @@ spa_l2cache_drop(spa_t *spa) if (spa_l2cache_exists(vd->vdev_guid, &pool) && pool != 0ULL && l2arc_vdev_present(vd)) - l2arc_remove_vdev(vd); + l2arc_remove_vdev(vd, !zfs_notrim); } } diff --git a/module/zfs/trim_map.c b/module/zfs/trim_map.c index ea6116868a97..3ae4eb89b172 100644 --- a/module/zfs/trim_map.c +++ b/module/zfs/trim_map.c @@ -392,7 +392,7 @@ trim_map_vdev_commit(spa_t *spa, zio_t *zio, vdev_t *vd) avl_remove(&tm->tm_queued_frees, ts); avl_add(&tm->tm_inflight_frees, ts); zio_nowait(zio_trim(zio, spa, vd, ts->ts_start, - ts->ts_end - ts->ts_start)); + ts->ts_end - ts->ts_start, 0)); } mutex_exit(&tm->tm_lock); } diff --git a/module/zfs/vdev_label.c b/module/zfs/vdev_label.c index aeab374b8c4f..413cc3fa1759 100644 --- a/module/zfs/vdev_label.c +++ b/module/zfs/vdev_label.c @@ -697,7 +697,7 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason) */ if (!zfs_notrim && (reason == VDEV_LABEL_CREATE || reason == VDEV_LABEL_SPARE || reason == VDEV_LABEL_L2CACHE)) - zio_wait(zio_trim(NULL, spa, vd, 0, vd->vdev_psize)); + zio_wait(zio_trim(NULL, spa, vd, 0, vd->vdev_psize, 0)); /* * Initialize its label. diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 5ae6ff4f1f24..d24ec3480274 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -982,14 +982,16 @@ zio_flush(zio_t *zio, vdev_t *vd) } zio_t * -zio_trim(zio_t *zio, spa_t *spa, vdev_t *vd, uint64_t offset, uint64_t size) +zio_trim(zio_t *zio, spa_t *spa, vdev_t *vd, uint64_t offset, uint64_t size, + enum zio_flag flags) { ASSERT(vd->vdev_ops->vdev_op_leaf); return zio_ioctl(zio, spa, vd, DKIOCTRIM, offset, size, NULL, NULL, ZIO_PRIORITY_TRIM, - ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE | ZIO_FLAG_DONT_RETRY); + ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE | ZIO_FLAG_DONT_RETRY + | flags); } void