Skip to content

Commit c8c3715

Browse files
Qu Wenruokdave
Qu Wenruo
authored andcommitted
btrfs-progs: find-root: Allow btrfs-find-root to search chunk root even chunk root is corrupted
Since now open_ctree_fs_info() can even return a valid fs_info with only system chunk mapping from super block, use this ability to do chunk root search for heavily damanged fs. As an fast alternative for time consuming and buggy chunk-recovery. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 9db13dc commit c8c3715

File tree

3 files changed

+15
-14
lines changed

3 files changed

+15
-14
lines changed

btrfs-find-root.c

+9-8
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ static void get_root_gen_and_level(u64 objectid, struct btrfs_fs_info *fs_info,
6969
case BTRFS_CHUNK_TREE_OBJECTID:
7070
level = btrfs_super_chunk_root_level(super);
7171
gen = btrfs_super_chunk_root_generation(super);
72-
printf("Search for chunk root is not supported yet\n");
7372
break;
7473
case BTRFS_TREE_LOG_OBJECTID:
7574
level = btrfs_super_log_root_level(super);
@@ -145,7 +144,7 @@ static void print_find_root_result(struct cache_tree *result,
145144

146145
int main(int argc, char **argv)
147146
{
148-
struct btrfs_root *root;
147+
struct btrfs_fs_info *fs_info;
149148
struct btrfs_find_root_filter filter = {0};
150149
struct cache_tree result;
151150
struct cache_extent *found;
@@ -192,16 +191,18 @@ int main(int argc, char **argv)
192191
exit(1);
193192
}
194193

195-
root = open_ctree(argv[optind], 0, OPEN_CTREE_CHUNK_ROOT_ONLY);
196-
if (!root) {
197-
fprintf(stderr, "Open ctree failed\n");
194+
fs_info = open_ctree_fs_info(argv[optind], 0, 0,
195+
OPEN_CTREE_CHUNK_ROOT_ONLY |
196+
OPEN_CTREE_IGNORE_CHUNK_TREE_ERROR);
197+
if (!fs_info) {
198+
error("open ctree failed");
198199
exit(1);
199200
}
200201
cache_tree_init(&result);
201202

202-
get_root_gen_and_level(filter.objectid, root->fs_info,
203+
get_root_gen_and_level(filter.objectid, fs_info,
203204
&filter.match_gen, &filter.match_level);
204-
ret = btrfs_find_root_search(root, &filter, &result, &found);
205+
ret = btrfs_find_root_search(fs_info, &filter, &result, &found);
205206
if (ret < 0) {
206207
fprintf(stderr, "Fail to search the tree root: %s\n",
207208
strerror(-ret));
@@ -215,7 +216,7 @@ int main(int argc, char **argv)
215216
print_find_root_result(&result, &filter);
216217
out:
217218
btrfs_find_root_free(&result);
218-
close_ctree(root);
219+
close_ctree_fs_info(fs_info);
219220
btrfs_close_all_devices();
220221
return ret;
221222
}

find-root.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,16 @@ static int add_eb_to_result(struct extent_buffer *eb,
101101
* Return 1 if found root with given gen/level and set *match to it.
102102
* Return <0 if error happens
103103
*/
104-
int btrfs_find_root_search(struct btrfs_root *chunk_root,
104+
int btrfs_find_root_search(struct btrfs_fs_info *fs_info,
105105
struct btrfs_find_root_filter *filter,
106106
struct cache_tree *result,
107107
struct cache_extent **match)
108108
{
109-
struct btrfs_fs_info *fs_info = chunk_root->fs_info;
110109
struct extent_buffer *eb;
111110
u64 chunk_offset = 0;
112111
u64 chunk_size = 0;
113112
u64 offset = 0;
114-
u32 leafsize = chunk_root->leafsize;
113+
u32 leafsize = btrfs_super_leafsize(fs_info->super_copy);
115114
int suppress_errors = 0;
116115
int ret = 0;
117116

@@ -133,8 +132,9 @@ int btrfs_find_root_search(struct btrfs_root *chunk_root,
133132
}
134133
for (offset = chunk_offset;
135134
offset < chunk_offset + chunk_size;
136-
offset += chunk_root->leafsize) {
137-
eb = read_tree_block(chunk_root, offset, leafsize, 0);
135+
offset += leafsize) {
136+
eb = read_tree_block_fs_info(fs_info, offset, leafsize,
137+
0);
138138
if (!eb || IS_ERR(eb))
139139
continue;
140140
ret = add_eb_to_result(eb, result, leafsize, filter,

find-root.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct btrfs_find_root_filter {
6565
* This *WILL* take *TONS* of extra time.
6666
*/
6767
};
68-
int btrfs_find_root_search(struct btrfs_root *chunk_root,
68+
int btrfs_find_root_search(struct btrfs_fs_info *fs_info,
6969
struct btrfs_find_root_filter *filter,
7070
struct cache_tree *result,
7171
struct cache_extent **match);

0 commit comments

Comments
 (0)