mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-24 03:08:51 +03:00
Add ability to scrub from last scrubbed txg
Some users might want to scrub only new data because they would like to know if the new write wasn't corrupted. This PR adds possibility scrub only newly written data. This introduces new `last_scrubbed_txg` property, indicating the transaction group (TXG) up to which the most recent scrub operation has checked and repaired the dataset, so users can run scrub only from the last saved point. We use a scn_max_txg and scn_min_txg which are already built into scrub, to accomplish that. Reviewed-by: Allan Jude <allan@klarasystems.com> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Mariusz Zaborski <mariusz.zaborski@klarasystems.com> Sponsored-By: Wasabi Technology, Inc. Sponsored-By: Klara Inc. Closes #16301
This commit is contained in:
+20
-2
@@ -451,9 +451,10 @@ spa_prop_get_config(spa_t *spa, nvlist_t *nv)
|
||||
|
||||
spa_prop_add_list(nv, ZPOOL_PROP_DEDUP_TABLE_SIZE, NULL,
|
||||
ddt_get_ddt_dsize(spa), src);
|
||||
|
||||
spa_prop_add_list(nv, ZPOOL_PROP_HEALTH, NULL,
|
||||
rvd->vdev_state, src);
|
||||
spa_prop_add_list(nv, ZPOOL_PROP_LAST_SCRUBBED_TXG, NULL,
|
||||
spa_get_last_scrubbed_txg(spa), src);
|
||||
|
||||
version = spa_version(spa);
|
||||
if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION)) {
|
||||
@@ -4727,6 +4728,12 @@ spa_ld_get_props(spa_t *spa)
|
||||
if (error != 0 && error != ENOENT)
|
||||
return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
|
||||
|
||||
/* Load the last scrubbed txg. */
|
||||
error = spa_dir_prop(spa, DMU_POOL_LAST_SCRUBBED_TXG,
|
||||
&spa->spa_scrubbed_last_txg, B_FALSE);
|
||||
if (error != 0 && error != ENOENT)
|
||||
return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
|
||||
|
||||
/*
|
||||
* Load the livelist deletion field. If a livelist is queued for
|
||||
* deletion, indicate that in the spa
|
||||
@@ -8869,6 +8876,13 @@ spa_scan_stop(spa_t *spa)
|
||||
|
||||
int
|
||||
spa_scan(spa_t *spa, pool_scan_func_t func)
|
||||
{
|
||||
return (spa_scan_range(spa, func, 0, 0));
|
||||
}
|
||||
|
||||
int
|
||||
spa_scan_range(spa_t *spa, pool_scan_func_t func, uint64_t txgstart,
|
||||
uint64_t txgend)
|
||||
{
|
||||
ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == 0);
|
||||
|
||||
@@ -8879,6 +8893,9 @@ spa_scan(spa_t *spa, pool_scan_func_t func)
|
||||
!spa_feature_is_enabled(spa, SPA_FEATURE_RESILVER_DEFER))
|
||||
return (SET_ERROR(ENOTSUP));
|
||||
|
||||
if (func != POOL_SCAN_SCRUB && (txgstart != 0 || txgend != 0))
|
||||
return (SET_ERROR(ENOTSUP));
|
||||
|
||||
/*
|
||||
* If a resilver was requested, but there is no DTL on a
|
||||
* writeable leaf device, we have nothing to do.
|
||||
@@ -8893,7 +8910,7 @@ spa_scan(spa_t *spa, pool_scan_func_t func)
|
||||
!spa_feature_is_enabled(spa, SPA_FEATURE_HEAD_ERRLOG))
|
||||
return (SET_ERROR(ENOTSUP));
|
||||
|
||||
return (dsl_scan(spa->spa_dsl_pool, func));
|
||||
return (dsl_scan(spa->spa_dsl_pool, func, txgstart, txgend));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -10976,6 +10993,7 @@ EXPORT_SYMBOL(spa_l2cache_drop);
|
||||
|
||||
/* scanning */
|
||||
EXPORT_SYMBOL(spa_scan);
|
||||
EXPORT_SYMBOL(spa_scan_range);
|
||||
EXPORT_SYMBOL(spa_scan_stop);
|
||||
|
||||
/* spa syncing */
|
||||
|
||||
Reference in New Issue
Block a user