aboutsummaryrefslogtreecommitdiff
path: root/module/zfs/vdev_removal.c
diff options
context:
space:
mode:
authorPaul Dagnelie <pcd@delphix.com>2019-10-09 17:36:03 +0000
committerBrian Behlendorf <behlendorf1@llnl.gov>2019-10-09 17:36:03 +0000
commitca5777793ee10b9f7bb57aef00a6c8d57969625e (patch)
tree2e1dc17f5be66c5ea8e955db0b37260ab8a2fbd0 /module/zfs/vdev_removal.c
parentd0a84ba92b40085b46efee9bc1219490876c7a68 (diff)
downloadsrc-ca5777793ee10b9f7bb57aef00a6c8d57969625e.tar.gz
src-ca5777793ee10b9f7bb57aef00a6c8d57969625e.zip
Diffstat (limited to 'module/zfs/vdev_removal.c')
-rw-r--r--module/zfs/vdev_removal.c66
1 files changed, 34 insertions, 32 deletions
diff --git a/module/zfs/vdev_removal.c b/module/zfs/vdev_removal.c
index 549087163a58..a4fac1cc590d 100644
--- a/module/zfs/vdev_removal.c
+++ b/module/zfs/vdev_removal.c
@@ -198,11 +198,12 @@ spa_vdev_removal_create(vdev_t *vd)
spa_vdev_removal_t *svr = kmem_zalloc(sizeof (*svr), KM_SLEEP);
mutex_init(&svr->svr_lock, NULL, MUTEX_DEFAULT, NULL);
cv_init(&svr->svr_cv, NULL, CV_DEFAULT, NULL);
- svr->svr_allocd_segs = range_tree_create(NULL, NULL);
+ svr->svr_allocd_segs = range_tree_create(NULL, RANGE_SEG64, NULL, 0, 0);
svr->svr_vdev_id = vd->vdev_id;
for (int i = 0; i < TXG_SIZE; i++) {
- svr->svr_frees[i] = range_tree_create(NULL, NULL);
+ svr->svr_frees[i] = range_tree_create(NULL, RANGE_SEG64, NULL,
+ 0, 0);
list_create(&svr->svr_new_segments[i],
sizeof (vdev_indirect_mapping_entry_t),
offsetof(vdev_indirect_mapping_entry_t, vime_node));
@@ -967,18 +968,15 @@ spa_vdev_copy_segment(vdev_t *vd, range_tree_t *segs,
* the allocation at the end of a segment, thus avoiding
* additional split blocks.
*/
- range_seg_t search;
- avl_index_t where;
- search.rs_start = start + maxalloc;
- search.rs_end = search.rs_start;
- range_seg_t *rs = avl_find(&segs->rt_root, &search, &where);
- if (rs == NULL) {
- rs = avl_nearest(&segs->rt_root, where, AVL_BEFORE);
- } else {
- rs = AVL_PREV(&segs->rt_root, rs);
- }
+ range_seg_max_t search;
+ zfs_btree_index_t where;
+ rs_set_start(&search, segs, start + maxalloc);
+ rs_set_end(&search, segs, start + maxalloc);
+ (void) zfs_btree_find(&segs->rt_root, &search, &where);
+ range_seg_t *rs = zfs_btree_prev(&segs->rt_root, &where,
+ &where);
if (rs != NULL) {
- size = rs->rs_end - start;
+ size = rs_get_end(rs, segs) - start;
} else {
/*
* There are no segments that end before maxalloc.
@@ -1011,20 +1009,22 @@ spa_vdev_copy_segment(vdev_t *vd, range_tree_t *segs,
* relative to the start of the range to be copied (i.e. relative to the
* local variable "start").
*/
- range_tree_t *obsolete_segs = range_tree_create(NULL, NULL);
-
- range_seg_t *rs = avl_first(&segs->rt_root);
- ASSERT3U(rs->rs_start, ==, start);
- uint64_t prev_seg_end = rs->rs_end;
- while ((rs = AVL_NEXT(&segs->rt_root, rs)) != NULL) {
- if (rs->rs_start >= start + size) {
+ range_tree_t *obsolete_segs = range_tree_create(NULL, RANGE_SEG64, NULL,
+ 0, 0);
+
+ zfs_btree_index_t where;
+ range_seg_t *rs = zfs_btree_first(&segs->rt_root, &where);
+ ASSERT3U(rs_get_start(rs, segs), ==, start);
+ uint64_t prev_seg_end = rs_get_end(rs, segs);
+ while ((rs = zfs_btree_next(&segs->rt_root, &where, &where)) != NULL) {
+ if (rs_get_start(rs, segs) >= start + size) {
break;
} else {
range_tree_add(obsolete_segs,
prev_seg_end - start,
- rs->rs_start - prev_seg_end);
+ rs_get_start(rs, segs) - prev_seg_end);
}
- prev_seg_end = rs->rs_end;
+ prev_seg_end = rs_get_end(rs, segs);
}
/* We don't end in the middle of an obsolete range */
ASSERT3U(start + size, <=, prev_seg_end);
@@ -1268,9 +1268,10 @@ spa_vdev_copy_impl(vdev_t *vd, spa_vdev_removal_t *svr, vdev_copy_arg_t *vca,
* allocated segments that we are copying. We may also be copying
* free segments (of up to vdev_removal_max_span bytes).
*/
- range_tree_t *segs = range_tree_create(NULL, NULL);
+ range_tree_t *segs = range_tree_create(NULL, RANGE_SEG64, NULL, 0, 0);
for (;;) {
- range_seg_t *rs = range_tree_first(svr->svr_allocd_segs);
+ range_tree_t *rt = svr->svr_allocd_segs;
+ range_seg_t *rs = range_tree_first(rt);
if (rs == NULL)
break;
@@ -1279,17 +1280,17 @@ spa_vdev_copy_impl(vdev_t *vd, spa_vdev_removal_t *svr, vdev_copy_arg_t *vca,
if (range_tree_is_empty(segs)) {
/* need to truncate the first seg based on max_alloc */
- seg_length =
- MIN(rs->rs_end - rs->rs_start, *max_alloc);
+ seg_length = MIN(rs_get_end(rs, rt) - rs_get_start(rs,
+ rt), *max_alloc);
} else {
- if (rs->rs_start - range_tree_max(segs) >
+ if (rs_get_start(rs, rt) - range_tree_max(segs) >
vdev_removal_max_span) {
/*
* Including this segment would cause us to
* copy a larger unneeded chunk than is allowed.
*/
break;
- } else if (rs->rs_end - range_tree_min(segs) >
+ } else if (rs_get_end(rs, rt) - range_tree_min(segs) >
*max_alloc) {
/*
* This additional segment would extend past
@@ -1298,13 +1299,14 @@ spa_vdev_copy_impl(vdev_t *vd, spa_vdev_removal_t *svr, vdev_copy_arg_t *vca,
*/
break;
} else {
- seg_length = rs->rs_end - rs->rs_start;
+ seg_length = rs_get_end(rs, rt) -
+ rs_get_start(rs, rt);
}
}
- range_tree_add(segs, rs->rs_start, seg_length);
+ range_tree_add(segs, rs_get_start(rs, rt), seg_length);
range_tree_remove(svr->svr_allocd_segs,
- rs->rs_start, seg_length);
+ rs_get_start(rs, rt), seg_length);
}
if (range_tree_is_empty(segs)) {
@@ -1483,7 +1485,7 @@ spa_vdev_remove_thread(void *arg)
vca.vca_msp = msp;
zfs_dbgmsg("copying %llu segments for metaslab %llu",
- avl_numnodes(&svr->svr_allocd_segs->rt_root),
+ zfs_btree_numnodes(&svr->svr_allocd_segs->rt_root),
msp->ms_id);
while (!svr->svr_thread_exit &&