From f5e77e4c520aa46583f7dd0f1d264ed93714acb2 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Fri, 29 Jan 2016 13:03:23 +0800 Subject: btrfs-progs: extent-tree: Introduce function to find the first overlapping extent Introduce a new function, btrfs_search_overlap_extent() to find the first overlapping extent. It's useful for later btrfs-convert rework. Signed-off-by: Qu Wenruo Signed-off-by: David Sterba --- extent-tree.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'extent-tree.c') diff --git a/extent-tree.c b/extent-tree.c index 4a41717e..6ccd4245 100644 --- a/extent-tree.c +++ b/extent-tree.c @@ -3909,6 +3909,69 @@ int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans, return 0; } +static void __get_extent_size(struct btrfs_root *root, struct btrfs_path *path, + u64 *start, u64 *len) +{ + struct btrfs_key key; + + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); + BUG_ON(!(key.type == BTRFS_EXTENT_ITEM_KEY || + key.type == BTRFS_METADATA_ITEM_KEY)); + *start = key.objectid; + if (key.type == BTRFS_EXTENT_ITEM_KEY) + *len = key.offset; + else + *len = root->nodesize; +} + +/* + * Find first overlap extent for range [bytenr, bytenr + len) + * Return 0 for found and point path to it. + * Return >0 for not found. + * Return <0 for err + */ +int btrfs_search_overlap_extent(struct btrfs_root *root, + struct btrfs_path *path, u64 bytenr, u64 len) +{ + struct btrfs_key key; + u64 cur_start; + u64 cur_len; + int ret; + + key.objectid = bytenr; + key.type = BTRFS_EXTENT_DATA_KEY; + key.offset = (u64)-1; + + ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); + if (ret < 0) + return ret; + BUG_ON(ret == 0); + + ret = btrfs_previous_extent_item(root, path, 0); + if (ret < 0) + return ret; + /* no previous, check next extent */ + if (ret > 0) + goto next; + __get_extent_size(root, path, &cur_start, &cur_len); + /* Tail overlap */ + if (cur_start + cur_len > bytenr) + return 1; + +next: + ret = btrfs_next_extent_item(root, path, bytenr + len); + if (ret < 0) + return ret; + /* No next, prev already checked, no overlap */ + if (ret > 0) + return 0; + __get_extent_size(root, path, &cur_start, &cur_len); + /* head overlap*/ + if (cur_start < bytenr + len) + return 1; + return 0; +} + /* * Record a file extent. Do all the required works, such as inserting * file extent item, inserting extent item and backref item into extent -- cgit v1.2.3