diff options
author | smh <smh@FreeBSD.org> | 2013-03-21 10:16:10 +0000 |
---|---|---|
committer | smh <smh@FreeBSD.org> | 2013-03-21 10:16:10 +0000 |
commit | 3db2bd548a96440bd699b58b1b5d6f610b3caff2 (patch) | |
tree | 2b795a7d020f9562d4f20f1ce9188d961bef7515 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c | |
parent | f8b4607ac92c9c001eb2197ae2267368be41f2c2 (diff) | |
download | FreeBSD-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/contrib/opensolaris/uts/common/fs/zfs/trim_map.c')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c | 9 |
1 files changed, 4 insertions, 5 deletions
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) { |