aboutsummaryrefslogtreecommitdiffstats
path: root/volumes.c
diff options
context:
space:
mode:
authorQu Wenruo <quwenruo@cn.fujitsu.com>2016-02-22 14:59:53 +0800
committerDavid Sterba <dsterba@suse.com>2016-02-26 17:27:58 +0100
commite2e0dae926b2174c368ee6dbed610d9f98c193a5 (patch)
tree7918cae2e54c1ea658cb8676d8a15cb6aac2cd4c /volumes.c
parentbfc2cb7cfbd4403a4ba6307e3f31ba4a654fd8aa (diff)
downloadbtrfs-progs-e2e0dae926b2174c368ee6dbed610d9f98c193a5.tar.gz
btrfs-progs-e2e0dae926b2174c368ee6dbed610d9f98c193a5.tar.xz
btrfs-progs-e2e0dae926b2174c368ee6dbed610d9f98c193a5.zip
btrfs-progs: volume: Fix a bug causing btrfs-find-root to skip first chunk
There is a small bug from 2011, where btrfs_next_bg (formally btrfs_next_metadata) function will always skip the first chunk. That's OK for that time, as there is always 3 empty temporary chunks. But now, we may ended up with only one metadata or system chunk, with empty chunk auto-remove from kernel or new mkfs.btrfs. So fix it by checking the initial value so btrfs_next_bg() will return the first chunk if its *logical parameter is 0. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'volumes.c')
-rw-r--r--volumes.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/volumes.c b/volumes.c
index a94be0e..059c4f4 100644
--- a/volumes.c
+++ b/volumes.c
@@ -1170,14 +1170,23 @@ int btrfs_next_bg(struct btrfs_mapping_tree *map_tree, u64 *logical,
{
struct cache_extent *ce;
struct map_lookup *map;
+ u64 cur = *logical;
- ce = search_cache_extent(&map_tree->cache_tree, *logical);
+ ce = search_cache_extent(&map_tree->cache_tree, cur);
while (ce) {
- ce = next_cache_extent(ce);
- if (!ce)
- return -ENOENT;
+ /*
+ * only jump to next bg if our cur is not 0
+ * As the initial logical for btrfs_next_bg() is 0, and
+ * if we jump to next bg, we skipped a valid bg.
+ */
+ if (cur) {
+ ce = next_cache_extent(ce);
+ if (!ce)
+ return -ENOENT;
+ }
+ cur = ce->start;
map = container_of(ce, struct map_lookup, ce);
if (map->type & type) {
*logical = ce->start;