Print this page
10592 misc. metaslab and vdev related ZoL bug fixes
Portions contributed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed by: Giuseppe Di Natale <guss80@gmail.com>
Reviewed by: George Melikov <mail@gmelikov.ru>
Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: Pavel Zakharov <pavel.zakharov@delphix.com>
Reviewed by: Tony Hutter <hutter2@llnl.gov>
Reviewed by: Kody Kantor <kody.kantor@joyent.com>
Approved by: Dan McDonald <danmcd@joyent.com>


 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++) {