summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWang Shilong <wangsl.fnst@cn.fujitsu.com>2014-03-06 13:53:56 +0800
committerChris Mason <clm@fb.com>2014-03-21 06:23:34 -0700
commitbedef66c0b8e1ded5aad6366b648f72d09e080d2 (patch)
treeabbd504f8b34be4e577626fe401342884fe40496
parentafb7de0da23676a37b2f28ced315889541591f69 (diff)
Btrfs-progs: fsck: deal with really corrupted extent tree
To reinit extent root, we need find a free extent, however, we may have a really corrupted extent tree, so we can't rely on existed extent tree to cache block group any more. During test, we fail to reinit extent tree which is because we can not find a free extent so let's make block group cache ourselves firstly. Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.cz> Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--cmds-check.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/cmds-check.c b/cmds-check.c
index 98199ce0..3cf59b61 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -6030,11 +6030,13 @@ static int pin_metadata_blocks(struct btrfs_fs_info *fs_info)
static int reset_block_groups(struct btrfs_fs_info *fs_info)
{
+ struct btrfs_block_group_cache *cache;
struct btrfs_path *path;
struct extent_buffer *leaf;
struct btrfs_chunk *chunk;
struct btrfs_key key;
int ret;
+ u64 start;
path = btrfs_alloc_path();
if (!path)
@@ -6085,8 +6087,19 @@ static int reset_block_groups(struct btrfs_fs_info *fs_info)
btrfs_chunk_type(leaf, chunk),
key.objectid, key.offset,
btrfs_chunk_length(leaf, chunk));
+ set_extent_dirty(&fs_info->free_space_cache, key.offset,
+ key.offset + btrfs_chunk_length(leaf, chunk),
+ GFP_NOFS);
path->slots[0]++;
}
+ start = 0;
+ while (1) {
+ cache = btrfs_lookup_first_block_group(fs_info, start);
+ if (!cache)
+ break;
+ cache->cached = 1;
+ start = cache->key.objectid + cache->key.offset;
+ }
btrfs_free_path(path);
return 0;