| 425 | } |
| 426 | |
| 427 | static void |
| 428 | range_tree_remove_impl(range_tree_t *rt, uint64_t start, uint64_t size, |
| 429 | boolean_t do_fill) |
| 430 | { |
| 431 | zfs_btree_index_t where; |
| 432 | range_seg_t *rs; |
| 433 | range_seg_max_t rsearch, rs_tmp; |
| 434 | uint64_t end = start + size; |
| 435 | boolean_t left_over, right_over; |
| 436 | |
| 437 | VERIFY3U(size, !=, 0); |
| 438 | VERIFY3U(size, <=, rt->rt_space); |
| 439 | if (rt->rt_type == RANGE_SEG64) |
| 440 | ASSERT3U(start + size, >, start); |
| 441 | |
| 442 | rs_set_start(&rsearch, rt, start); |
| 443 | rs_set_end(&rsearch, rt, end); |
| 444 | rs = zfs_btree_find(&rt->rt_root, &rsearch, &where); |
| 445 | |
| 446 | /* Make sure we completely overlap with someone */ |
| 447 | if (rs == NULL) { |
| 448 | zfs_panic_recover("zfs: removing nonexistent segment from " |
| 449 | "range tree (offset=%llx size=%llx)", |
| 450 | (longlong_t)start, (longlong_t)size); |
| 451 | return; |
| 452 | } |
| 453 | |
| 454 | /* |
| 455 | * Range trees with gap support must only remove complete segments |
| 456 | * from the tree. This allows us to maintain accurate fill accounting |
| 457 | * and to ensure that bridged sections are not leaked. If we need to |
| 458 | * remove less than the full segment, we can only adjust the fill count. |
| 459 | */ |
| 460 | if (rt->rt_gap != 0) { |
| 461 | if (do_fill) { |
| 462 | if (rs_get_fill(rs, rt) == size) { |
| 463 | start = rs_get_start(rs, rt); |
| 464 | end = rs_get_end(rs, rt); |
| 465 | size = end - start; |
| 466 | } else { |
| 467 | range_tree_adjust_fill(rt, rs, -size); |
| 468 | return; |
| 469 | } |
| 470 | } else if (rs_get_start(rs, rt) != start || |
| 471 | rs_get_end(rs, rt) != end) { |
| 472 | zfs_panic_recover("zfs: freeing partial segment of " |
| 473 | "gap tree (offset=%llx size=%llx) of " |
| 474 | "(offset=%llx size=%llx)", |
| 475 | (longlong_t)start, (longlong_t)size, |
| 476 | (longlong_t)rs_get_start(rs, rt), |
| 477 | (longlong_t)rs_get_end(rs, rt) - rs_get_start(rs, |
| 478 | rt)); |
| 479 | return; |
| 480 | } |
| 481 | } |
| 482 | |
| 483 | VERIFY3U(rs_get_start(rs, rt), <=, start); |
| 484 | VERIFY3U(rs_get_end(rs, rt), >=, end); |
no test coverage detected