btrfs: add a btrfs_data_csum_ok helper
Add a new checksumming helper that wraps btrfs_check_data_csum and does all the checks to if we're dealing with some form of nodatacsum I/O. This helper will be used by the new storage layer checksum validation and repair code. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
1c2b3ee3b0
commit
e52190441b
@ -423,6 +423,8 @@ int btrfs_check_sector_csum(struct btrfs_fs_info *fs_info, struct page *page,
|
||||
u32 pgoff, u8 *csum, const u8 * const csum_expected);
|
||||
int btrfs_check_data_csum(struct btrfs_inode *inode, struct btrfs_bio *bbio,
|
||||
u32 bio_offset, struct page *page, u32 pgoff);
|
||||
bool btrfs_data_csum_ok(struct btrfs_bio *bbio, struct btrfs_device *dev,
|
||||
u32 bio_offset, struct bio_vec *bv);
|
||||
unsigned int btrfs_verify_data_csum(struct btrfs_bio *bbio,
|
||||
u32 bio_offset, struct page *page,
|
||||
u64 start, u64 end);
|
||||
|
@ -3495,6 +3495,44 @@ zeroit:
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the checksum of a single data sector.
|
||||
*
|
||||
* @bbio: btrfs_io_bio which contains the csum
|
||||
* @dev: device the sector is on
|
||||
* @bio_offset: offset to the beginning of the bio (in bytes)
|
||||
* @bv: bio_vec to check
|
||||
*
|
||||
* Check if the checksum on a data block is valid. When a checksum mismatch is
|
||||
* detected, report the error and fill the corrupted range with zero.
|
||||
*
|
||||
* Return %true if the sector is ok or had no checksum to start with, else %false.
|
||||
*/
|
||||
bool btrfs_data_csum_ok(struct btrfs_bio *bbio, struct btrfs_device *dev,
|
||||
u32 bio_offset, struct bio_vec *bv)
|
||||
{
|
||||
struct btrfs_inode *inode = bbio->inode;
|
||||
u64 file_offset = bbio->file_offset + bio_offset;
|
||||
u64 end = file_offset + bv->bv_len - 1;
|
||||
|
||||
if (!bbio->csum)
|
||||
return true;
|
||||
|
||||
if (btrfs_is_data_reloc_root(inode->root) &&
|
||||
test_range_bit(&inode->io_tree, file_offset, end, EXTENT_NODATASUM,
|
||||
1, NULL)) {
|
||||
/* Skip the range without csum for data reloc inode */
|
||||
clear_extent_bits(&inode->io_tree, file_offset, end,
|
||||
EXTENT_NODATASUM);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (btrfs_check_data_csum(inode, bbio, bio_offset, bv->bv_page,
|
||||
bv->bv_offset) < 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* When reads are done, we need to check csums to verify the data is correct.
|
||||
* if there's a match, we allow the bio to finish. If not, the code in
|
||||
|
Loading…
Reference in New Issue
Block a user