]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
dm: test for REQ_ATOMIC in dm_accept_partial_bio()
authorMikulas Patocka <mpatocka@redhat.com>
Wed, 5 Nov 2025 15:01:33 +0000 (16:01 +0100)
committerMikulas Patocka <mpatocka@redhat.com>
Wed, 10 Dec 2025 18:28:12 +0000 (19:28 +0100)
Any bio with REQ_ATOMIC flag set should never be split or partially
completed, so BUG_ON() on this scenario in dm_accept_partial_bio() (whose
intent is to allow partial completions).

Also, we must reject atomic bio to targets that don't support them,
otherwise this BUG could be triggered by stray bios that have the
REQ_ATOMIC set.

Signed-off-by: John Garry <john.g.garry@oracle.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Tested-by: John Garry <john.g.garry@oracle.com>
drivers/md/dm.c

index 557f3f52edf4fe28dfc851bae41ab8b29abc29bd..44be646574b77b5b509f5c4e69d792976853ab04 100644 (file)
@@ -1321,6 +1321,7 @@ void dm_accept_partial_bio(struct bio *bio, unsigned int n_sectors)
        BUG_ON(dm_tio_flagged(tio, DM_TIO_IS_DUPLICATE_BIO));
        BUG_ON(bio_sectors > *tio->len_ptr);
        BUG_ON(n_sectors > bio_sectors);
+       BUG_ON(bio->bi_opf & REQ_ATOMIC);
 
        if (static_branch_unlikely(&zoned_enabled) &&
            unlikely(bdev_is_zoned(bio->bi_bdev))) {
@@ -1735,8 +1736,12 @@ static blk_status_t __split_and_process_bio(struct clone_info *ci)
        ci->submit_as_polled = !!(ci->bio->bi_opf & REQ_POLLED);
 
        len = min_t(sector_t, max_io_len(ti, ci->sector), ci->sector_count);
-       if (ci->bio->bi_opf & REQ_ATOMIC && len != ci->sector_count)
-               return BLK_STS_IOERR;
+       if (ci->bio->bi_opf & REQ_ATOMIC) {
+               if (unlikely(!dm_target_supports_atomic_writes(ti->type)))
+                       return BLK_STS_IOERR;
+               if (unlikely(len != ci->sector_count))
+                       return BLK_STS_IOERR;
+       }
 
        setup_split_accounting(ci, len);