summaryrefslogtreecommitdiffstats
path: root/module/zfs/vdev_indirect.c
diff options
context:
space:
mode:
Diffstat (limited to 'module/zfs/vdev_indirect.c')
-rw-r--r--module/zfs/vdev_indirect.c74
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 */