User reported that btrfs-progs misc-tests/028-superblock-recover fails:
    [TEST/misc]   028-superblock-recover
unexpected success: mounted fs with corrupted superblock
test failed for case 028-superblock-recover

The test case expects that a broken image with bad superblock will be
rejected to be mounted. However, the test image just passed csum check
of superblock and was successfully mounted.

Commit 55fc29bed8dd ("btrfs: use cached value of fs_info::csum_size
everywhere") replaces all calls to btrfs_super_csum_size by
fs_info::csum_size. The calls include the place where fs_info->csum_size
is not initialized. So btrfs_check_super_csum() passes because memcmp()
with len 0 always returns 0.

Fix it by caching csum size in btrfs_fs_info::csum_size once we know the
csum type in superblock is valid in open_ctree().

Link: https://github.com/kdave/btrfs-progs/issues/250
Fixes: 55fc29bed8dd ("btrfs: use cached value of fs_info::csum_size everywhere")
Signed-off-by: Su Yue <[email protected]>
---
 fs/btrfs/disk-io.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 6b35b7e88136..07a2b4f69b10 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3044,6 +3044,8 @@ int __cold open_ctree(struct super_block *sb, struct 
btrfs_fs_devices *fs_device
                goto fail_alloc;
        }
 
+       fs_info->csum_size = btrfs_super_csum_size(disk_super);
+
        ret = btrfs_init_csum_hash(fs_info, csum_type);
        if (ret) {
                err = ret;
@@ -3161,7 +3163,6 @@ int __cold open_ctree(struct super_block *sb, struct 
btrfs_fs_devices *fs_device
        fs_info->nodesize = nodesize;
        fs_info->sectorsize = sectorsize;
        fs_info->sectorsize_bits = ilog2(sectorsize);
-       fs_info->csum_size = btrfs_super_csum_size(disk_super);
        fs_info->csums_per_leaf = BTRFS_MAX_ITEM_SIZE(fs_info) / 
fs_info->csum_size;
        fs_info->stripesize = stripesize;
 
-- 
2.30.0

Reply via email to