]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
btrfs: add a btrfs_data_csum_ok helper
authorChristoph Hellwig <hch@lst.de>
Sat, 21 Jan 2023 06:50:06 +0000 (07:50 +0100)
committerDavid Sterba <dsterba@suse.com>
Wed, 15 Feb 2023 18:38:51 +0000 (19:38 +0100)
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>
fs/btrfs/btrfs_inode.h
fs/btrfs/inode.c

index 195c09e20609e48ffed8a01f73056937451f3577..3faabcef9898fb283ed93007bb76738fa7919697 100644 (file)
@@ -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);
index 598897b0d661daea70a92e85fd167646cda300e2..ba90f90e3d87c89c1d959427ce72652f4c5784c8 100644 (file)
@@ -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