From 8cbb5cd1d4d8359a1a733702da41b114622f7e6a Mon Sep 17 00:00:00 2001 From: Etienne Dechamps Date: Thu, 20 Sep 2012 16:39:13 +0200 Subject: [PATCH] TRIM the whole vdev on create/add/attach. With this patch, ZFS will attempt to TRIM the whole vdev in the following cases: - zpool create, zpool add, zpool attach any vdev - zpool import spare and L2ARC devices We do this to make sure we start from a "clean state". This way, the physical device knows that all the data it held before it was added to the pool is now obsolete. This is similar to what mke2fs does. --- include/sys/zio.h | 3 ++- module/zfs/trim_map.c | 3 ++- module/zfs/vdev_label.c | 10 ++++++++++ module/zfs/zio.c | 8 ++++---- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/include/sys/zio.h b/include/sys/zio.h index 737d6a49d6c2..8cb939d46916 100644 --- a/include/sys/zio.h +++ b/include/sys/zio.h @@ -516,7 +516,8 @@ extern int zio_alloc_zil(spa_t *spa, uint64_t txg, blkptr_t *new_bp, blkptr_t *old_bp, uint64_t size, boolean_t use_slog); 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 void zio_trim(zio_t *zio, vdev_t *vd, uint64_t offset, uint64_t size); +extern zio_t *zio_trim(zio_t *zio, spa_t *spa, vdev_t *vd, + uint64_t offset, uint64_t size); extern void zio_shrink(zio_t *zio, uint64_t size); extern int zio_wait(zio_t *zio); diff --git a/module/zfs/trim_map.c b/module/zfs/trim_map.c index c8591c557e2e..608921fc731d 100644 --- a/module/zfs/trim_map.c +++ b/module/zfs/trim_map.c @@ -392,7 +392,8 @@ trim_map_vdev_commit(spa_t *spa, zio_t *zio, vdev_t *vd) list_remove(&tm->tm_head, ts); avl_remove(&tm->tm_queued_frees, ts); avl_add(&tm->tm_inflight_frees, ts); - zio_trim(zio, vd, ts->ts_start, ts->ts_end - ts->ts_start); + zio_nowait(zio_trim(zio, spa, vd, ts->ts_start, + ts->ts_end - ts->ts_start)); } mutex_exit(&tm->tm_lock); } diff --git a/module/zfs/vdev_label.c b/module/zfs/vdev_label.c index 16071520b2d9..043ece16c4c4 100644 --- a/module/zfs/vdev_label.c +++ b/module/zfs/vdev_label.c @@ -688,6 +688,16 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason) return (0); ASSERT(reason == VDEV_LABEL_REPLACE); } + + /* + * TRIM the whole thing so that we start with a clean slate. + * It's just an optimization, so we don't care if it fails. + * Don't TRIM if removing so that we don't interfere with zpool + * disaster recovery. + */ + if (reason == VDEV_LABEL_CREATE || reason == VDEV_LABEL_SPARE + || reason == VDEV_LABEL_L2CACHE) + zio_wait(zio_trim(NULL, spa, vd, 0, vd->vdev_psize)); /* * Initialize its label. diff --git a/module/zfs/zio.c b/module/zfs/zio.c index d862a5ee42a1..a1a84d16f4e5 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -981,15 +981,15 @@ zio_flush(zio_t *zio, vdev_t *vd) ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE | ZIO_FLAG_DONT_RETRY)); } -void -zio_trim(zio_t *zio, vdev_t *vd, uint64_t offset, uint64_t size) +zio_t * +zio_trim(zio_t *zio, spa_t *spa, vdev_t *vd, uint64_t offset, uint64_t size) { ASSERT(vd->vdev_ops->vdev_op_leaf); - zio_nowait(zio_ioctl(zio, zio->io_spa, vd, DKIOCTRIM, offset, size, + 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); } void