[PATCH] md/raid5: fix stripe_request_ctx bitmap sizing for unaligned bios

"Chen Cheng" <[email protected]>
Newsgroups gmane.linux.kernel,gmane.linux.raid
Message-ID <[email protected]>
From: Chen Cheng <[email protected]>

stripe_request_ctx.sectors_to_do needs one extra bit for unaligned bios,
as documented by the existing comment.

raid5_make_request() rounds the bio start down to a stripe boundary, but
keeps ctx->last_sector at bio_end_sector(bio). As a result, an unaligned
bio with len == max_hw_sectors can span one more stripe than
max_hw_sectors >> RAID5_STRIPE_SHIFT(conf).

For example, if RAID5_STRIPE_SECTORS(conf) == 8 and max_hw_sectors ==
2048, a bio at sector 1 with len 2048 sectors yields stripe_cnt = 257.
bitmap_set(ctx->sectors_to_do, 0, 257) then touches the first bit beyond
a 256-bit allocation, matching the KASAN report:

  __bitmap_set
  bitmap_set
  raid5_make_request

Restore the missing extra bit in both ctx_pool sizing paths.

This bug is harder to reproduce from userspace on v7.1 because
lim.chunk_sectors = lim.io_opt >> 9 causes the block layer to split
large unaligned bios on full-stripe boundaries before they reach
raid5_make_request(). That masks the reproducer, but does not fix the
under-allocation.

Signed-off-by: Chen Cheng <[email protected]>
---
 drivers/md/raid5.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 65ae7d8930fc..9ece79e608f7 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -7756,15 +7756,15 @@ static int raid5_create_ctx_pool(struct r5conf *conf)
 {
 	struct stripe_request_ctx *ctx;
 	int size;
 
 	if (mddev_is_dm(conf->mddev))
-		size = BITS_TO_LONGS(RAID5_MAX_REQ_STRIPES);
+		size = BITS_TO_LONGS(RAID5_MAX_REQ_STRIPES + 1);
 	else
 		size = BITS_TO_LONGS(
-			queue_max_hw_sectors(conf->mddev->gendisk->queue) >>
-			RAID5_STRIPE_SHIFT(conf));
+			(queue_max_hw_sectors(conf->mddev->gendisk->queue) >>
+			 RAID5_STRIPE_SHIFT(conf)) + 1);
 
 	conf->ctx_size = struct_size(ctx, sectors_to_do, size);
 	conf->ctx_pool = mempool_create_kmalloc_pool(NR_RAID_BIOS,
 						     conf->ctx_size);
 
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.