]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
btrfs: add orig_logical to btrfs_bio for encryption
authorJosef Bacik <josef@toxicpanda.com>
Tue, 18 Nov 2025 16:08:40 +0000 (17:08 +0100)
committerDavid Sterba <dsterba@suse.com>
Tue, 25 Nov 2025 00:52:23 +0000 (01:52 +0100)
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 checksumming the bio instead of the
bio->iter.bi_sector.

Note: The patch was taken from v5 of fscrypt patchset
(https://lore.kernel.org/linux-btrfs/cover.1706116485.git.josef@toxicpanda.com/)
which was handled over time by various people: Omar Sandoval, Sweet Tea
Dorminy, Josef Bacik.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Daniel Vacek <neelx@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
[ add note ]
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/bio.c
fs/btrfs/bio.h
fs/btrfs/file-item.c

index 1b38e3ee0a3365c674fa6296906a0c74c18f4e5c..fa1d321a2fb83861b9b42bd422ce0a4edf3343ab 100644 (file)
@@ -94,6 +94,8 @@ 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;
+               bbio->orig_logical = orig_bbio->orig_logical;
+               orig_bbio->orig_logical += map_length;
        }
        bbio->csum_search_commit_root = orig_bbio->csum_search_commit_root;
        atomic_inc(&orig_bbio->pending_ios);
@@ -765,6 +767,14 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
                goto end_bbio;
        }
 
+       /*
+        * 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 = btrfs_append_map_length(bbio, map_length);
index 035145909b003c9a0eb80ca09a953285a0674639..1be74209f0b8dbeafd8e38b35ffce29d19f3af4e 100644 (file)
@@ -52,6 +52,7 @@ 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;
@@ -60,6 +61,7 @@ struct btrfs_bio {
                        struct completion csum_done;
                        struct bvec_iter csum_saved_iter;
                        u64 orig_physical;
+                       u64 orig_logical;
                };
 
                /* For metadata reads: parentness verification. */
index b17632ea085f255d658d979ae97cf8baaf5b7013..14e5257f0f04444a89d1c92b094a256ac827c3d7 100644 (file)
@@ -824,7 +824,7 @@ int btrfs_csum_one_bio(struct btrfs_bio *bbio, bool async)
        if (!sums)
                return -ENOMEM;
 
-       sums->logical = bio->bi_iter.bi_sector << SECTOR_SHIFT;
+       sums->logical = bbio->orig_logical;
        sums->len = bio->bi_iter.bi_size;
        INIT_LIST_HEAD(&sums->list);
        bbio->sums = sums;