xref: /freebsd/sys/contrib/openzfs/module/zfs/range_tree.c (revision 22649d4dba730d46244fd2dff4fd174903c8379f)
1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3  * This file and its contents are supplied under the terms of the
4  * Common Development and Distribution License ("CDDL"), version 1.0.
5  * You may only use this file in accordance with the terms of version
6  * 1.0 of the CDDL.
7  *
8  * A full copy of the text of the CDDL should have accompanied this
9  * source.  A copy of the CDDL is also available via the Internet at
10  * https://opensource.org/license/CDDL-1.0.
11  */
12 /*
13  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
14  * Use is subject to license terms.
15  */
16 /*
17  * Copyright (c) 2013, 2019 by Delphix. All rights reserved.
18  * Copyright (c) 2015, Nexenta Systems, Inc. All rights reserved.
19  */
20 
21 #include <sys/zfs_context.h>
22 #include <sys/spa.h>
23 #include <sys/dmu.h>
24 #include <sys/dnode.h>
25 #include <sys/zio.h>
26 #include <sys/range_tree.h>
27 #include <sys/sysmacros.h>
28 
29 #ifndef _KERNEL
30 /*
31  * Need the extra 'abort()' here since is possible for PANIC() to return, and
32  * our panic() usage in this file assumes it's NORETURN.
33  */
34 #define	panic(...) do {PANIC(__VA_ARGS__); abort(); } while (0);
35 #define	zfs_panic_recover(...) panic(__VA_ARGS__)
36 #endif
37 
38 /*
39  * Range trees are tree-based data structures that can be used to
40  * track free space or generally any space allocation information.
41  * A range tree keeps track of individual segments and automatically
42  * provides facilities such as adjacent extent merging and extent
43  * splitting in response to range add/remove requests.
44  *
45  * A range tree starts out completely empty, with no segments in it.
46  * Adding an allocation via zfs_range_tree_add to the range tree can either:
47  * 1) create a new extent
48  * 2) extend an adjacent extent
49  * 3) merge two adjacent extents
50  * Conversely, removing an allocation via zfs_range_tree_remove can:
51  * 1) completely remove an extent
52  * 2) shorten an extent (if the allocation was near one of its ends)
53  * 3) split an extent into two extents, in effect punching a hole
54  *
55  * A range tree is also capable of 'bridging' gaps when adding
56  * allocations. This is useful for cases when close proximity of
57  * allocations is an important detail that needs to be represented
58  * in the range tree. See zfs_range_tree_set_gap(). The default behavior
59  * is not to bridge gaps (i.e. the maximum allowed gap size is 0).
60  *
61  * In order to traverse a range tree, use either the zfs_range_tree_walk()
62  * or zfs_range_tree_vacate() functions.
63  *
64  * To obtain more accurate information on individual segment
65  * operations that the range tree performs "under the hood", you can
66  * specify a set of callbacks by passing a zfs_range_tree_ops_t structure
67  * to the zfs_range_tree_create function. Any callbacks that are non-NULL
68  * are then called at the appropriate times.
69  *
70  * The range tree code also supports a special variant of range trees
71  * that can bridge small gaps between segments. This kind of tree is used
72  * by the dsl scanning code to group I/Os into mostly sequential chunks to
73  * optimize disk performance. The code here attempts to do this with as
74  * little memory and computational overhead as possible. One limitation of
75  * this implementation is that segments of range trees with gaps can only
76  * support removing complete segments.
77  */
78 
79 static inline void
zfs_rs_copy(zfs_range_seg_t * src,zfs_range_seg_t * dest,zfs_range_tree_t * rt)80 zfs_rs_copy(zfs_range_seg_t *src, zfs_range_seg_t *dest, zfs_range_tree_t *rt)
81 {
82 	ASSERT3U(rt->rt_type, <, ZFS_RANGE_SEG_NUM_TYPES);
83 	size_t size = 0;
84 	switch (rt->rt_type) {
85 	case ZFS_RANGE_SEG32:
86 		size = sizeof (zfs_range_seg32_t);
87 		break;
88 	case ZFS_RANGE_SEG64:
89 		size = sizeof (zfs_range_seg64_t);
90 		break;
91 	case ZFS_RANGE_SEG_GAP:
92 		size = sizeof (zfs_range_seg_gap_t);
93 		break;
94 	default:
95 		__builtin_unreachable();
96 	}
97 	memcpy(dest, src, size);
98 }
99 
100 void
zfs_range_tree_stat_verify(zfs_range_tree_t * rt)101 zfs_range_tree_stat_verify(zfs_range_tree_t *rt)
102 {
103 	zfs_range_seg_t *rs;
104 	zfs_btree_index_t where;
105 	uint64_t hist[ZFS_RANGE_TREE_HISTOGRAM_SIZE] = { 0 };
106 	int i;
107 
108 	for (rs = zfs_btree_first(&rt->rt_root, &where); rs != NULL;
109 	    rs = zfs_btree_next(&rt->rt_root, &where, &where)) {
110 		uint64_t size = zfs_rs_get_end(rs, rt) -
111 		    zfs_rs_get_start(rs, rt);
112 		int idx	= highbit64(size) - 1;
113 
114 		hist[idx]++;
115 		ASSERT3U(hist[idx], !=, 0);
116 	}
117 
118 	for (i = 0; i < ZFS_RANGE_TREE_HISTOGRAM_SIZE; i++) {
119 		VERIFY3UF(hist[i], ==, rt->rt_histogram[i],
120 		    "i=%d, hist=%px, hist=%llu, rt_hist=%llu",
121 		    i, hist, (u_longlong_t)hist[i],
122 		    (u_longlong_t)rt->rt_histogram[i]);
123 	}
124 }
125 
126 static void
zfs_range_tree_stat_incr(zfs_range_tree_t * rt,zfs_range_seg_t * rs)127 zfs_range_tree_stat_incr(zfs_range_tree_t *rt, zfs_range_seg_t *rs)
128 {
129 	uint64_t size = zfs_rs_get_end(rs, rt) - zfs_rs_get_start(rs, rt);
130 	int idx = highbit64(size) - 1;
131 
132 	ASSERT(size != 0);
133 	ASSERT3U(idx, <,
134 	    sizeof (rt->rt_histogram) / sizeof (*rt->rt_histogram));
135 
136 	rt->rt_histogram[idx]++;
137 	ASSERT3U(rt->rt_histogram[idx], !=, 0);
138 }
139 
140 static void
zfs_range_tree_stat_decr(zfs_range_tree_t * rt,zfs_range_seg_t * rs)141 zfs_range_tree_stat_decr(zfs_range_tree_t *rt, zfs_range_seg_t *rs)
142 {
143 	uint64_t size = zfs_rs_get_end(rs, rt) - zfs_rs_get_start(rs, rt);
144 	int idx = highbit64(size) - 1;
145 
146 	ASSERT(size != 0);
147 	ASSERT3U(idx, <,
148 	    sizeof (rt->rt_histogram) / sizeof (*rt->rt_histogram));
149 
150 	ASSERT3U(rt->rt_histogram[idx], !=, 0);
151 	rt->rt_histogram[idx]--;
152 }
153 
154 __attribute__((always_inline)) inline
155 static int
zfs_range_tree_seg32_compare(const void * x1,const void * x2)156 zfs_range_tree_seg32_compare(const void *x1, const void *x2)
157 {
158 	const zfs_range_seg32_t *r1 = x1;
159 	const zfs_range_seg32_t *r2 = x2;
160 
161 	ASSERT3U(r1->rs_start, <=, r1->rs_end);
162 	ASSERT3U(r2->rs_start, <=, r2->rs_end);
163 
164 	return ((r1->rs_start >= r2->rs_end) - (r1->rs_end <= r2->rs_start));
165 }
166 
167 __attribute__((always_inline)) inline
168 static int
zfs_range_tree_seg64_compare(const void * x1,const void * x2)169 zfs_range_tree_seg64_compare(const void *x1, const void *x2)
170 {
171 	const zfs_range_seg64_t *r1 = x1;
172 	const zfs_range_seg64_t *r2 = x2;
173 
174 	ASSERT3U(r1->rs_start, <=, r1->rs_end);
175 	ASSERT3U(r2->rs_start, <=, r2->rs_end);
176 
177 	return ((r1->rs_start >= r2->rs_end) - (r1->rs_end <= r2->rs_start));
178 }
179 
180 __attribute__((always_inline)) inline
181 static int
zfs_range_tree_seg_gap_compare(const void * x1,const void * x2)182 zfs_range_tree_seg_gap_compare(const void *x1, const void *x2)
183 {
184 	const zfs_range_seg_gap_t *r1 = x1;
185 	const zfs_range_seg_gap_t *r2 = x2;
186 
187 	ASSERT3U(r1->rs_start, <=, r1->rs_end);
188 	ASSERT3U(r2->rs_start, <=, r2->rs_end);
189 
190 	return ((r1->rs_start >= r2->rs_end) - (r1->rs_end <= r2->rs_start));
191 }
192 
ZFS_BTREE_FIND_IN_BUF_FUNC(zfs_range_tree_seg32_find_in_buf,zfs_range_seg32_t,zfs_range_tree_seg32_compare)193 ZFS_BTREE_FIND_IN_BUF_FUNC(zfs_range_tree_seg32_find_in_buf, zfs_range_seg32_t,
194     zfs_range_tree_seg32_compare)
195 
196 ZFS_BTREE_FIND_IN_BUF_FUNC(zfs_range_tree_seg64_find_in_buf, zfs_range_seg64_t,
197     zfs_range_tree_seg64_compare)
198 
199 ZFS_BTREE_FIND_IN_BUF_FUNC(zfs_range_tree_seg_gap_find_in_buf,
200     zfs_range_seg_gap_t, zfs_range_tree_seg_gap_compare)
201 
202 static zfs_range_tree_t *
203 zfs_range_tree_create_impl(const zfs_range_tree_ops_t *ops,
204     zfs_range_seg_type_t type, void *arg, uint64_t start, uint64_t shift,
205     uint64_t gap, uint64_t flags, const char *name)
206 {
207 	zfs_range_tree_t *rt = kmem_zalloc(sizeof (zfs_range_tree_t), KM_SLEEP);
208 
209 	ASSERT3U(shift, <, 64);
210 	ASSERT3U(type, <=, ZFS_RANGE_SEG_NUM_TYPES);
211 	size_t size;
212 	int (*compare) (const void *, const void *);
213 	bt_find_in_buf_f bt_find;
214 	switch (type) {
215 	case ZFS_RANGE_SEG32:
216 		size = sizeof (zfs_range_seg32_t);
217 		compare = zfs_range_tree_seg32_compare;
218 		bt_find = zfs_range_tree_seg32_find_in_buf;
219 		break;
220 	case ZFS_RANGE_SEG64:
221 		size = sizeof (zfs_range_seg64_t);
222 		compare = zfs_range_tree_seg64_compare;
223 		bt_find = zfs_range_tree_seg64_find_in_buf;
224 		break;
225 	case ZFS_RANGE_SEG_GAP:
226 		size = sizeof (zfs_range_seg_gap_t);
227 		compare = zfs_range_tree_seg_gap_compare;
228 		bt_find = zfs_range_tree_seg_gap_find_in_buf;
229 		break;
230 	default:
231 		panic("Invalid range seg type %d", type);
232 	}
233 	zfs_btree_create(&rt->rt_root, compare, bt_find, size);
234 
235 	rt->rt_ops = ops;
236 	rt->rt_gap = gap;
237 	rt->rt_flags = flags;
238 	rt->rt_name = name;
239 	rt->rt_arg = arg;
240 	rt->rt_type = type;
241 	rt->rt_start = start;
242 	rt->rt_shift = shift;
243 
244 	if (rt->rt_ops != NULL && rt->rt_ops->rtop_create != NULL)
245 		rt->rt_ops->rtop_create(rt, rt->rt_arg);
246 
247 	return (rt);
248 }
249 
250 zfs_range_tree_t *
zfs_range_tree_create_gap(const zfs_range_tree_ops_t * ops,zfs_range_seg_type_t type,void * arg,uint64_t start,uint64_t shift,uint64_t gap)251 zfs_range_tree_create_gap(const zfs_range_tree_ops_t *ops,
252     zfs_range_seg_type_t type, void *arg, uint64_t start, uint64_t shift,
253     uint64_t gap)
254 {
255 	return (zfs_range_tree_create_impl(ops, type, arg, start, shift, gap,
256 	    0, NULL));
257 }
258 
259 zfs_range_tree_t *
zfs_range_tree_create(const zfs_range_tree_ops_t * ops,zfs_range_seg_type_t type,void * arg,uint64_t start,uint64_t shift)260 zfs_range_tree_create(const zfs_range_tree_ops_t *ops,
261     zfs_range_seg_type_t type, void *arg, uint64_t start, uint64_t shift)
262 {
263 	return (zfs_range_tree_create_impl(ops, type, arg, start, shift, 0,
264 	    0, NULL));
265 }
266 
267 zfs_range_tree_t *
zfs_range_tree_create_flags(const zfs_range_tree_ops_t * ops,zfs_range_seg_type_t type,void * arg,uint64_t start,uint64_t shift,uint64_t flags,const char * name)268 zfs_range_tree_create_flags(const zfs_range_tree_ops_t *ops,
269     zfs_range_seg_type_t type, void *arg, uint64_t start, uint64_t shift,
270     uint64_t flags, const char *name)
271 {
272 	return (zfs_range_tree_create_impl(ops, type, arg, start, shift, 0,
273 	    flags, name));
274 }
275 
276 void
zfs_range_tree_destroy(zfs_range_tree_t * rt)277 zfs_range_tree_destroy(zfs_range_tree_t *rt)
278 {
279 	VERIFY0(rt->rt_space);
280 
281 	if (rt->rt_ops != NULL && rt->rt_ops->rtop_destroy != NULL)
282 		rt->rt_ops->rtop_destroy(rt, rt->rt_arg);
283 
284 	if (rt->rt_name != NULL && (rt->rt_flags & ZFS_RT_F_DYN_NAME))
285 		kmem_strfree((char *)(uintptr_t)rt->rt_name);
286 
287 	zfs_btree_destroy(&rt->rt_root);
288 	kmem_free(rt, sizeof (*rt));
289 }
290 
291 void
zfs_range_tree_adjust_fill(zfs_range_tree_t * rt,zfs_range_seg_t * rs,int64_t delta)292 zfs_range_tree_adjust_fill(zfs_range_tree_t *rt, zfs_range_seg_t *rs,
293     int64_t delta)
294 {
295 	if (delta < 0 && delta * -1 >= zfs_rs_get_fill(rs, rt)) {
296 		zfs_panic_recover("zfs: rt=%s: attempting to decrease fill to "
297 		    "or below 0; probable double remove in segment [%llx:%llx]",
298 		    ZFS_RT_NAME(rt),
299 		    (longlong_t)zfs_rs_get_start(rs, rt),
300 		    (longlong_t)zfs_rs_get_end(rs, rt));
301 	}
302 	if (zfs_rs_get_fill(rs, rt) + delta > zfs_rs_get_end(rs, rt) -
303 	    zfs_rs_get_start(rs, rt)) {
304 		zfs_panic_recover("zfs: rt=%s: attempting to increase fill "
305 		    "beyond max; probable double add in segment [%llx:%llx]",
306 		    ZFS_RT_NAME(rt),
307 		    (longlong_t)zfs_rs_get_start(rs, rt),
308 		    (longlong_t)zfs_rs_get_end(rs, rt));
309 	}
310 
311 	if (rt->rt_ops != NULL && rt->rt_ops->rtop_remove != NULL)
312 		rt->rt_ops->rtop_remove(rt, rs, rt->rt_arg);
313 	zfs_rs_set_fill(rs, rt, zfs_rs_get_fill(rs, rt) + delta);
314 	if (rt->rt_ops != NULL && rt->rt_ops->rtop_add != NULL)
315 		rt->rt_ops->rtop_add(rt, rs, rt->rt_arg);
316 }
317 
318 static void
zfs_range_tree_add_impl(void * arg,uint64_t start,uint64_t size,uint64_t fill)319 zfs_range_tree_add_impl(void *arg, uint64_t start, uint64_t size, uint64_t fill)
320 {
321 	zfs_range_tree_t *rt = arg;
322 	zfs_btree_index_t where;
323 	zfs_range_seg_t *rs_before, *rs_after, *rs;
324 	zfs_range_seg_max_t tmp, rsearch;
325 	uint64_t end = start + size, gap = rt->rt_gap;
326 	uint64_t bridge_size = 0;
327 	boolean_t merge_before, merge_after;
328 
329 	ASSERT3U(size, !=, 0);
330 	ASSERT3U(fill, <=, size);
331 	ASSERT3U(start + size, >, start);
332 
333 	zfs_rs_set_start(&rsearch, rt, start);
334 	zfs_rs_set_end(&rsearch, rt, end);
335 	rs = zfs_btree_find(&rt->rt_root, &rsearch, &where);
336 
337 	/*
338 	 * If this is a gap-supporting range tree, it is possible that we
339 	 * are inserting into an existing segment. In this case simply
340 	 * bump the fill count and call the remove / add callbacks. If the
341 	 * new range will extend an existing segment, we remove the
342 	 * existing one, apply the new extent to it and re-insert it using
343 	 * the normal code paths.
344 	 */
345 	if (rs != NULL) {
346 		uint64_t rstart = zfs_rs_get_start(rs, rt);
347 		uint64_t rend = zfs_rs_get_end(rs, rt);
348 		if (gap == 0) {
349 			zfs_panic_recover("zfs: rt=%s: adding segment "
350 			    "(offset=%llx size=%llx) overlapping with existing "
351 			    "one (offset=%llx size=%llx)",
352 			    ZFS_RT_NAME(rt),
353 			    (longlong_t)start, (longlong_t)size,
354 			    (longlong_t)rstart, (longlong_t)(rend - rstart));
355 			return;
356 		}
357 		if (rstart <= start && rend >= end) {
358 			zfs_range_tree_adjust_fill(rt, rs, fill);
359 			return;
360 		}
361 
362 		if (rt->rt_ops != NULL && rt->rt_ops->rtop_remove != NULL)
363 			rt->rt_ops->rtop_remove(rt, rs, rt->rt_arg);
364 
365 		zfs_range_tree_stat_decr(rt, rs);
366 		rt->rt_space -= rend - rstart;
367 
368 		fill += zfs_rs_get_fill(rs, rt);
369 		start = MIN(start, rstart);
370 		end = MAX(end, rend);
371 		size = end - start;
372 
373 		zfs_btree_remove(&rt->rt_root, rs);
374 		zfs_range_tree_add_impl(rt, start, size, fill);
375 		return;
376 	}
377 
378 	ASSERT0P(rs);
379 
380 	/*
381 	 * Determine whether or not we will have to merge with our neighbors.
382 	 * If gap != 0, we might need to merge with our neighbors even if we
383 	 * aren't directly touching.
384 	 */
385 	zfs_btree_index_t where_before, where_after;
386 	rs_before = zfs_btree_prev(&rt->rt_root, &where, &where_before);
387 	rs_after = zfs_btree_next(&rt->rt_root, &where, &where_after);
388 
389 	merge_before = (rs_before != NULL && zfs_rs_get_end(rs_before, rt) >=
390 	    start - gap);
391 	merge_after = (rs_after != NULL && zfs_rs_get_start(rs_after, rt) <=
392 	    end + gap);
393 
394 	if (merge_before && gap != 0)
395 		bridge_size += start - zfs_rs_get_end(rs_before, rt);
396 	if (merge_after && gap != 0)
397 		bridge_size += zfs_rs_get_start(rs_after, rt) - end;
398 
399 	if (merge_before && merge_after) {
400 		if (rt->rt_ops != NULL && rt->rt_ops->rtop_remove != NULL) {
401 			rt->rt_ops->rtop_remove(rt, rs_before, rt->rt_arg);
402 			rt->rt_ops->rtop_remove(rt, rs_after, rt->rt_arg);
403 		}
404 
405 		zfs_range_tree_stat_decr(rt, rs_before);
406 		zfs_range_tree_stat_decr(rt, rs_after);
407 
408 		zfs_rs_copy(rs_after, &tmp, rt);
409 		uint64_t before_start = zfs_rs_get_start_raw(rs_before, rt);
410 		uint64_t before_fill = zfs_rs_get_fill(rs_before, rt);
411 		uint64_t after_fill = zfs_rs_get_fill(rs_after, rt);
412 		zfs_btree_remove_idx(&rt->rt_root, &where_before);
413 
414 		/*
415 		 * We have to re-find the node because our old reference is
416 		 * invalid as soon as we do any mutating btree operations.
417 		 */
418 		rs_after = zfs_btree_find(&rt->rt_root, &tmp, &where_after);
419 		ASSERT3P(rs_after, !=, NULL);
420 		zfs_rs_set_start_raw(rs_after, rt, before_start);
421 		zfs_rs_set_fill(rs_after, rt, after_fill + before_fill + fill);
422 		rs = rs_after;
423 	} else if (merge_before) {
424 		if (rt->rt_ops != NULL && rt->rt_ops->rtop_remove != NULL)
425 			rt->rt_ops->rtop_remove(rt, rs_before, rt->rt_arg);
426 
427 		zfs_range_tree_stat_decr(rt, rs_before);
428 
429 		uint64_t before_fill = zfs_rs_get_fill(rs_before, rt);
430 		zfs_rs_set_end(rs_before, rt, end);
431 		zfs_rs_set_fill(rs_before, rt, before_fill + fill);
432 		rs = rs_before;
433 	} else if (merge_after) {
434 		if (rt->rt_ops != NULL && rt->rt_ops->rtop_remove != NULL)
435 			rt->rt_ops->rtop_remove(rt, rs_after, rt->rt_arg);
436 
437 		zfs_range_tree_stat_decr(rt, rs_after);
438 
439 		uint64_t after_fill = zfs_rs_get_fill(rs_after, rt);
440 		zfs_rs_set_start(rs_after, rt, start);
441 		zfs_rs_set_fill(rs_after, rt, after_fill + fill);
442 		rs = rs_after;
443 	} else {
444 		rs = &tmp;
445 
446 		zfs_rs_set_start(rs, rt, start);
447 		zfs_rs_set_end(rs, rt, end);
448 		zfs_rs_set_fill(rs, rt, fill);
449 		zfs_btree_add_idx(&rt->rt_root, rs, &where);
450 	}
451 
452 	if (gap != 0) {
453 		ASSERT3U(zfs_rs_get_fill(rs, rt), <=, zfs_rs_get_end(rs, rt) -
454 		    zfs_rs_get_start(rs, rt));
455 	} else {
456 		ASSERT3U(zfs_rs_get_fill(rs, rt), ==, zfs_rs_get_end(rs, rt) -
457 		    zfs_rs_get_start(rs, rt));
458 	}
459 
460 	if (rt->rt_ops != NULL && rt->rt_ops->rtop_add != NULL)
461 		rt->rt_ops->rtop_add(rt, rs, rt->rt_arg);
462 
463 	zfs_range_tree_stat_incr(rt, rs);
464 	rt->rt_space += size + bridge_size;
465 }
466 
467 void
zfs_range_tree_add(void * arg,uint64_t start,uint64_t size)468 zfs_range_tree_add(void *arg, uint64_t start, uint64_t size)
469 {
470 	zfs_range_tree_add_impl(arg, start, size, size);
471 }
472 
473 static void
zfs_range_tree_remove_impl(zfs_range_tree_t * rt,uint64_t start,uint64_t size,boolean_t do_fill)474 zfs_range_tree_remove_impl(zfs_range_tree_t *rt, uint64_t start, uint64_t size,
475     boolean_t do_fill)
476 {
477 	zfs_btree_index_t where;
478 	zfs_range_seg_t *rs;
479 	zfs_range_seg_max_t rsearch, rs_tmp;
480 	uint64_t end = start + size;
481 	uint64_t rstart, rend;
482 	boolean_t left_over, right_over;
483 
484 	VERIFY3U(size, !=, 0);
485 	VERIFY3U(size, <=, rt->rt_space);
486 	if (rt->rt_type == ZFS_RANGE_SEG64)
487 		ASSERT3U(start + size, >, start);
488 
489 	zfs_rs_set_start(&rsearch, rt, start);
490 	zfs_rs_set_end(&rsearch, rt, end);
491 	rs = zfs_btree_find(&rt->rt_root, &rsearch, &where);
492 
493 	/* Make sure we completely overlap with someone */
494 	if (rs == NULL) {
495 		zfs_panic_recover("zfs: rt=%s: removing nonexistent segment "
496 		    "from range tree (offset=%llx size=%llx)",
497 		    ZFS_RT_NAME(rt), (longlong_t)start, (longlong_t)size);
498 		return;
499 	}
500 
501 	rstart = zfs_rs_get_start(rs, rt);
502 	rend = zfs_rs_get_end(rs, rt);
503 
504 	/*
505 	 * Range trees with gap support must only remove complete segments
506 	 * from the tree. This allows us to maintain accurate fill accounting
507 	 * and to ensure that bridged sections are not leaked. If we need to
508 	 * remove less than the full segment, we can only adjust the fill count.
509 	 */
510 	if (rt->rt_gap != 0) {
511 		if (do_fill) {
512 			if (zfs_rs_get_fill(rs, rt) == size) {
513 				start = rstart;
514 				end = rend;
515 				size = end - start;
516 			} else {
517 				zfs_range_tree_adjust_fill(rt, rs, -size);
518 				return;
519 			}
520 		} else if (rstart != start || rend != end) {
521 			zfs_panic_recover("zfs: rt=%s: freeing partial segment "
522 			    "of gap tree (offset=%llx size=%llx) of "
523 			    "(offset=%llx size=%llx)",
524 			    ZFS_RT_NAME(rt),
525 			    (longlong_t)start, (longlong_t)size,
526 			    (longlong_t)rstart, (longlong_t)(rend - rstart));
527 			return;
528 		}
529 	}
530 
531 	if (!(rstart <= start && rend >= end)) {
532 		zfs_panic_recover("zfs: rt=%s: removing segment "
533 		    "(offset=%llx size=%llx) not completely overlapped by "
534 		    "existing one (offset=%llx size=%llx)",
535 		    ZFS_RT_NAME(rt),
536 		    (longlong_t)start, (longlong_t)size,
537 		    (longlong_t)rstart, (longlong_t)(rend - rstart));
538 		return;
539 	}
540 
541 	left_over = (rstart != start);
542 	right_over = (rend != end);
543 
544 	zfs_range_tree_stat_decr(rt, rs);
545 
546 	if (rt->rt_ops != NULL && rt->rt_ops->rtop_remove != NULL)
547 		rt->rt_ops->rtop_remove(rt, rs, rt->rt_arg);
548 
549 	if (left_over && right_over) {
550 		zfs_range_seg_max_t newseg;
551 		zfs_rs_set_start(&newseg, rt, end);
552 		zfs_rs_set_end_raw(&newseg, rt, zfs_rs_get_end_raw(rs, rt));
553 		zfs_rs_set_fill(&newseg, rt, zfs_rs_get_end(rs, rt) - end);
554 		zfs_range_tree_stat_incr(rt, &newseg);
555 
556 		// This modifies the buffer already inside the range tree
557 		zfs_rs_set_end(rs, rt, start);
558 
559 		zfs_rs_copy(rs, &rs_tmp, rt);
560 		if (zfs_btree_next(&rt->rt_root, &where, &where) != NULL)
561 			zfs_btree_add_idx(&rt->rt_root, &newseg, &where);
562 		else
563 			zfs_btree_add(&rt->rt_root, &newseg);
564 
565 		if (rt->rt_ops != NULL && rt->rt_ops->rtop_add != NULL)
566 			rt->rt_ops->rtop_add(rt, &newseg, rt->rt_arg);
567 	} else if (left_over) {
568 		// This modifies the buffer already inside the range tree
569 		zfs_rs_set_end(rs, rt, start);
570 		zfs_rs_copy(rs, &rs_tmp, rt);
571 	} else if (right_over) {
572 		// This modifies the buffer already inside the range tree
573 		zfs_rs_set_start(rs, rt, end);
574 		zfs_rs_copy(rs, &rs_tmp, rt);
575 	} else {
576 		zfs_btree_remove_idx(&rt->rt_root, &where);
577 		rs = NULL;
578 	}
579 
580 	if (rs != NULL) {
581 		/*
582 		 * The fill of the leftover segment will always be equal to
583 		 * the size, since we do not support removing partial segments
584 		 * of range trees with gaps.
585 		 */
586 		zfs_rs_set_fill_raw(rs, rt, zfs_rs_get_end_raw(rs, rt) -
587 		    zfs_rs_get_start_raw(rs, rt));
588 		zfs_range_tree_stat_incr(rt, &rs_tmp);
589 
590 		if (rt->rt_ops != NULL && rt->rt_ops->rtop_add != NULL)
591 			rt->rt_ops->rtop_add(rt, &rs_tmp, rt->rt_arg);
592 	}
593 
594 	rt->rt_space -= size;
595 }
596 
597 void
zfs_range_tree_remove(void * arg,uint64_t start,uint64_t size)598 zfs_range_tree_remove(void *arg, uint64_t start, uint64_t size)
599 {
600 	zfs_range_tree_remove_impl(arg, start, size, B_FALSE);
601 }
602 
603 void
zfs_range_tree_remove_fill(zfs_range_tree_t * rt,uint64_t start,uint64_t size)604 zfs_range_tree_remove_fill(zfs_range_tree_t *rt, uint64_t start, uint64_t size)
605 {
606 	zfs_range_tree_remove_impl(rt, start, size, B_TRUE);
607 }
608 
609 void
zfs_range_tree_resize_segment(zfs_range_tree_t * rt,zfs_range_seg_t * rs,uint64_t newstart,uint64_t newsize)610 zfs_range_tree_resize_segment(zfs_range_tree_t *rt, zfs_range_seg_t *rs,
611     uint64_t newstart, uint64_t newsize)
612 {
613 	int64_t delta = newsize - (zfs_rs_get_end(rs, rt) -
614 	    zfs_rs_get_start(rs, rt));
615 
616 	zfs_range_tree_stat_decr(rt, rs);
617 	if (rt->rt_ops != NULL && rt->rt_ops->rtop_remove != NULL)
618 		rt->rt_ops->rtop_remove(rt, rs, rt->rt_arg);
619 
620 	zfs_rs_set_start(rs, rt, newstart);
621 	zfs_rs_set_end(rs, rt, newstart + newsize);
622 
623 	zfs_range_tree_stat_incr(rt, rs);
624 	if (rt->rt_ops != NULL && rt->rt_ops->rtop_add != NULL)
625 		rt->rt_ops->rtop_add(rt, rs, rt->rt_arg);
626 
627 	rt->rt_space += delta;
628 }
629 
630 static zfs_range_seg_t *
zfs_range_tree_find_impl(zfs_range_tree_t * rt,uint64_t start,uint64_t size)631 zfs_range_tree_find_impl(zfs_range_tree_t *rt, uint64_t start, uint64_t size)
632 {
633 	zfs_range_seg_max_t rsearch;
634 	uint64_t end = start + size;
635 
636 	VERIFY(size != 0);
637 
638 	zfs_rs_set_start(&rsearch, rt, start);
639 	zfs_rs_set_end(&rsearch, rt, end);
640 	return (zfs_btree_find(&rt->rt_root, &rsearch, NULL));
641 }
642 
643 zfs_range_seg_t *
zfs_range_tree_find(zfs_range_tree_t * rt,uint64_t start,uint64_t size)644 zfs_range_tree_find(zfs_range_tree_t *rt, uint64_t start, uint64_t size)
645 {
646 	if (rt->rt_type == ZFS_RANGE_SEG64)
647 		ASSERT3U(start + size, >, start);
648 
649 	zfs_range_seg_t *rs = zfs_range_tree_find_impl(rt, start, size);
650 	if (rs != NULL && zfs_rs_get_start(rs, rt) <= start &&
651 	    zfs_rs_get_end(rs, rt) >= start + size) {
652 		return (rs);
653 	}
654 	return (NULL);
655 }
656 
657 void
zfs_range_tree_verify_not_present(zfs_range_tree_t * rt,uint64_t off,uint64_t size)658 zfs_range_tree_verify_not_present(zfs_range_tree_t *rt, uint64_t off,
659     uint64_t size)
660 {
661 	zfs_range_seg_t *rs = zfs_range_tree_find(rt, off, size);
662 	if (rs != NULL)
663 		panic("segment already in tree; rs=%p", (void *)rs);
664 }
665 
666 boolean_t
zfs_range_tree_contains(zfs_range_tree_t * rt,uint64_t start,uint64_t size)667 zfs_range_tree_contains(zfs_range_tree_t *rt, uint64_t start, uint64_t size)
668 {
669 	return (zfs_range_tree_find(rt, start, size) != NULL);
670 }
671 
672 /*
673  * Returns the first subset of the given range which overlaps with the range
674  * tree. Returns true if there is a segment in the range, and false if there
675  * isn't.
676  */
677 boolean_t
zfs_range_tree_find_in(zfs_range_tree_t * rt,uint64_t start,uint64_t size,uint64_t * ostart,uint64_t * osize)678 zfs_range_tree_find_in(zfs_range_tree_t *rt, uint64_t start, uint64_t size,
679     uint64_t *ostart, uint64_t *osize)
680 {
681 	if (rt->rt_type == ZFS_RANGE_SEG64)
682 		ASSERT3U(start + size, >, start);
683 
684 	zfs_range_seg_max_t rsearch;
685 	zfs_rs_set_start(&rsearch, rt, start);
686 	zfs_rs_set_end_raw(&rsearch, rt, zfs_rs_get_start_raw(&rsearch, rt) +
687 	    1);
688 
689 	zfs_btree_index_t where;
690 	zfs_range_seg_t *rs = zfs_btree_find(&rt->rt_root, &rsearch, &where);
691 	if (rs != NULL) {
692 		*ostart = start;
693 		*osize = MIN(size, zfs_rs_get_end(rs, rt) - start);
694 		return (B_TRUE);
695 	}
696 
697 	rs = zfs_btree_next(&rt->rt_root, &where, &where);
698 	if (rs == NULL || zfs_rs_get_start(rs, rt) >= start + size)
699 		return (B_FALSE);
700 
701 	*ostart = zfs_rs_get_start(rs, rt);
702 	*osize = MIN(start + size, zfs_rs_get_end(rs, rt)) -
703 	    zfs_rs_get_start(rs, rt);
704 	return (B_TRUE);
705 }
706 
707 /*
708  * Ensure that this range is not in the tree, regardless of whether
709  * it is currently in the tree.
710  */
711 void
zfs_range_tree_clear(zfs_range_tree_t * rt,uint64_t start,uint64_t size)712 zfs_range_tree_clear(zfs_range_tree_t *rt, uint64_t start, uint64_t size)
713 {
714 	zfs_range_seg_t *rs;
715 
716 	if (size == 0)
717 		return;
718 
719 	if (rt->rt_type == ZFS_RANGE_SEG64)
720 		ASSERT3U(start + size, >, start);
721 
722 	while ((rs = zfs_range_tree_find_impl(rt, start, size)) != NULL) {
723 		uint64_t free_start = MAX(zfs_rs_get_start(rs, rt), start);
724 		uint64_t free_end = MIN(zfs_rs_get_end(rs, rt), start + size);
725 		zfs_range_tree_remove(rt, free_start, free_end - free_start);
726 	}
727 }
728 
729 void
zfs_range_tree_swap(zfs_range_tree_t ** rtsrc,zfs_range_tree_t ** rtdst)730 zfs_range_tree_swap(zfs_range_tree_t **rtsrc, zfs_range_tree_t **rtdst)
731 {
732 	zfs_range_tree_t *rt;
733 
734 	ASSERT0(zfs_range_tree_space(*rtdst));
735 	ASSERT0(zfs_btree_numnodes(&(*rtdst)->rt_root));
736 
737 	rt = *rtsrc;
738 	*rtsrc = *rtdst;
739 	*rtdst = rt;
740 }
741 
742 void
zfs_range_tree_vacate(zfs_range_tree_t * rt,zfs_range_tree_func_t * func,void * arg)743 zfs_range_tree_vacate(zfs_range_tree_t *rt, zfs_range_tree_func_t *func,
744     void *arg)
745 {
746 	if (rt->rt_ops != NULL && rt->rt_ops->rtop_vacate != NULL)
747 		rt->rt_ops->rtop_vacate(rt, rt->rt_arg);
748 
749 	if (func != NULL) {
750 		zfs_range_seg_t *rs;
751 		zfs_btree_index_t *cookie = NULL;
752 
753 		while ((rs = zfs_btree_destroy_nodes(&rt->rt_root, &cookie)) !=
754 		    NULL) {
755 			func(arg, zfs_rs_get_start(rs, rt),
756 			    zfs_rs_get_end(rs, rt) - zfs_rs_get_start(rs, rt));
757 		}
758 	} else {
759 		zfs_btree_clear(&rt->rt_root);
760 	}
761 
762 	memset(rt->rt_histogram, 0, sizeof (rt->rt_histogram));
763 	rt->rt_space = 0;
764 }
765 
766 void
zfs_range_tree_walk(zfs_range_tree_t * rt,zfs_range_tree_func_t * func,void * arg)767 zfs_range_tree_walk(zfs_range_tree_t *rt, zfs_range_tree_func_t *func,
768     void *arg)
769 {
770 	zfs_btree_index_t where;
771 	for (zfs_range_seg_t *rs = zfs_btree_first(&rt->rt_root, &where);
772 	    rs != NULL; rs = zfs_btree_next(&rt->rt_root, &where, &where)) {
773 		func(arg, zfs_rs_get_start(rs, rt), zfs_rs_get_end(rs, rt) -
774 		    zfs_rs_get_start(rs, rt));
775 	}
776 }
777 
778 zfs_range_seg_t *
zfs_range_tree_first(zfs_range_tree_t * rt)779 zfs_range_tree_first(zfs_range_tree_t *rt)
780 {
781 	return (zfs_btree_first(&rt->rt_root, NULL));
782 }
783 
784 uint64_t
zfs_range_tree_space(zfs_range_tree_t * rt)785 zfs_range_tree_space(zfs_range_tree_t *rt)
786 {
787 	return (rt->rt_space);
788 }
789 
790 uint64_t
zfs_range_tree_numsegs(zfs_range_tree_t * rt)791 zfs_range_tree_numsegs(zfs_range_tree_t *rt)
792 {
793 	return ((rt == NULL) ? 0 : zfs_btree_numnodes(&rt->rt_root));
794 }
795 
796 boolean_t
zfs_range_tree_is_empty(zfs_range_tree_t * rt)797 zfs_range_tree_is_empty(zfs_range_tree_t *rt)
798 {
799 	ASSERT(rt != NULL);
800 	return (zfs_range_tree_space(rt) == 0);
801 }
802 
803 /*
804  * Remove any overlapping ranges between the given segment [start, end)
805  * from removefrom. Add non-overlapping leftovers to addto.
806  */
807 void
zfs_range_tree_remove_xor_add_segment(uint64_t start,uint64_t end,zfs_range_tree_t * removefrom,zfs_range_tree_t * addto)808 zfs_range_tree_remove_xor_add_segment(uint64_t start, uint64_t end,
809     zfs_range_tree_t *removefrom, zfs_range_tree_t *addto)
810 {
811 	zfs_btree_index_t where;
812 	zfs_range_seg_max_t starting_rs;
813 	zfs_rs_set_start(&starting_rs, removefrom, start);
814 	zfs_rs_set_end_raw(&starting_rs, removefrom,
815 	    zfs_rs_get_start_raw(&starting_rs, removefrom) + 1);
816 
817 	zfs_range_seg_t *curr = zfs_btree_find(&removefrom->rt_root,
818 	    &starting_rs, &where);
819 
820 	if (curr == NULL)
821 		curr = zfs_btree_next(&removefrom->rt_root, &where, &where);
822 
823 	zfs_range_seg_t *next;
824 	for (; curr != NULL; curr = next) {
825 		if (start == end)
826 			return;
827 		VERIFY3U(start, <, end);
828 
829 		/* there is no overlap */
830 		if (end <= zfs_rs_get_start(curr, removefrom)) {
831 			zfs_range_tree_add(addto, start, end - start);
832 			return;
833 		}
834 
835 		uint64_t overlap_start = MAX(zfs_rs_get_start(curr, removefrom),
836 		    start);
837 		uint64_t overlap_end = MIN(zfs_rs_get_end(curr, removefrom),
838 		    end);
839 		uint64_t overlap_size = overlap_end - overlap_start;
840 		ASSERT3S(overlap_size, >, 0);
841 		zfs_range_seg_max_t rs;
842 		zfs_rs_copy(curr, &rs, removefrom);
843 
844 		zfs_range_tree_remove(removefrom, overlap_start, overlap_size);
845 
846 		if (start < overlap_start)
847 			zfs_range_tree_add(addto, start, overlap_start - start);
848 
849 		start = overlap_end;
850 		next = zfs_btree_find(&removefrom->rt_root, &rs, &where);
851 		/*
852 		 * If we find something here, we only removed part of the
853 		 * curr segment. Either there's some left at the end
854 		 * because we've reached the end of the range we're removing,
855 		 * or there's some left at the start because we started
856 		 * partway through the range.  Either way, we continue with
857 		 * the loop. If it's the former, we'll return at the start of
858 		 * the loop, and if it's the latter we'll see if there is more
859 		 * area to process.
860 		 */
861 		if (next != NULL) {
862 			ASSERT(start == end || start == zfs_rs_get_end(&rs,
863 			    removefrom));
864 		}
865 
866 		next = zfs_btree_next(&removefrom->rt_root, &where, &where);
867 	}
868 	VERIFY0P(curr);
869 
870 	if (start != end) {
871 		VERIFY3U(start, <, end);
872 		zfs_range_tree_add(addto, start, end - start);
873 	} else {
874 		VERIFY3U(start, ==, end);
875 	}
876 }
877 
878 /*
879  * For each entry in rt, if it exists in removefrom, remove it
880  * from removefrom. Otherwise, add it to addto.
881  */
882 void
zfs_range_tree_remove_xor_add(zfs_range_tree_t * rt,zfs_range_tree_t * removefrom,zfs_range_tree_t * addto)883 zfs_range_tree_remove_xor_add(zfs_range_tree_t *rt,
884     zfs_range_tree_t *removefrom, zfs_range_tree_t *addto)
885 {
886 	zfs_btree_index_t where;
887 	for (zfs_range_seg_t *rs = zfs_btree_first(&rt->rt_root, &where); rs;
888 	    rs = zfs_btree_next(&rt->rt_root, &where, &where)) {
889 		zfs_range_tree_remove_xor_add_segment(zfs_rs_get_start(rs, rt),
890 		    zfs_rs_get_end(rs, rt), removefrom, addto);
891 	}
892 }
893 
894 uint64_t
zfs_range_tree_min(zfs_range_tree_t * rt)895 zfs_range_tree_min(zfs_range_tree_t *rt)
896 {
897 	zfs_range_seg_t *rs = zfs_btree_first(&rt->rt_root, NULL);
898 	return (rs != NULL ? zfs_rs_get_start(rs, rt) : 0);
899 }
900 
901 uint64_t
zfs_range_tree_max(zfs_range_tree_t * rt)902 zfs_range_tree_max(zfs_range_tree_t *rt)
903 {
904 	zfs_range_seg_t *rs = zfs_btree_last(&rt->rt_root, NULL);
905 	return (rs != NULL ? zfs_rs_get_end(rs, rt) : 0);
906 }
907 
908 uint64_t
zfs_range_tree_span(zfs_range_tree_t * rt)909 zfs_range_tree_span(zfs_range_tree_t *rt)
910 {
911 	return (zfs_range_tree_max(rt) - zfs_range_tree_min(rt));
912 }
913