diff options
author | Gui Hecheng <guihc.fnst@cn.fujitsu.com> | 2014-11-26 10:43:41 +0800 |
---|---|---|
committer | David Sterba <dsterba@suse.cz> | 2014-12-09 14:32:38 +0100 |
commit | 662d1dddcad79839f1cbc13cb0be3ec326af2933 (patch) | |
tree | bec570ce3392c8ff4467a235128556662e846be7 /btrfs-convert.c | |
parent | f0b1ff4481798c877bdf8869b8f69f36124466a8 (diff) |
btrfs-progs: convert: fix unable to rollback case with removed empty block groups
Run fstests: btrfs/012 will fail with message:
unable to do rollback
It is because the rollback function checks sequentially each piece of space
to map to a certain block group. If some piece doesn't, rollback refuses to continue.
After kernel commit:
commit 47ab2a6c689913db23ccae38349714edf8365e0a
Btrfs: remove empty block groups automatically
Empty block groups are removed, so there are possible gaps:
|--block group 1--| |--block group 2--|
^
|
gap
So the piece of space of the gap belongs to a removed empty block group,
and rollback should detect this case, and feel free to continue.
Signed-off-by: Gui Hecheng <guihc.fnst@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.cz>
Diffstat (limited to 'btrfs-convert.c')
-rw-r--r-- | btrfs-convert.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/btrfs-convert.c b/btrfs-convert.c index 6e2ab0f2..4c6c793a 100644 --- a/btrfs-convert.c +++ b/btrfs-convert.c @@ -2418,8 +2418,17 @@ static int may_rollback(struct btrfs_root *root) while (1) { ret = btrfs_map_block(&info->mapping_tree, WRITE, bytenr, &length, &multi, 0, NULL); - if (ret) + if (ret) { + if (ret == -ENOENT) { + /* removed block group at the tail */ + if (length == (u64)-1) + break; + + /* removed block group in the middle */ + goto next; + } goto fail; + } num_stripes = multi->num_stripes; physical = multi->stripes[0].physical; @@ -2427,7 +2436,7 @@ static int may_rollback(struct btrfs_root *root) if (num_stripes != 1 || physical != bytenr) goto fail; - +next: bytenr += length; if (bytenr >= total_bytes) break; |