md: raid1: check if adding pages to resync bio fails
authorJohannes Thumshirn <johannes.thumshirn@wdc.com>
Wed, 31 May 2023 11:50:38 +0000 (04:50 -0700)
committerJens Axboe <axboe@kernel.dk>
Thu, 1 Jun 2023 15:13:31 +0000 (09:13 -0600)
Check if adding pages to resync bio fails and if bail out.

As the comment above suggests this cannot happen, WARN if it actually
happens. Technically __bio_add_pages() would be sufficient here, but
asserting the pages actually get added to the bio is preferred.

This way we can mark bio_add_pages as __must_check.

Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Link: https://lore.kernel.org/r/33aea4c271220dc9bcab58c4b7bec478c1511142.1685532726.git.johannes.thumshirn@wdc.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/md/raid1-10.c
drivers/md/raid10.c

index e61f6cad4e08e9bef57faaecfef4305f1a621200..cd349e69ed7756ff85baf4b6a65f33b98c3588ae 100644 (file)
@@ -101,11 +101,12 @@ static void md_bio_reset_resync_pages(struct bio *bio, struct resync_pages *rp,
                struct page *page = resync_fetch_page(rp, idx);
                int len = min_t(int, size, PAGE_SIZE);
 
-               /*
-                * won't fail because the vec table is big
-                * enough to hold all these pages
-                */
-               bio_add_page(bio, page, len, 0);
+               if (WARN_ON(!bio_add_page(bio, page, len, 0))) {
+                       bio->bi_status = BLK_STS_RESOURCE;
+                       bio_endio(bio);
+                       return;
+               }
+
                size -= len;
        } while (idx++ < RESYNC_PAGES && size > 0);
 }
index 4fcfcb350d2b43c3ffa5d2f2cb581d7ee47a5321..381c21f7fb06220c44d59fa9b8ca3b34c1fc86ae 100644 (file)
@@ -3819,11 +3819,11 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
                for (bio= biolist ; bio ; bio=bio->bi_next) {
                        struct resync_pages *rp = get_resync_pages(bio);
                        page = resync_fetch_page(rp, page_idx);
-                       /*
-                        * won't fail because the vec table is big enough
-                        * to hold all these pages
-                        */
-                       bio_add_page(bio, page, len, 0);
+                       if (WARN_ON(!bio_add_page(bio, page, len, 0))) {
+                               bio->bi_status = BLK_STS_RESOURCE;
+                               bio_endio(bio);
+                               goto giveup;
+                       }
                }
                nr_sectors += len>>9;
                sector_nr += len>>9;
@@ -4997,11 +4997,11 @@ read_more:
                if (len > PAGE_SIZE)
                        len = PAGE_SIZE;
                for (bio = blist; bio ; bio = bio->bi_next) {
-                       /*
-                        * won't fail because the vec table is big enough
-                        * to hold all these pages
-                        */
-                       bio_add_page(bio, page, len, 0);
+                       if (WARN_ON(!bio_add_page(bio, page, len, 0))) {
+                               bio->bi_status = BLK_STS_RESOURCE;
+                               bio_endio(bio);
+                               return sectors_done;
+                       }
                }
                sector_nr += len >> 9;
                nr_sectors += len >> 9;