Changeset View
Changeset View
Standalone View
Standalone View
sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
Show First 20 Lines • Show All 547 Lines • ▼ Show 20 Lines | vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops) | ||||
vd->vdev_guid_sum = guid; | vd->vdev_guid_sum = guid; | ||||
vd->vdev_ops = ops; | vd->vdev_ops = ops; | ||||
vd->vdev_state = VDEV_STATE_CLOSED; | vd->vdev_state = VDEV_STATE_CLOSED; | ||||
vd->vdev_ishole = (ops == &vdev_hole_ops); | vd->vdev_ishole = (ops == &vdev_hole_ops); | ||||
vic->vic_prev_indirect_vdev = UINT64_MAX; | vic->vic_prev_indirect_vdev = UINT64_MAX; | ||||
rw_init(&vd->vdev_indirect_rwlock, NULL, RW_DEFAULT, NULL); | rw_init(&vd->vdev_indirect_rwlock, NULL, RW_DEFAULT, NULL); | ||||
mutex_init(&vd->vdev_obsolete_lock, NULL, MUTEX_DEFAULT, NULL); | mutex_init(&vd->vdev_obsolete_lock, NULL, MUTEX_DEFAULT, NULL); | ||||
vd->vdev_obsolete_segments = range_tree_create(NULL, NULL); | vd->vdev_obsolete_segments = range_tree_create(NULL, NULL, &vd->vdev_obsolete_lock); | ||||
mutex_init(&vd->vdev_dtl_lock, NULL, MUTEX_DEFAULT, NULL); | mutex_init(&vd->vdev_dtl_lock, NULL, MUTEX_DEFAULT, NULL); | ||||
mutex_init(&vd->vdev_stat_lock, NULL, MUTEX_DEFAULT, NULL); | mutex_init(&vd->vdev_stat_lock, NULL, MUTEX_DEFAULT, NULL); | ||||
mutex_init(&vd->vdev_probe_lock, NULL, MUTEX_DEFAULT, NULL); | mutex_init(&vd->vdev_probe_lock, NULL, MUTEX_DEFAULT, NULL); | ||||
mutex_init(&vd->vdev_queue_lock, NULL, MUTEX_DEFAULT, NULL); | mutex_init(&vd->vdev_queue_lock, NULL, MUTEX_DEFAULT, NULL); | ||||
mutex_init(&vd->vdev_scan_io_queue_lock, NULL, MUTEX_DEFAULT, NULL); | |||||
for (int t = 0; t < DTL_TYPES; t++) { | for (int t = 0; t < DTL_TYPES; t++) { | ||||
vd->vdev_dtl[t] = range_tree_create(NULL, NULL); | vd->vdev_dtl[t] = range_tree_create(NULL, NULL, &vd->vdev_dtl_lock); | ||||
} | } | ||||
txg_list_create(&vd->vdev_ms_list, spa, | txg_list_create(&vd->vdev_ms_list, spa, | ||||
offsetof(struct metaslab, ms_txg_node)); | offsetof(struct metaslab, ms_txg_node)); | ||||
txg_list_create(&vd->vdev_dtl_list, spa, | txg_list_create(&vd->vdev_dtl_list, spa, | ||||
offsetof(struct vdev, vdev_dtl_node)); | offsetof(struct vdev, vdev_dtl_node)); | ||||
vd->vdev_stat.vs_timestamp = gethrtime(); | vd->vdev_stat.vs_timestamp = gethrtime(); | ||||
vdev_queue_init(vd); | vdev_queue_init(vd); | ||||
vdev_cache_init(vd); | vdev_cache_init(vd); | ||||
▲ Show 20 Lines • Show All 255 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void | void | ||||
vdev_free(vdev_t *vd) | vdev_free(vdev_t *vd) | ||||
{ | { | ||||
spa_t *spa = vd->vdev_spa; | spa_t *spa = vd->vdev_spa; | ||||
/* | /* | ||||
* Scan queues are normally destroyed at the end of a scan. If the | |||||
* queue exists here, that implies the vdev is being removed while | |||||
* the scan is still running. | |||||
*/ | |||||
if (vd->vdev_scan_io_queue != NULL) { | |||||
mutex_enter(&vd->vdev_scan_io_queue_lock); | |||||
dsl_scan_io_queue_destroy(vd->vdev_scan_io_queue); | |||||
vd->vdev_scan_io_queue = NULL; | |||||
mutex_exit(&vd->vdev_scan_io_queue_lock); | |||||
} | |||||
/* | |||||
* vdev_free() implies closing the vdev first. This is simpler than | * vdev_free() implies closing the vdev first. This is simpler than | ||||
* trying to ensure complicated semantics for all callers. | * trying to ensure complicated semantics for all callers. | ||||
*/ | */ | ||||
vdev_close(vd); | vdev_close(vd); | ||||
ASSERT(!list_link_active(&vd->vdev_config_dirty_node)); | ASSERT(!list_link_active(&vd->vdev_config_dirty_node)); | ||||
ASSERT(!list_link_active(&vd->vdev_state_dirty_node)); | ASSERT(!list_link_active(&vd->vdev_state_dirty_node)); | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | vdev_free(vdev_t *vd) | ||||
range_tree_destroy(vd->vdev_obsolete_segments); | range_tree_destroy(vd->vdev_obsolete_segments); | ||||
rw_destroy(&vd->vdev_indirect_rwlock); | rw_destroy(&vd->vdev_indirect_rwlock); | ||||
mutex_destroy(&vd->vdev_obsolete_lock); | mutex_destroy(&vd->vdev_obsolete_lock); | ||||
mutex_destroy(&vd->vdev_queue_lock); | mutex_destroy(&vd->vdev_queue_lock); | ||||
mutex_destroy(&vd->vdev_dtl_lock); | mutex_destroy(&vd->vdev_dtl_lock); | ||||
mutex_destroy(&vd->vdev_stat_lock); | mutex_destroy(&vd->vdev_stat_lock); | ||||
mutex_destroy(&vd->vdev_probe_lock); | mutex_destroy(&vd->vdev_probe_lock); | ||||
mutex_destroy(&vd->vdev_scan_io_queue_lock); | |||||
if (vd == spa->spa_root_vdev) | if (vd == spa->spa_root_vdev) | ||||
spa->spa_root_vdev = NULL; | spa->spa_root_vdev = NULL; | ||||
kmem_free(vd, sizeof (vdev_t)); | kmem_free(vd, sizeof (vdev_t)); | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | if (list_link_active(&svd->vdev_state_dirty_node)) { | ||||
vdev_state_dirty(tvd); | vdev_state_dirty(tvd); | ||||
} | } | ||||
tvd->vdev_deflate_ratio = svd->vdev_deflate_ratio; | tvd->vdev_deflate_ratio = svd->vdev_deflate_ratio; | ||||
svd->vdev_deflate_ratio = 0; | svd->vdev_deflate_ratio = 0; | ||||
tvd->vdev_islog = svd->vdev_islog; | tvd->vdev_islog = svd->vdev_islog; | ||||
svd->vdev_islog = 0; | svd->vdev_islog = 0; | ||||
dsl_scan_io_queue_vdev_xfer(svd, tvd); | |||||
} | } | ||||
static void | static void | ||||
vdev_top_update(vdev_t *tvd, vdev_t *vd) | vdev_top_update(vdev_t *tvd, vdev_t *vd) | ||||
{ | { | ||||
if (vd == NULL) | if (vd == NULL) | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 1,277 Lines • ▼ Show 20 Lines | vdev_dtl_empty(vdev_t *vd, vdev_dtl_type_t t) | ||||
mutex_enter(&vd->vdev_dtl_lock); | mutex_enter(&vd->vdev_dtl_lock); | ||||
empty = range_tree_is_empty(rt); | empty = range_tree_is_empty(rt); | ||||
mutex_exit(&vd->vdev_dtl_lock); | mutex_exit(&vd->vdev_dtl_lock); | ||||
return (empty); | return (empty); | ||||
} | } | ||||
/* | /* | ||||
* Returns B_TRUE if vdev determines offset needs to be resilvered. | |||||
*/ | |||||
boolean_t | |||||
vdev_dtl_need_resilver(vdev_t *vd, uint64_t offset, size_t psize) | |||||
{ | |||||
ASSERT(vd != vd->vdev_spa->spa_root_vdev); | |||||
if (vd->vdev_ops->vdev_op_need_resilver == NULL || | |||||
vd->vdev_ops->vdev_op_leaf) | |||||
return (B_TRUE); | |||||
return (vd->vdev_ops->vdev_op_need_resilver(vd, offset, psize)); | |||||
} | |||||
/* | |||||
* Returns the lowest txg in the DTL range. | * Returns the lowest txg in the DTL range. | ||||
*/ | */ | ||||
static uint64_t | static uint64_t | ||||
vdev_dtl_min(vdev_t *vd) | vdev_dtl_min(vdev_t *vd) | ||||
{ | { | ||||
range_seg_t *rs; | range_seg_t *rs; | ||||
ASSERT(MUTEX_HELD(&vd->vdev_dtl_lock)); | ASSERT(MUTEX_HELD(&vd->vdev_dtl_lock)); | ||||
▲ Show 20 Lines • Show All 262 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
vdev_dtl_sync(vdev_t *vd, uint64_t txg) | vdev_dtl_sync(vdev_t *vd, uint64_t txg) | ||||
{ | { | ||||
spa_t *spa = vd->vdev_spa; | spa_t *spa = vd->vdev_spa; | ||||
range_tree_t *rt = vd->vdev_dtl[DTL_MISSING]; | range_tree_t *rt = vd->vdev_dtl[DTL_MISSING]; | ||||
objset_t *mos = spa->spa_meta_objset; | objset_t *mos = spa->spa_meta_objset; | ||||
range_tree_t *rtsync; | range_tree_t *rtsync; | ||||
kmutex_t rtlock; | |||||
dmu_tx_t *tx; | dmu_tx_t *tx; | ||||
uint64_t object = space_map_object(vd->vdev_dtl_sm); | uint64_t object = space_map_object(vd->vdev_dtl_sm); | ||||
ASSERT(vdev_is_concrete(vd)); | ASSERT(vdev_is_concrete(vd)); | ||||
ASSERT(vd->vdev_ops->vdev_op_leaf); | ASSERT(vd->vdev_ops->vdev_op_leaf); | ||||
tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg); | tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg); | ||||
Show All 25 Lines | if (vd->vdev_dtl_sm == NULL) { | ||||
new_object = space_map_alloc(mos, vdev_dtl_sm_blksz, tx); | new_object = space_map_alloc(mos, vdev_dtl_sm_blksz, tx); | ||||
VERIFY3U(new_object, !=, 0); | VERIFY3U(new_object, !=, 0); | ||||
VERIFY0(space_map_open(&vd->vdev_dtl_sm, mos, new_object, | VERIFY0(space_map_open(&vd->vdev_dtl_sm, mos, new_object, | ||||
0, -1ULL, 0)); | 0, -1ULL, 0)); | ||||
ASSERT(vd->vdev_dtl_sm != NULL); | ASSERT(vd->vdev_dtl_sm != NULL); | ||||
} | } | ||||
rtsync = range_tree_create(NULL, NULL); | bzero(&rtlock, sizeof(rtlock)); | ||||
mutex_init(&rtlock, NULL, MUTEX_DEFAULT, NULL); | |||||
rtsync = range_tree_create(NULL, NULL, &rtlock); | |||||
mutex_enter(&vd->vdev_dtl_lock); | mutex_enter(&vd->vdev_dtl_lock); | ||||
range_tree_walk(rt, range_tree_add, rtsync); | range_tree_walk(rt, range_tree_add, rtsync); | ||||
mutex_exit(&vd->vdev_dtl_lock); | mutex_exit(&vd->vdev_dtl_lock); | ||||
space_map_truncate(vd->vdev_dtl_sm, vdev_dtl_sm_blksz, tx); | space_map_truncate(vd->vdev_dtl_sm, vdev_dtl_sm_blksz, tx); | ||||
space_map_write(vd->vdev_dtl_sm, rtsync, SM_ALLOC, tx); | space_map_write(vd->vdev_dtl_sm, rtsync, SM_ALLOC, tx); | ||||
range_tree_vacate(rtsync, NULL, NULL); | range_tree_vacate(rtsync, NULL, NULL); | ||||
▲ Show 20 Lines • Show All 1,613 Lines • Show Last 20 Lines |