From 7abe4c3385c10a0907edc65ca907462ee922e075 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Thu, 4 Jul 2019 14:10:58 +0800 Subject: [PATCH] btrfs-progs: image: determine if a tree block is in the range of system chunks Introduce a new helper function, is_in_sys_chunks(), to determine if an item is in the range of system chunks. Since btrfs-image will merge adjacent same type extents into one item, this function is designed to return true for any bytes in system chunk range. Signed-off-by: Qu Wenruo Signed-off-by: David Sterba --- image/main.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/image/main.c b/image/main.c index 38097b9e..b983587b 100644 --- a/image/main.c +++ b/image/main.c @@ -1659,6 +1659,53 @@ static int wait_for_worker(struct mdrestore_struct *mdres) return ret; } +/* + * Check if a range [start, start + len] has ANY bytes covered by system chunk + * ranges. + */ +static bool is_in_sys_chunks(struct mdrestore_struct *mdres, u64 start, u64 len) +{ + struct rb_node *node = mdres->sys_chunks.root.rb_node; + struct cache_extent *entry; + struct cache_extent *next; + struct cache_extent *prev; + + if (start > mdres->sys_chunk_end) + return false; + + while (node) { + entry = rb_entry(node, struct cache_extent, rb_node); + if (start > entry->start) { + if (!node->rb_right) + break; + node = node->rb_right; + } else if (start < entry->start) { + if (!node->rb_left) + break; + node = node->rb_left; + } else { + /* Already in a system chunk */ + return true; + } + } + if (!node) + return false; + entry = rb_entry(node, struct cache_extent, rb_node); + /* Now we have entry which is the nearst chunk around @start */ + if (start > entry->start) { + prev = entry; + next = next_cache_extent(entry); + } else { + prev = prev_cache_extent(entry); + next = entry; + } + if (prev && prev->start + prev->size > start) + return true; + if (next && start + len > next->start) + return true; + return false; +} + static int read_chunk_block(struct mdrestore_struct *mdres, u8 *buffer, u64 bytenr, u64 item_bytenr, u32 bufsize, u64 cluster_bytenr)