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

Function vdev_rebuild_range

freebsd/contrib/openzfs/module/zfs/vdev_rebuild.c:535–608  ·  view source on GitHub ↗

* Issues a rebuild I/O and takes care of rate limiting the number of queued * rebuild I/Os. The provided start and size must be properly aligned for the * top-level vdev type being rebuilt. */

Source from the content-addressed store, hash-verified

533 * top-level vdev type being rebuilt.
534 */
535static int
536vdev_rebuild_range(vdev_rebuild_t *vr, uint64_t start, uint64_t size)
537{
538 uint64_t ms_id __maybe_unused = vr->vr_scan_msp->ms_id;
539 vdev_t *vd = vr->vr_top_vdev;
540 spa_t *spa = vd->vdev_spa;
541 blkptr_t blk;
542
543 ASSERT3U(ms_id, ==, start >> vd->vdev_ms_shift);
544 ASSERT3U(ms_id, ==, (start + size - 1) >> vd->vdev_ms_shift);
545
546 vr->vr_pass_bytes_scanned += size;
547 vr->vr_rebuild_phys.vrp_bytes_scanned += size;
548
549 /*
550 * Rebuild the data in this range by constructing a special block
551 * pointer. It has no relation to any existing blocks in the pool.
552 * However, by disabling checksum verification and issuing a scrub IO
553 * we can reconstruct and repair any children with missing data.
554 */
555 vdev_rebuild_blkptr_init(&blk, vd, start, size);
556 uint64_t psize = BP_GET_PSIZE(&blk);
557
558 if (!vdev_dtl_need_resilver(vd, &blk.blk_dva[0], psize, TXG_UNKNOWN))
559 return (0);
560
561 mutex_enter(&vr->vr_io_lock);
562
563 /* Limit in flight rebuild I/Os */
564 while (vr->vr_bytes_inflight >= vr->vr_bytes_inflight_max)
565 cv_wait(&vr->vr_io_cv, &vr->vr_io_lock);
566
567 vr->vr_bytes_inflight += psize;
568 mutex_exit(&vr->vr_io_lock);
569
570 dmu_tx_t *tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
571 VERIFY0(dmu_tx_assign(tx, TXG_WAIT));
572 uint64_t txg = dmu_tx_get_txg(tx);
573
574 spa_config_enter(spa, SCL_STATE_ALL, vd, RW_READER);
575 mutex_enter(&vd->vdev_rebuild_lock);
576
577 /* This is the first I/O for this txg. */
578 if (vr->vr_scan_offset[txg & TXG_MASK] == 0) {
579 vr->vr_scan_offset[txg & TXG_MASK] = start;
580 dsl_sync_task_nowait(spa_get_dsl(spa),
581 vdev_rebuild_update_sync,
582 (void *)(uintptr_t)vd->vdev_id, tx);
583 }
584
585 /* When exiting write out our progress. */
586 if (vdev_rebuild_should_stop(vd)) {
587 mutex_enter(&vr->vr_io_lock);
588 vr->vr_bytes_inflight -= psize;
589 mutex_exit(&vr->vr_io_lock);
590 spa_config_exit(vd->vdev_spa, SCL_STATE_ALL, vd);
591 mutex_exit(&vd->vdev_rebuild_lock);
592 dmu_tx_commit(tx);

Callers 1

vdev_rebuild_rangesFunction · 0.85

Calls 15

vdev_rebuild_blkptr_initFunction · 0.85
vdev_dtl_need_resilverFunction · 0.85
mutex_enterFunction · 0.85
cv_waitFunction · 0.85
mutex_exitFunction · 0.85
dmu_tx_create_ddFunction · 0.85
spa_get_dslFunction · 0.85
dmu_tx_assignFunction · 0.85
dmu_tx_get_txgFunction · 0.85
spa_config_enterFunction · 0.85
dsl_sync_task_nowaitFunction · 0.85
vdev_rebuild_should_stopFunction · 0.85

Tested by

no test coverage detected