245
246 vd->vdev_spa->spa_checkpoint_info.sci_dspace -= sme->sme_run;
247 vd->vdev_stat.vs_checkpoint_space -= sme->sme_run;
248 sdc->sdc_entry_limit--;
249
250 return (0);
251 }
252
253 static void
254 spa_checkpoint_accounting_verify(spa_t *spa)
255 {
256 vdev_t *rvd = spa->spa_root_vdev;
257 uint64_t ckpoint_sm_space_sum = 0;
258 uint64_t vs_ckpoint_space_sum = 0;
259
260 for (uint64_t c = 0; c < rvd->vdev_children; c++) {
261 vdev_t *vd = rvd->vdev_child[c];
262
263 if (vd->vdev_checkpoint_sm != NULL) {
264 ckpoint_sm_space_sum +=
265 -vd->vdev_checkpoint_sm->sm_alloc;
266 vs_ckpoint_space_sum +=
267 vd->vdev_stat.vs_checkpoint_space;
268 ASSERT3U(ckpoint_sm_space_sum, ==,
269 vs_ckpoint_space_sum);
270 } else {
271 ASSERT0(vd->vdev_stat.vs_checkpoint_space);
272 }
273 }
274 ASSERT3U(spa->spa_checkpoint_info.sci_dspace, ==, ckpoint_sm_space_sum);
275 }
276
277 static void
278 spa_checkpoint_discard_thread_sync(void *arg, dmu_tx_t *tx)
279 {
280 vdev_t *vd = arg;
281 int error;
282
283 /*
284 * The space map callback is applied only to non-debug entries.
285 * Because the number of debug entries is less or equal to the
330 uint64_t words_after =
331 space_map_length(vd->vdev_checkpoint_sm) / sizeof (uint64_t);
332
333 #ifdef DEBUG
334 spa_checkpoint_accounting_verify(vd->vdev_spa);
335 #endif
336
337 zfs_dbgmsg("discarding checkpoint: txg %llu, vdev id %d, "
338 "deleted %llu words - %llu words are left",
339 tx->tx_txg, vd->vdev_id, (words_before - words_after),
340 words_after);
341
342 if (error != EINTR) {
343 if (error != 0) {
344 zfs_panic_recover("zfs: error %d was returned "
345 "while incrementally destroying the checkpoint "
346 "space map of vdev %llu\n",
347 error, vd->vdev_id);
348 }
349 ASSERT0(words_after);
350 ASSERT0(vd->vdev_checkpoint_sm->sm_alloc);
351 ASSERT0(space_map_length(vd->vdev_checkpoint_sm));
352
353 space_map_free(vd->vdev_checkpoint_sm, tx);
354 space_map_close(vd->vdev_checkpoint_sm);
355 vd->vdev_checkpoint_sm = NULL;
356
357 VERIFY0(zap_remove(spa_meta_objset(vd->vdev_spa),
358 vd->vdev_top_zap, VDEV_TOP_ZAP_POOL_CHECKPOINT_SM, tx));
359 }
360 }
361
362 static boolean_t
363 spa_checkpoint_discard_is_done(spa_t *spa)
364 {
365 vdev_t *rvd = spa->spa_root_vdev;
366
367 ASSERT(!spa_has_checkpoint(spa));
368 ASSERT(spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT));
369
370 for (uint64_t c = 0; c < rvd->vdev_children; c++) {
|
245
246 vd->vdev_spa->spa_checkpoint_info.sci_dspace -= sme->sme_run;
247 vd->vdev_stat.vs_checkpoint_space -= sme->sme_run;
248 sdc->sdc_entry_limit--;
249
250 return (0);
251 }
252
253 static void
254 spa_checkpoint_accounting_verify(spa_t *spa)
255 {
256 vdev_t *rvd = spa->spa_root_vdev;
257 uint64_t ckpoint_sm_space_sum = 0;
258 uint64_t vs_ckpoint_space_sum = 0;
259
260 for (uint64_t c = 0; c < rvd->vdev_children; c++) {
261 vdev_t *vd = rvd->vdev_child[c];
262
263 if (vd->vdev_checkpoint_sm != NULL) {
264 ckpoint_sm_space_sum +=
265 -space_map_allocated(vd->vdev_checkpoint_sm);
266 vs_ckpoint_space_sum +=
267 vd->vdev_stat.vs_checkpoint_space;
268 ASSERT3U(ckpoint_sm_space_sum, ==,
269 vs_ckpoint_space_sum);
270 } else {
271 ASSERT0(vd->vdev_stat.vs_checkpoint_space);
272 }
273 }
274 ASSERT3U(spa->spa_checkpoint_info.sci_dspace, ==, ckpoint_sm_space_sum);
275 }
276
277 static void
278 spa_checkpoint_discard_thread_sync(void *arg, dmu_tx_t *tx)
279 {
280 vdev_t *vd = arg;
281 int error;
282
283 /*
284 * The space map callback is applied only to non-debug entries.
285 * Because the number of debug entries is less or equal to the
330 uint64_t words_after =
331 space_map_length(vd->vdev_checkpoint_sm) / sizeof (uint64_t);
332
333 #ifdef DEBUG
334 spa_checkpoint_accounting_verify(vd->vdev_spa);
335 #endif
336
337 zfs_dbgmsg("discarding checkpoint: txg %llu, vdev id %d, "
338 "deleted %llu words - %llu words are left",
339 tx->tx_txg, vd->vdev_id, (words_before - words_after),
340 words_after);
341
342 if (error != EINTR) {
343 if (error != 0) {
344 zfs_panic_recover("zfs: error %d was returned "
345 "while incrementally destroying the checkpoint "
346 "space map of vdev %llu\n",
347 error, vd->vdev_id);
348 }
349 ASSERT0(words_after);
350 ASSERT0(space_map_allocated(vd->vdev_checkpoint_sm));
351 ASSERT0(space_map_length(vd->vdev_checkpoint_sm));
352
353 space_map_free(vd->vdev_checkpoint_sm, tx);
354 space_map_close(vd->vdev_checkpoint_sm);
355 vd->vdev_checkpoint_sm = NULL;
356
357 VERIFY0(zap_remove(spa_meta_objset(vd->vdev_spa),
358 vd->vdev_top_zap, VDEV_TOP_ZAP_POOL_CHECKPOINT_SM, tx));
359 }
360 }
361
362 static boolean_t
363 spa_checkpoint_discard_is_done(spa_t *spa)
364 {
365 vdev_t *rvd = spa->spa_root_vdev;
366
367 ASSERT(!spa_has_checkpoint(spa));
368 ASSERT(spa_feature_is_active(spa, SPA_FEATURE_POOL_CHECKPOINT));
369
370 for (uint64_t c = 0; c < rvd->vdev_children; c++) {
|