aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/spa.c
diff options
context:
space:
mode:
authorAlexander Motin <[email protected]>2022-02-04 16:06:38 -0500
committerGitHub <[email protected]>2022-02-04 13:06:38 -0800
commitf2c5bc150e609a78185ea63c84fce7718f56e28a (patch)
tree7edac1f0f1869281959bea3a3943527d2344ff56 /module/zfs/spa.c
parent2f14adacaa8211f4d628f905986005246602b2ac (diff)
Add more control/visibility to spa_load_verify().
Use error thresholds from policy to control whether to scrub data and/or metadata. If threshold is set to UINT64_MAX, then caller probably does not care about result and we may skip that part. By default import neither set the data error threshold nor read the error counter, so skip the data scrub for faster import. Metadata are still scrubbed and fail if even single error found. While there just for symmetry return number of metadata errors in case threshold is not set to zero and we haven't reached it. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Pavel Zakharov <[email protected]> Signed-off-by: Alexander Motin <[email protected]> Closes #13022
Diffstat (limited to 'module/zfs/spa.c')
-rw-r--r--module/zfs/spa.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/module/zfs/spa.c b/module/zfs/spa.c
index d35e14c79..7e18048af 100644
--- a/module/zfs/spa.c
+++ b/module/zfs/spa.c
@@ -2251,6 +2251,7 @@ spa_claim_notify(zio_t *zio)
}
typedef struct spa_load_error {
+ boolean_t sle_verify_data;
uint64_t sle_meta_count;
uint64_t sle_data_count;
} spa_load_error_t;
@@ -2291,6 +2292,9 @@ static int
spa_load_verify_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
const zbookmark_phys_t *zb, const dnode_phys_t *dnp, void *arg)
{
+ zio_t *rio = arg;
+ spa_load_error_t *sle = rio->io_private;
+
(void) zilog, (void) dnp;
if (zb->zb_level == ZB_DNODE_LEVEL || BP_IS_HOLE(bp) ||
@@ -2303,12 +2307,12 @@ spa_load_verify_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
*/
if (!spa_load_verify_metadata)
return (0);
- if (!BP_IS_METADATA(bp) && !spa_load_verify_data)
+ if (!BP_IS_METADATA(bp) &&
+ (!spa_load_verify_data || !sle->sle_verify_data))
return (0);
uint64_t maxinflight_bytes =
arc_target_bytes() >> spa_load_verify_shift;
- zio_t *rio = arg;
size_t size = BP_GET_PSIZE(bp);
mutex_enter(&spa->spa_scrub_lock);
@@ -2346,7 +2350,8 @@ spa_load_verify(spa_t *spa)
zpool_get_load_policy(spa->spa_config, &policy);
- if (policy.zlp_rewind & ZPOOL_NEVER_REWIND)
+ if (policy.zlp_rewind & ZPOOL_NEVER_REWIND ||
+ policy.zlp_maxmeta == UINT64_MAX)
return (0);
dsl_pool_config_enter(spa->spa_dsl_pool, FTAG);
@@ -2357,6 +2362,13 @@ spa_load_verify(spa_t *spa)
if (error != 0)
return (error);
+ /*
+ * Verify data only if we are rewinding or error limit was set.
+ * Otherwise nothing except dbgmsg care about it to waste time.
+ */
+ sle.sle_verify_data = (policy.zlp_rewind & ZPOOL_REWIND_MASK) ||
+ (policy.zlp_maxdata < UINT64_MAX);
+
rio = zio_root(spa, NULL, &sle,
ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE);
@@ -2401,6 +2413,8 @@ spa_load_verify(spa_t *spa)
fnvlist_add_int64(spa->spa_load_info, ZPOOL_CONFIG_REWIND_TIME,
loss);
fnvlist_add_uint64(spa->spa_load_info,
+ ZPOOL_CONFIG_LOAD_META_ERRORS, sle.sle_meta_count);
+ fnvlist_add_uint64(spa->spa_load_info,
ZPOOL_CONFIG_LOAD_DATA_ERRORS, sle.sle_data_count);
} else {
spa->spa_load_max_txg = spa->spa_uberblock.ub_txg;