Fix incorrect deletion order in range_tree_add_impl gap case

After a side-effectful call like add or remove, references to range 
segs stored in btrees can no longer be used safely.  We move the 
remove call to just before the reinsertion call so that the seg 
remains valid for as long as we need it.

Reviewed-by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Paul Dagnelie <pcd@delphix.com>
Closes #11044 
Closes #11056
This commit is contained in:
Paul Dagnelie 2020-10-14 08:59:54 -07:00 committed by GitHub
parent 47a7e99939
commit 6a60ef80e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -314,7 +314,6 @@ range_tree_add_impl(void *arg, uint64_t start, uint64_t size, uint64_t fill)
return;
}
zfs_btree_remove(&rt->rt_root, rs);
if (rt->rt_ops != NULL && rt->rt_ops->rtop_remove != NULL)
rt->rt_ops->rtop_remove(rt, rs, rt->rt_arg);
@ -326,6 +325,7 @@ range_tree_add_impl(void *arg, uint64_t start, uint64_t size, uint64_t fill)
end = MAX(end, rend);
size = end - start;
zfs_btree_remove(&rt->rt_root, rs);
range_tree_add_impl(rt, start, size, fill);
return;
}