MCPcopy Create free account
hub / github.com/F-Stack/f-stack / spa_vdev_remove_thread

Function spa_vdev_remove_thread

freebsd/contrib/openzfs/module/zfs/vdev_removal.c:1406–1600  ·  view source on GitHub ↗

* The removal thread operates in open context. It iterates over all * allocated space in the vdev, by loading each metaslab's spacemap. * For each contiguous segment of allocated space (capping the segment * size at SPA_MAXBLOCKSIZE), we: * - Allocate space for it on another vdev. * - Create a new mapping from the old location to the new location * (as a record in svr_new_segment

Source from the content-addressed store, hash-verified

1404 * (see vdev_mapping_sync()).
1405 */
1406static void
1407spa_vdev_remove_thread(void *arg)
1408{
1409 spa_t *spa = arg;
1410 spa_vdev_removal_t *svr = spa->spa_vdev_removal;
1411 vdev_copy_arg_t vca;
1412 uint64_t max_alloc = spa_remove_max_segment(spa);
1413 uint64_t last_txg = 0;
1414
1415 spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
1416 vdev_t *vd = vdev_lookup_top(spa, svr->svr_vdev_id);
1417 vdev_indirect_mapping_t *vim = vd->vdev_indirect_mapping;
1418 uint64_t start_offset = vdev_indirect_mapping_max_offset(vim);
1419
1420 ASSERT3P(vd->vdev_ops, !=, &vdev_indirect_ops);
1421 ASSERT(vdev_is_concrete(vd));
1422 ASSERT(vd->vdev_removing);
1423 ASSERT(vd->vdev_indirect_config.vic_mapping_object != 0);
1424 ASSERT(vim != NULL);
1425
1426 mutex_init(&vca.vca_lock, NULL, MUTEX_DEFAULT, NULL);
1427 cv_init(&vca.vca_cv, NULL, CV_DEFAULT, NULL);
1428 vca.vca_outstanding_bytes = 0;
1429 vca.vca_read_error_bytes = 0;
1430 vca.vca_write_error_bytes = 0;
1431
1432 mutex_enter(&svr->svr_lock);
1433
1434 /*
1435 * Start from vim_max_offset so we pick up where we left off
1436 * if we are restarting the removal after opening the pool.
1437 */
1438 uint64_t msi;
1439 for (msi = start_offset >> vd->vdev_ms_shift;
1440 msi < vd->vdev_ms_count && !svr->svr_thread_exit; msi++) {
1441 metaslab_t *msp = vd->vdev_ms[msi];
1442 ASSERT3U(msi, <=, vd->vdev_ms_count);
1443
1444 ASSERT0(range_tree_space(svr->svr_allocd_segs));
1445
1446 mutex_enter(&msp->ms_sync_lock);
1447 mutex_enter(&msp->ms_lock);
1448
1449 /*
1450 * Assert nothing in flight -- ms_*tree is empty.
1451 */
1452 for (int i = 0; i < TXG_SIZE; i++) {
1453 ASSERT0(range_tree_space(msp->ms_allocating[i]));
1454 }
1455
1456 /*
1457 * If the metaslab has ever been allocated from (ms_sm!=NULL),
1458 * read the allocated segments from the space map object
1459 * into svr_allocd_segs. Since we do this while holding
1460 * svr_lock and ms_sync_lock, concurrent frees (which
1461 * would have modified the space map) will wait for us
1462 * to finish loading the spacemap, and then take the
1463 * appropriate action (see free_from_removing_vdev()).

Callers

nothing calls this directly

Calls 15

spa_remove_max_segmentFunction · 0.85
spa_config_enterFunction · 0.85
vdev_lookup_topFunction · 0.85
vdev_is_concreteFunction · 0.85
mutex_enterFunction · 0.85
range_tree_spaceFunction · 0.85
space_map_loadFunction · 0.85
range_tree_walkFunction · 0.85
range_tree_clearFunction · 0.85
mutex_exitFunction · 0.85
zfs_btree_numnodesFunction · 0.85

Tested by

no test coverage detected