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>
master
Gui Hecheng 2014-11-26 10:43:41 +08:00 committed by David Sterba
parent f0b1ff4481
commit 662d1dddca
2 changed files with 13 additions and 2 deletions

View File

@ -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;

View File

@ -1318,10 +1318,12 @@ again:
ce = search_cache_extent(&map_tree->cache_tree, logical);
if (!ce) {
kfree(multi);
*length = (u64)-1;
return -ENOENT;
}
if (ce->start > logical) {
kfree(multi);
*length = ce->start - logical;
return -ENOENT;
}