block: handle bio_split_to_limits() NULL return
authorJens Axboe <axboe@kernel.dk>
Wed, 4 Jan 2023 15:51:19 +0000 (08:51 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Jan 2023 10:58:33 +0000 (11:58 +0100)
commit 613b14884b8595e20b9fac4126bf627313827fbe upstream.

This can't happen right now, but in preparation for allowing
bio_split_to_limits() returning NULL if it ended the bio, check for it
in all the callers.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
block/blk-merge.c
block/blk-mq.c
drivers/block/drbd/drbd_req.c
drivers/block/ps3vram.c
drivers/md/dm.c
drivers/md/md.c
drivers/nvme/host/multipath.c
drivers/s390/block/dcssblk.c

index f46c87ef951df46aa0610ce6fb44409e82c3f799..84f03d066cb31edf9463c919beb0216054b7200a 100644 (file)
@@ -358,11 +358,13 @@ struct bio *__bio_split_to_limits(struct bio *bio, struct queue_limits *lim,
        default:
                split = bio_split_rw(bio, lim, nr_segs, bs,
                                get_max_io_size(bio, lim) << SECTOR_SHIFT);
+               if (IS_ERR(split))
+                       return NULL;
                break;
        }
 
        if (split) {
-               /* there isn't chance to merge the splitted bio */
+               /* there isn't chance to merge the split bio */
                split->bi_opf |= REQ_NOMERGE;
 
                blkcg_bio_issue_init(split);
index 0b855e033a8348f0b3748bb358ec2e304a551f5c..63abbe342b28c8fd60ffdcd0367ebfe8da0784a3 100644 (file)
@@ -2919,8 +2919,11 @@ void blk_mq_submit_bio(struct bio *bio)
        blk_status_t ret;
 
        bio = blk_queue_bounce(bio, q);
-       if (bio_may_exceed_limits(bio, &q->limits))
+       if (bio_may_exceed_limits(bio, &q->limits)) {
                bio = __bio_split_to_limits(bio, &q->limits, &nr_segs);
+               if (!bio)
+                       return;
+       }
 
        if (!bio_integrity_prep(bio))
                return;
index 7f9bcc82fc9c4935a4ccd0a10b5d8d1f6051d2a1..d700bf06b534fb3197104e4929d12960a3e49e06 100644 (file)
@@ -1607,6 +1607,8 @@ void drbd_submit_bio(struct bio *bio)
        struct drbd_device *device = bio->bi_bdev->bd_disk->private_data;
 
        bio = bio_split_to_limits(bio);
+       if (!bio)
+               return;
 
        /*
         * what we "blindly" assume:
index c76e0148eada3302a04b81a886fa7cdb34df2de1..574e470b220b09bf3e032f14a60998cfe5d833ce 100644 (file)
@@ -587,6 +587,8 @@ static void ps3vram_submit_bio(struct bio *bio)
        dev_dbg(&dev->core, "%s\n", __func__);
 
        bio = bio_split_to_limits(bio);
+       if (!bio)
+               return;
 
        spin_lock_irq(&priv->lock);
        busy = !bio_list_empty(&priv->list);
index e30c2d2bc9c783d3cce9cf226e4de03a3eb7c255..d49809e9db96eb787e415a6cbb1ee1eb3f21af5b 100644 (file)
@@ -1755,6 +1755,8 @@ static void dm_split_and_process_bio(struct mapped_device *md,
                 * otherwise associated queue_limits won't be imposed.
                 */
                bio = bio_split_to_limits(bio);
+               if (!bio)
+                       return;
        }
 
        init_clone_info(&ci, md, map, bio, is_abnormal);
index fd82881761d345a43a8ec9b512b31414cdd9a58a..b911085060dc39b21edb8eb82524b14f683e6963 100644 (file)
@@ -443,6 +443,8 @@ static void md_submit_bio(struct bio *bio)
        }
 
        bio = bio_split_to_limits(bio);
+       if (!bio)
+               return;
 
        if (mddev->ro == 1 && unlikely(rw == WRITE)) {
                if (bio_sectors(bio) != 0)
index 7e025b8948cbf7bffa667d67362207ddcd241f28..d09ed00701743ee4d3b10cbc19a6f4d60c822cf9 100644 (file)
@@ -351,6 +351,8 @@ static void nvme_ns_head_submit_bio(struct bio *bio)
         * pool from the original queue to allocate the bvecs from.
         */
        bio = bio_split_to_limits(bio);
+       if (!bio)
+               return;
 
        srcu_idx = srcu_read_lock(&head->srcu);
        ns = nvme_find_path(head);
index b392b9f5482e0e1f3c3e3c67118876981b7cfe7a..c0f85ffb2b62de7ae80c32b456fc49673e57e50e 100644 (file)
@@ -865,6 +865,8 @@ dcssblk_submit_bio(struct bio *bio)
        unsigned long bytes_done;
 
        bio = bio_split_to_limits(bio);
+       if (!bio)
+               return;
 
        bytes_done = 0;
        dev_info = bio->bi_bdev->bd_disk->private_data;