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