Skip to content

Commit 2115abe

Browse files
adam900710kdave
authored andcommitted
btrfs-progs: check: auto-detect chunk level when --chunk-root is specified
[BUG] There is a bug report that, when using --chunk-root option, if the specified chunk root tree block has a different level than the one in the super block, btrfs check will reject the run: ERROR: root [3 0] level 0 does not match 1 ERROR: cannot read chunk root ERROR: cannot open file system Opening filesystem to check... [CAUSE] During btrfs_setup_chunk_tree_and_device_map(), although it accepts a @chunk_root_bytenr parameter, it still uses the chunk root level from the super block. Thus if the provided chunk root is at a different level, it will still be rejected. [FIX] Read out the tree block at @chunk_root_bytenr, and use the level from the tree block instead. Pull-request: #1037 Link: https://lore.kernel.org/linux-btrfs/CAKZK7uxiRmDxk-1goC4yj7QZPSmL-=GAoAuF=OdekbSNVrG8fg@mail.gmail.com/ Signed-off-by: Qu Wenruo <[email protected]>
1 parent 2142f25 commit 2115abe

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

kernel-shared/disk-io.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,6 +1439,7 @@ int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info,
14391439
{
14401440
struct btrfs_super_block *sb = fs_info->super_copy;
14411441
u64 generation;
1442+
u8 level;
14421443
int ret;
14431444

14441445
btrfs_setup_root(fs_info->chunk_root, fs_info,
@@ -1448,22 +1449,35 @@ int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info,
14481449
if (ret)
14491450
return ret;
14501451

1451-
generation = btrfs_super_chunk_root_generation(sb);
1452-
14531452
if (chunk_root_bytenr && !IS_ALIGNED(chunk_root_bytenr,
14541453
fs_info->sectorsize)) {
14551454
warning("chunk_root_bytenr %llu is unaligned to %u, ignore it",
14561455
chunk_root_bytenr, fs_info->sectorsize);
14571456
chunk_root_bytenr = 0;
14581457
}
14591458

1460-
if (!chunk_root_bytenr)
1461-
chunk_root_bytenr = btrfs_super_chunk_root(sb);
1462-
else
1459+
if (chunk_root_bytenr) {
1460+
struct extent_buffer *eb;
1461+
struct btrfs_tree_parent_check check = { 0 };
1462+
14631463
generation = 0;
1464+
eb = read_tree_block(fs_info, chunk_root_bytenr, &check);
1465+
if (IS_ERR(eb)) {
1466+
ret = PTR_ERR(eb);
1467+
errno = -ret;
1468+
error("unable to read tree block at %llu: %m", chunk_root_bytenr);
1469+
return ret;
1470+
}
1471+
level = btrfs_header_level(eb);
1472+
free_extent_buffer(eb);
1473+
} else {
1474+
chunk_root_bytenr = btrfs_super_chunk_root(sb);
1475+
generation = btrfs_super_chunk_root_generation(sb);
1476+
level = btrfs_super_chunk_root_level(sb);
1477+
}
14641478

14651479
ret = read_root_node(fs_info, fs_info->chunk_root, chunk_root_bytenr,
1466-
generation, btrfs_super_chunk_root_level(sb));
1480+
generation, level);
14671481
if (ret) {
14681482
if (fs_info->ignore_chunk_tree_error) {
14691483
warning("cannot read chunk root, continue anyway");

0 commit comments

Comments
 (0)