diff options
Diffstat (limited to 'module/zfs/vdev_indirect.c')
-rw-r--r-- | module/zfs/vdev_indirect.c | 74 |
1 files changed, 45 insertions, 29 deletions
diff --git a/module/zfs/vdev_indirect.c b/module/zfs/vdev_indirect.c index d57bb717a..097be6f0e 100644 --- a/module/zfs/vdev_indirect.c +++ b/module/zfs/vdev_indirect.c @@ -420,15 +420,16 @@ vdev_indirect_should_condense(vdev_t *vd) * If nothing new has been marked obsolete, there is no * point in condensing. */ + ASSERTV(uint64_t obsolete_sm_obj); + ASSERT0(vdev_obsolete_sm_object(vd, &obsolete_sm_obj)); if (vd->vdev_obsolete_sm == NULL) { - ASSERT0(vdev_obsolete_sm_object(vd)); + ASSERT0(obsolete_sm_obj); return (B_FALSE); } ASSERT(vd->vdev_obsolete_sm != NULL); - ASSERT3U(vdev_obsolete_sm_object(vd), ==, - space_map_object(vd->vdev_obsolete_sm)); + ASSERT3U(obsolete_sm_obj, ==, space_map_object(vd->vdev_obsolete_sm)); uint64_t bytes_mapped = vdev_indirect_mapping_bytes_mapped(vim); uint64_t bytes_obsolete = space_map_allocated(vd->vdev_obsolete_sm); @@ -770,8 +771,9 @@ spa_condense_indirect_start_sync(vdev_t *vd, dmu_tx_t *tx) ASSERT(spa_feature_is_active(spa, SPA_FEATURE_OBSOLETE_COUNTS)); ASSERT(vdev_indirect_mapping_num_entries(vd->vdev_indirect_mapping)); - uint64_t obsolete_sm_obj = vdev_obsolete_sm_object(vd); - ASSERT(obsolete_sm_obj != 0); + uint64_t obsolete_sm_obj; + VERIFY0(vdev_obsolete_sm_object(vd, &obsolete_sm_obj)); + ASSERT3U(obsolete_sm_obj, !=, 0); scip->scip_vdev = vd->vdev_id; scip->scip_next_mapping_object = @@ -822,16 +824,18 @@ vdev_indirect_sync_obsolete(vdev_t *vd, dmu_tx_t *tx) ASSERT(vd->vdev_removing || vd->vdev_ops == &vdev_indirect_ops); ASSERT(spa_feature_is_enabled(spa, SPA_FEATURE_OBSOLETE_COUNTS)); - if (vdev_obsolete_sm_object(vd) == 0) { - uint64_t obsolete_sm_object = - space_map_alloc(spa->spa_meta_objset, + uint64_t obsolete_sm_object; + VERIFY0(vdev_obsolete_sm_object(vd, &obsolete_sm_object)); + if (obsolete_sm_object == 0) { + obsolete_sm_object = space_map_alloc(spa->spa_meta_objset, vdev_standard_sm_blksz, tx); ASSERT(vd->vdev_top_zap != 0); VERIFY0(zap_add(vd->vdev_spa->spa_meta_objset, vd->vdev_top_zap, VDEV_TOP_ZAP_INDIRECT_OBSOLETE_SM, sizeof (obsolete_sm_object), 1, &obsolete_sm_object, tx)); - ASSERT3U(vdev_obsolete_sm_object(vd), !=, 0); + ASSERT0(vdev_obsolete_sm_object(vd, &obsolete_sm_object)); + ASSERT3U(obsolete_sm_object, !=, 0); spa_feature_incr(spa, SPA_FEATURE_OBSOLETE_COUNTS, tx); VERIFY0(space_map_open(&vd->vdev_obsolete_sm, @@ -841,7 +845,7 @@ vdev_indirect_sync_obsolete(vdev_t *vd, dmu_tx_t *tx) } ASSERT(vd->vdev_obsolete_sm != NULL); - ASSERT3U(vdev_obsolete_sm_object(vd), ==, + ASSERT3U(obsolete_sm_object, ==, space_map_object(vd->vdev_obsolete_sm)); space_map_write(vd->vdev_obsolete_sm, @@ -889,44 +893,56 @@ spa_start_indirect_condensing_thread(spa_t *spa) } /* - * Gets the obsolete spacemap object from the vdev's ZAP. - * Returns the spacemap object, or 0 if it wasn't in the ZAP or the ZAP doesn't - * exist yet. + * Gets the obsolete spacemap object from the vdev's ZAP. On success sm_obj + * will contain either the obsolete spacemap object or zero if none exists. + * All other errors are returned to the caller. */ int -vdev_obsolete_sm_object(vdev_t *vd) +vdev_obsolete_sm_object(vdev_t *vd, uint64_t *sm_obj) { ASSERT0(spa_config_held(vd->vdev_spa, SCL_ALL, RW_WRITER)); + if (vd->vdev_top_zap == 0) { + *sm_obj = 0; return (0); } - uint64_t sm_obj = 0; - int err; - err = zap_lookup(vd->vdev_spa->spa_meta_objset, vd->vdev_top_zap, - VDEV_TOP_ZAP_INDIRECT_OBSOLETE_SM, sizeof (sm_obj), 1, &sm_obj); - - ASSERT(err == 0 || err == ENOENT); + int error = zap_lookup(vd->vdev_spa->spa_meta_objset, vd->vdev_top_zap, + VDEV_TOP_ZAP_INDIRECT_OBSOLETE_SM, sizeof (sm_obj), 1, sm_obj); + if (error == ENOENT) { + *sm_obj = 0; + error = 0; + } - return (sm_obj); + return (error); } -boolean_t -vdev_obsolete_counts_are_precise(vdev_t *vd) +/* + * Gets the obsolete count are precise spacemap object from the vdev's ZAP. + * On success are_precise will be set to reflect if the counts are precise. + * All other errors are returned to the caller. + */ +int +vdev_obsolete_counts_are_precise(vdev_t *vd, boolean_t *are_precise) { ASSERT0(spa_config_held(vd->vdev_spa, SCL_ALL, RW_WRITER)); + if (vd->vdev_top_zap == 0) { - return (B_FALSE); + *are_precise = B_FALSE; + return (0); } uint64_t val = 0; - int err; - err = zap_lookup(vd->vdev_spa->spa_meta_objset, vd->vdev_top_zap, + int error = zap_lookup(vd->vdev_spa->spa_meta_objset, vd->vdev_top_zap, VDEV_TOP_ZAP_OBSOLETE_COUNTS_ARE_PRECISE, sizeof (val), 1, &val); + if (error == 0) { + *are_precise = (val != 0); + } else if (error == ENOENT) { + *are_precise = B_FALSE; + error = 0; + } - ASSERT(err == 0 || err == ENOENT); - - return (val != 0); + return (error); } /* ARGSUSED */ |