Skip to content

Commit 2996e1f

Browse files
Johannes Thumshirnkdave
authored andcommitted
btrfs: factor our read/write stage off csum_tree_block into its callers
Currently csum_tree_block() does two things, first it as it's name suggests it calculates the checksum for a tree-block. But it also writes this checksum to disk or reads an extent_buffer from disk and compares the checksum with the calculated checksum, depending on the verify argument. Furthermore one of the two callers passes in '1' for the verify argument, the other one passes in '0'. For clarity and less layering violations, factor out the second stage in csum_tree_block()'s callers. Suggested-by: Nikolay Borisov <[email protected]> Reviewed-by: Qu Wenruo <[email protected]> Reviewed-by: Nikolay Borisov <[email protected]> Signed-off-by: Johannes Thumshirn <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 37624b5 commit 2996e1f

File tree

1 file changed

+29
-26
lines changed

1 file changed

+29
-26
lines changed

fs/btrfs/disk-io.c

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -260,15 +260,12 @@ void btrfs_csum_final(u32 crc, u8 *result)
260260
}
261261

262262
/*
263-
* compute the csum for a btree block, and either verify it or write it
264-
* into the csum field of the block.
263+
* Compute the csum of a btree block and store the result to provided buffer.
264+
*
265+
* Returns error if the extent buffer cannot be mapped.
265266
*/
266-
static int csum_tree_block(struct btrfs_fs_info *fs_info,
267-
struct extent_buffer *buf,
268-
int verify)
267+
static int csum_tree_block(struct extent_buffer *buf, u8 *result)
269268
{
270-
u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
271-
char result[BTRFS_CSUM_SIZE];
272269
unsigned long len;
273270
unsigned long cur_len;
274271
unsigned long offset = BTRFS_CSUM_SIZE;
@@ -300,23 +297,6 @@ static int csum_tree_block(struct btrfs_fs_info *fs_info,
300297

301298
btrfs_csum_final(crc, result);
302299

303-
if (verify) {
304-
if (memcmp_extent_buffer(buf, result, 0, csum_size)) {
305-
u32 val;
306-
u32 found = 0;
307-
memcpy(&found, result, csum_size);
308-
309-
read_extent_buffer(buf, &val, 0, csum_size);
310-
btrfs_warn_rl(fs_info,
311-
"%s checksum verify failed on %llu wanted %X found %X level %d",
312-
fs_info->sb->s_id, buf->start,
313-
val, found, btrfs_header_level(buf));
314-
return -EUCLEAN;
315-
}
316-
} else {
317-
write_extent_buffer(buf, result, 0, csum_size);
318-
}
319-
320300
return 0;
321301
}
322302

@@ -533,6 +513,8 @@ static int csum_dirty_buffer(struct btrfs_fs_info *fs_info, struct page *page)
533513
{
534514
u64 start = page_offset(page);
535515
u64 found_start;
516+
u8 result[BTRFS_CSUM_SIZE];
517+
u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
536518
struct extent_buffer *eb;
537519

538520
eb = (struct extent_buffer *)page->private;
@@ -552,7 +534,11 @@ static int csum_dirty_buffer(struct btrfs_fs_info *fs_info, struct page *page)
552534
ASSERT(memcmp_extent_buffer(eb, fs_info->fs_devices->metadata_uuid,
553535
btrfs_header_fsid(), BTRFS_FSID_SIZE) == 0);
554536

555-
return csum_tree_block(fs_info, eb, 0);
537+
if (csum_tree_block(eb, result))
538+
return -EINVAL;
539+
540+
write_extent_buffer(eb, result, 0, csum_size);
541+
return 0;
556542
}
557543

558544
static int check_tree_block_fsid(struct btrfs_fs_info *fs_info,
@@ -595,7 +581,9 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
595581
struct extent_buffer *eb;
596582
struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
597583
struct btrfs_fs_info *fs_info = root->fs_info;
584+
u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
598585
int ret = 0;
586+
u8 result[BTRFS_CSUM_SIZE];
599587
int reads_done;
600588

601589
if (!page->private)
@@ -642,10 +630,25 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
642630
btrfs_set_buffer_lockdep_class(btrfs_header_owner(eb),
643631
eb, found_level);
644632

645-
ret = csum_tree_block(fs_info, eb, 1);
633+
ret = csum_tree_block(eb, result);
646634
if (ret)
647635
goto err;
648636

637+
if (memcmp_extent_buffer(eb, result, 0, csum_size)) {
638+
u32 val;
639+
u32 found = 0;
640+
641+
memcpy(&found, result, csum_size);
642+
643+
read_extent_buffer(eb, &val, 0, csum_size);
644+
btrfs_warn_rl(fs_info,
645+
"%s checksum verify failed on %llu wanted %x found %x level %d",
646+
fs_info->sb->s_id, eb->start,
647+
val, found, btrfs_header_level(eb));
648+
ret = -EUCLEAN;
649+
goto err;
650+
}
651+
649652
/*
650653
* If this is a leaf block and it is corrupt, set the corrupt bit so
651654
* that we don't try and read the other copies of this block, just

0 commit comments

Comments
 (0)