Skip to content

Commit

Permalink
DLPX-67503 [Backport of Issue DLPX-67502 to 6.0.0.0] ztest crash in r…
Browse files Browse the repository at this point in the history
…s_get_start (openzfs#113)
  • Loading branch information
pcd1193182 authored Nov 22, 2019
1 parent 6f45de5 commit 4354b72
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 16 deletions.
21 changes: 13 additions & 8 deletions include/sys/btree.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,10 @@ void zfs_btree_create(zfs_btree_t *, int (*) (const void *, const void *),
/*
* Find a node with a matching value in the tree. Returns the matching node
* found. If not found, it returns NULL and then if "where" is not NULL it sets
* "where" for use with zfs_btree_insert() or zfs_btree_nearest().
* "where" for use with zfs_btree_add_idx() or zfs_btree_nearest().
*
* node - node that has the value being looked for
* where - position for use with zfs_btree_nearest() or zfs_btree_insert(),
* where - position for use with zfs_btree_nearest() or zfs_btree_add_idx(),
* may be NULL
*/
void *zfs_btree_find(zfs_btree_t *, const void *, zfs_btree_index_t *);
Expand All @@ -145,17 +145,20 @@ void *zfs_btree_find(zfs_btree_t *, const void *, zfs_btree_index_t *);
* node - the node to insert
* where - position as returned from zfs_btree_find()
*/
void zfs_btree_insert(zfs_btree_t *, const void *, const zfs_btree_index_t *);
void zfs_btree_add_idx(zfs_btree_t *, const void *, const zfs_btree_index_t *);

/*
* Return the first or last valued node in the tree. Will return NULL
* if the tree is empty.
* Return the first or last valued node in the tree. Will return NULL if the
* tree is empty. The index can be NULL if the location of the first or last
* element isn't required.
*/
void *zfs_btree_first(zfs_btree_t *, zfs_btree_index_t *);
void *zfs_btree_last(zfs_btree_t *, zfs_btree_index_t *);

/*
* Return the next or previous valued node in the tree.
* Return the next or previous valued node in the tree. The second index can
* safely be NULL, if the location of the next or previous value isn't
* required.
*/
void *zfs_btree_next(zfs_btree_t *, const zfs_btree_index_t *,
zfs_btree_index_t *);
Expand All @@ -169,7 +172,9 @@ void *zfs_btree_get(zfs_btree_t *, zfs_btree_index_t *);

/*
* Add a single value to the tree. The value must not compare equal to any
* other node already in the tree.
* other node already in the tree. Note that the value will be copied out, not
* inserted directly. It is safe to free or destroy the value once this
* function returns.
*/
void zfs_btree_add(zfs_btree_t *, const void *);

Expand All @@ -183,7 +188,7 @@ void zfs_btree_remove(zfs_btree_t *, const void *);
/*
* Remove the value at the given location from the tree.
*/
void zfs_btree_remove_from(zfs_btree_t *, zfs_btree_index_t *);
void zfs_btree_remove_idx(zfs_btree_t *, zfs_btree_index_t *);

/*
* Return the number of nodes in the tree
Expand Down
8 changes: 4 additions & 4 deletions module/zfs/btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,7 @@ zfs_btree_bulk_finish(zfs_btree_t *tree)
* Insert value into tree at the location specified by where.
*/
void
zfs_btree_insert(zfs_btree_t *tree, const void *value,
zfs_btree_add_idx(zfs_btree_t *tree, const void *value,
const zfs_btree_index_t *where)
{
zfs_btree_index_t idx = {0};
Expand Down Expand Up @@ -1322,7 +1322,7 @@ zfs_btree_add(zfs_btree_t *tree, const void *node)
{
zfs_btree_index_t where = {0};
VERIFY3P(zfs_btree_find(tree, node, &where), ==, NULL);
zfs_btree_insert(tree, node, &where);
zfs_btree_add_idx(tree, node, &where);
}

/* Helper function to free a tree node. */
Expand Down Expand Up @@ -1593,7 +1593,7 @@ zfs_btree_remove_from_node(zfs_btree_t *tree, zfs_btree_core_t *node,

/* Remove the element at the specific location. */
void
zfs_btree_remove_from(zfs_btree_t *tree, zfs_btree_index_t *where)
zfs_btree_remove_idx(zfs_btree_t *tree, zfs_btree_index_t *where)
{
size_t size = tree->bt_elem_size;
zfs_btree_hdr_t *hdr = where->bti_node;
Expand Down Expand Up @@ -1840,7 +1840,7 @@ zfs_btree_remove(zfs_btree_t *tree, const void *value)
{
zfs_btree_index_t where = {0};
VERIFY3P(zfs_btree_find(tree, value, &where), !=, NULL);
zfs_btree_remove_from(tree, &where);
zfs_btree_remove_idx(tree, &where);
}

/* Return the number of elements in the tree. */
Expand Down
4 changes: 4 additions & 0 deletions module/zfs/dsl_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -2929,6 +2929,8 @@ scan_io_queue_fetch_ext(dsl_scan_io_queue_t *queue)
*/
range_seg_t *size_rs =
zfs_btree_first(&queue->q_exts_by_size, NULL);
if (size_rs == NULL)
return (NULL);
uint64_t start = rs_get_start(size_rs, rt);
uint64_t size = rs_get_end(size_rs, rt) - start;
range_seg_t *addr_rs = range_tree_find(rt, start,
Expand Down Expand Up @@ -2960,6 +2962,8 @@ scan_io_queue_fetch_ext(dsl_scan_io_queue_t *queue)
*/
range_seg_t *size_rs = zfs_btree_first(&queue->q_exts_by_size,
NULL);
if (size_rs == NULL)
return (NULL);
uint64_t start = rs_get_start(size_rs, rt);
uint64_t size = rs_get_end(size_rs, rt) - start;
range_seg_t *addr_rs = range_tree_find(rt, start, size);
Expand Down
8 changes: 4 additions & 4 deletions module/zfs/range_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ range_tree_add_impl(void *arg, uint64_t start, uint64_t size, uint64_t fill)
uint64_t before_start = rs_get_start_raw(rs_before, rt);
uint64_t before_fill = rs_get_fill(rs_before, rt);
uint64_t after_fill = rs_get_fill(rs_after, rt);
zfs_btree_remove_from(&rt->rt_root, &where_before);
zfs_btree_remove_idx(&rt->rt_root, &where_before);

/*
* We have to re-find the node because our old reference is
Expand Down Expand Up @@ -385,7 +385,7 @@ range_tree_add_impl(void *arg, uint64_t start, uint64_t size, uint64_t fill)
rs_set_start(rs, rt, start);
rs_set_end(rs, rt, end);
rs_set_fill(rs, rt, fill);
zfs_btree_insert(&rt->rt_root, rs, &where);
zfs_btree_add_idx(&rt->rt_root, rs, &where);
}

if (gap != 0) {
Expand Down Expand Up @@ -488,7 +488,7 @@ range_tree_remove_impl(range_tree_t *rt, uint64_t start, uint64_t size,

rs_copy(rs, &rs_tmp, rt);
if (zfs_btree_next(&rt->rt_root, &where, &where) != NULL)
zfs_btree_insert(&rt->rt_root, &newseg, &where);
zfs_btree_add_idx(&rt->rt_root, &newseg, &where);
else
zfs_btree_add(&rt->rt_root, &newseg);

Expand All @@ -503,7 +503,7 @@ range_tree_remove_impl(range_tree_t *rt, uint64_t start, uint64_t size,
rs_set_start(rs, rt, end);
rs_copy(rs, &rs_tmp, rt);
} else {
zfs_btree_remove_from(&rt->rt_root, &where);
zfs_btree_remove_idx(&rt->rt_root, &where);
rs = NULL;
}

Expand Down

0 comments on commit 4354b72

Please sign in to comment.