diff mbox series

[2/2] btrfs-progs: corrupt-block: re-generate the checksum for generation corruption

Message ID 426aaa1e6b83b99fddd66bc892499aca03105748.1663053391.git.wqu@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs-progs: make corrupt-block metadata geneartion corruption work again | expand

Commit Message

Qu Wenruo Sept. 13, 2022, 7:19 a.m. UTC
[BUG]
If using btrfs-corrupt-block to corrupt the generation of a tree
block (in my example, it's csum root), it will cause csum mismatch other
than the expected transid mismatch:

 # ./btrfs-corrupt-block --metadata-block 30474240 -f generation \
   /dev/test/scratch1
 # btrfs check /dev/test/scratch1
 Opening filesystem to check...
 checksum verify failed on 30474240 wanted 0xb3e8059a found 0xb4a4b45c
 checksum verify failed on 30474240 wanted 0xb3e8059a found 0xb4a4b45c
 checksum verify failed on 30474240 wanted 0xb3e8059a found 0xb4a4b45c
 Csum didn't match
 ERROR: could not setup csum tree
 ERROR: cannot open file system

[CAUSE]
Inside the switch branch BTRFS_METADATA_BLOCK_GENERATION in
corrupt_metadata_block(), we just set the generation and trigger
write_and_map_eb().

However write_and_map_eb() doesn't re-generate the checksum by itself,
thus we make the victim tree block to have a stale checksum.

[FIX]
Just call csum_tree_block_size() before write_and_map_eb().

Now the corrupted fs have the expected corruption pattern now:

 # btrfs check /dev/test/scratch1
 Opening filesystem to check...
 parent transid verify failed on 30474240 wanted 7 found 11814770867473404344
 parent transid verify failed on 30474240 wanted 7 found 11814770867473404344
 parent transid verify failed on 30474240 wanted 7 found 11814770867473404344
 Ignoring transid failure
 ...

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 btrfs-corrupt-block.c | 2 ++
 1 file changed, 2 insertions(+)
diff mbox series

Patch

diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
index 4fa27b98fe16..b6aefe658ead 100644
--- a/btrfs-corrupt-block.c
+++ b/btrfs-corrupt-block.c
@@ -885,6 +885,8 @@  static int corrupt_metadata_block(struct btrfs_fs_info *fs_info, u64 block,
 		u64 bogus = generate_u64(orig);
 
 		btrfs_set_header_generation(eb, bogus);
+		csum_tree_block_size(eb, fs_info->csum_size, 0,
+				     fs_info->csum_type);
 		ret = write_and_map_eb(fs_info, eb);
 		free_extent_buffer(eb);
 		if (ret < 0) {