summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/zfs/range_tree.c
diff options
context:
space:
mode:
authorPaul Dagnelie <pcd@delphix.com>2019-11-06 09:42:30 -0700
committerJerry Jelinek <jerry.jelinek@joyent.com>2019-11-13 13:49:14 -0700
commitaf1d63aba5cec023f92214c1f1faec9b489ac517 (patch)
tree2d1488cead8d4e3ebfd5504a79ecaa2832ccc403 /usr/src/uts/common/fs/zfs/range_tree.c
parent7dcf02b394314978ad87de8ce3756c58bcec5ce0 (diff)
downloadillumos-joyent-af1d63aba5cec023f92214c1f1faec9b489ac517.tar.gz
11918 metaslab improvements
Portions contributed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Matt Ahrens <matt@delphix.com> Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed by: George Wilson <gwilson@delphix.com> Reviewed by: Igor Kozhukhov <igor@dilos.org> Reviewed by: Sebastien Roy <sebastien.roy@delphix.com> Reviewed by: Serapheim Dimitropoulos <serapheim@delphix.com> Reviewed by: Andy Fiddaman <andy@omniosce.org> Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/uts/common/fs/zfs/range_tree.c')
-rw-r--r--usr/src/uts/common/fs/zfs/range_tree.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/usr/src/uts/common/fs/zfs/range_tree.c b/usr/src/uts/common/fs/zfs/range_tree.c
index 0ce251126b..92726c3f71 100644
--- a/usr/src/uts/common/fs/zfs/range_tree.c
+++ b/usr/src/uts/common/fs/zfs/range_tree.c
@@ -525,6 +525,36 @@ range_tree_contains(range_tree_t *rt, uint64_t start, uint64_t size)
}
/*
+ * Returns the first subset of the given range which overlaps with the range
+ * tree. Returns true if there is a segment in the range, and false if there
+ * isn't.
+ */
+boolean_t
+range_tree_find_in(range_tree_t *rt, uint64_t start, uint64_t size,
+ uint64_t *ostart, uint64_t *osize)
+{
+ range_seg_t rsearch;
+ rsearch.rs_start = start;
+ rsearch.rs_end = start + 1;
+
+ avl_index_t where;
+ range_seg_t *rs = avl_find(&rt->rt_root, &rsearch, &where);
+ if (rs != NULL) {
+ *ostart = start;
+ *osize = MIN(size, rs->rs_end - start);
+ return (B_TRUE);
+ }
+
+ rs = avl_nearest(&rt->rt_root, where, AVL_AFTER);
+ if (rs == NULL || rs->rs_start > start + size)
+ return (B_FALSE);
+
+ *ostart = rs->rs_start;
+ *osize = MIN(start + size, rs->rs_end) - rs->rs_start;
+ return (B_TRUE);
+}
+
+/*
* Ensure that this range is not in the tree, regardless of whether
* it is currently in the tree.
*/