When checksumming the encrypted bio on writes we need to know which
logical address this checksum is for.  At the point where we get the
encrypted bio the bi_sector is the physical location on the target disk,
so we need to save the original logical offset in the btrfs_bio.  Then
we can use this when csum'ing the bio instead of the
bio->iter.bi_sector.

Signed-off-by: Josef Bacik <jo...@toxicpanda.com>
---
 fs/btrfs/bio.c       | 9 +++++++++
 fs/btrfs/bio.h       | 3 +++
 fs/btrfs/file-item.c | 2 +-
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c
index 90e4d4709fa3..7d6931e53beb 100644
--- a/fs/btrfs/bio.c
+++ b/fs/btrfs/bio.c
@@ -96,6 +96,7 @@ static struct btrfs_bio *btrfs_split_bio(struct btrfs_fs_info 
*fs_info,
        if (bbio_has_ordered_extent(bbio)) {
                refcount_inc(&orig_bbio->ordered->refs);
                bbio->ordered = orig_bbio->ordered;
+               orig_bbio->orig_logical += map_length;
        }
        atomic_inc(&orig_bbio->pending_ios);
        return bbio;
@@ -674,6 +675,14 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int 
mirror_num)
                goto fail;
        }
 
+       /*
+        * For fscrypt writes we will get the encrypted bio after we've remapped
+        * our bio to the physical disk location, so we need to save the
+        * original bytenr so we know what we're checksumming.
+        */
+       if (bio_op(bio) == REQ_OP_WRITE && is_data_bbio(bbio))
+               bbio->orig_logical = logical;
+
        map_length = min(map_length, length);
        if (use_append)
                map_length = min(map_length, fs_info->max_zone_append_size);
diff --git a/fs/btrfs/bio.h b/fs/btrfs/bio.h
index ca79decee060..5d3f53dcd6d5 100644
--- a/fs/btrfs/bio.h
+++ b/fs/btrfs/bio.h
@@ -54,11 +54,14 @@ struct btrfs_bio {
                 * - pointer to the checksums for this bio
                 * - original physical address from the allocator
                 *   (for zone append only)
+                * - original logical address, used for checksumming fscrypt
+                *   bios.
                 */
                struct {
                        struct btrfs_ordered_extent *ordered;
                        struct btrfs_ordered_sum *sums;
                        u64 orig_physical;
+                       u64 orig_logical;
                };
 
                /* For metadata reads: parentness verification. */
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index d925d6d98bf4..26e3bc602655 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -756,7 +756,7 @@ blk_status_t btrfs_csum_one_bio(struct btrfs_bio *bbio, 
struct bio *bio)
        sums->len = bio->bi_iter.bi_size;
        INIT_LIST_HEAD(&sums->list);
 
-       sums->logical = bio->bi_iter.bi_sector << SECTOR_SHIFT;
+       sums->logical = bbio->orig_logical;
        index = 0;
 
        shash->tfm = fs_info->csum_shash;
-- 
2.41.0

Reply via email to