summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authorsmh <smh@FreeBSD.org>2013-03-21 10:16:10 +0000
committersmh <smh@FreeBSD.org>2013-03-21 10:16:10 +0000
commit3db2bd548a96440bd699b58b1b5d6f610b3caff2 (patch)
tree2b795a7d020f9562d4f20f1ce9188d961bef7515 /sys/cddl
parentf8b4607ac92c9c001eb2197ae2267368be41f2c2 (diff)
downloadFreeBSD-src-3db2bd548a96440bd699b58b1b5d6f610b3caff2.zip
FreeBSD-src-3db2bd548a96440bd699b58b1b5d6f610b3caff2.tar.gz
Improve TXG handling in the TRIM module.
This patch adds some improvements to the way the trim module considers TXGs: - Free ZIOs are registered with the TXG from the ZIO itself, not the current SPA syncing TXG (which may be out of date); - L2ARC are registered with a zero TXG number, as L2ARC has no concept of TXGs; - The TXG limit for issuing TRIMs is now computed from the last synced TXG, not the currently syncing TXG. Indeed, under extremely unlikely race conditions, there is a risk we could trim blocks which have been freed in a TXG that has not finished syncing, resulting in potential data corruption in case of a crash. Reviewed by: pjd (mentor) Approved by: pjd (mentor) Obtained from: https://github.com/dechamps/zfs/commit/5b46ad40d9081d75505d6f3bf04ac652445df366 MFC after: 2 weeks
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c6
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/trim_map.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c9
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c2
4 files changed, 9 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 3ac20d0..906ff63 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
@@ -1693,7 +1693,7 @@ arc_hdr_destroy(arc_buf_hdr_t *hdr)
if (l2hdr != NULL) {
trim_map_free(l2hdr->b_dev->l2ad_vdev, l2hdr->b_daddr,
- hdr->b_size);
+ hdr->b_size, 0);
list_remove(l2hdr->b_dev->l2ad_buflist, hdr);
ARCSTAT_INCR(arcstat_l2_size, -hdr->b_size);
kmem_free(l2hdr, sizeof (l2arc_buf_hdr_t));
@@ -3532,7 +3532,7 @@ arc_release(arc_buf_t *buf, void *tag)
if (l2hdr) {
trim_map_free(l2hdr->b_dev->l2ad_vdev, l2hdr->b_daddr,
- hdr->b_size);
+ hdr->b_size, 0);
list_remove(l2hdr->b_dev->l2ad_buflist, hdr);
kmem_free(l2hdr, sizeof (l2arc_buf_hdr_t));
ARCSTAT_INCR(arcstat_l2_size, -buf_size);
@@ -4448,7 +4448,7 @@ l2arc_write_done(zio_t *zio)
abl2 = ab->b_l2hdr;
ab->b_l2hdr = NULL;
trim_map_free(abl2->b_dev->l2ad_vdev, abl2->b_daddr,
- ab->b_size);
+ ab->b_size, 0);
kmem_free(abl2, sizeof (l2arc_buf_hdr_t));
ARCSTAT_INCR(arcstat_l2_size, -ab->b_size);
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/trim_map.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/trim_map.h
index 4f06256..f228d07 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/trim_map.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/trim_map.h
@@ -36,7 +36,7 @@ extern "C" {
extern void trim_map_create(vdev_t *vd);
extern void trim_map_destroy(vdev_t *vd);
-extern void trim_map_free(vdev_t *vd, uint64_t offset, uint64_t size);
+extern void trim_map_free(vdev_t *vd, uint64_t offset, uint64_t size, uint64_t txg);
extern boolean_t trim_map_write_start(zio_t *zio);
extern void trim_map_write_done(zio_t *zio);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c
index bd24d4a..3a72936 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c
@@ -272,7 +272,7 @@ trim_map_free_locked(trim_map_t *tm, uint64_t start, uint64_t end, uint64_t txg)
}
void
-trim_map_free(vdev_t *vd, uint64_t offset, uint64_t size)
+trim_map_free(vdev_t *vd, uint64_t offset, uint64_t size, uint64_t txg)
{
trim_map_t *tm = vd->vdev_trimmap;
@@ -280,8 +280,7 @@ trim_map_free(vdev_t *vd, uint64_t offset, uint64_t size)
return;
mutex_enter(&tm->tm_lock);
- trim_map_free_locked(tm, offset, TRIM_ZIO_END(vd, offset, size),
- vd->vdev_spa->spa_syncing_txg);
+ trim_map_free_locked(tm, offset, TRIM_ZIO_END(vd, offset, size), txg);
mutex_exit(&tm->tm_lock);
}
@@ -387,7 +386,7 @@ trim_map_vdev_commit(spa_t *spa, zio_t *zio, vdev_t *vd)
if (tm == NULL)
return;
- txglimit = MIN(spa->spa_syncing_txg, spa_freeze_txg(spa)) -
+ txglimit = MIN(spa_last_synced_txg(spa), spa_freeze_txg(spa)) -
trim_txg_limit;
mutex_enter(&tm->tm_lock);
@@ -444,7 +443,7 @@ trim_map_commit(spa_t *spa, zio_t *zio, vdev_t *vd)
{
int c;
- if (vd == NULL || spa->spa_syncing_txg <= trim_txg_limit)
+ if (vd == NULL || spa_last_synced_txg(spa) <= trim_txg_limit)
return;
if (vd->vdev_ops->vdev_op_leaf) {
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
index a62dfeb..b1f43f3 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
@@ -2475,7 +2475,7 @@ zio_vdev_io_start(zio_t *zio)
}
if (vd->vdev_ops->vdev_op_leaf && zio->io_type == ZIO_TYPE_FREE) {
- trim_map_free(vd, zio->io_offset, zio->io_size);
+ trim_map_free(vd, zio->io_offset, zio->io_size, zio->io_txg);
return (ZIO_PIPELINE_CONTINUE);
}
OpenPOWER on IntegriCloud