mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 18:43:33 +02:00
md/raid5: make sure max_sectors is not less than io_opt
Otherwise, even if user issue IO by io_opt, such IO will be split by max_sectors before they are submitted to raid5. For consequence, full stripe IO is impossible. BTW, dm-raid5 is not affected and still have such problem. Link: https://lore.kernel.org/linux-raid/20260114171241.3043364-7-yukuai@fnnas.com Signed-off-by: Yu Kuai <yukuai@fnnas.com>
This commit is contained in:
parent
9340a95d48
commit
4ffe28ed0d
|
|
@ -777,14 +777,14 @@ struct stripe_request_ctx {
|
|||
/* last sector in the request */
|
||||
sector_t last_sector;
|
||||
|
||||
/* the request had REQ_PREFLUSH, cleared after the first stripe_head */
|
||||
bool do_flush;
|
||||
|
||||
/*
|
||||
* bitmap to track stripe sectors that have been added to stripes
|
||||
* add one to account for unaligned requests
|
||||
*/
|
||||
DECLARE_BITMAP(sectors_to_do, RAID5_MAX_REQ_STRIPES + 1);
|
||||
|
||||
/* the request had REQ_PREFLUSH, cleared after the first stripe_head */
|
||||
bool do_flush;
|
||||
unsigned long sectors_to_do[];
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -6127,7 +6127,7 @@ static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
|
|||
bi->bi_next = NULL;
|
||||
|
||||
ctx = mempool_alloc(conf->ctx_pool, GFP_NOIO);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
memset(ctx, 0, conf->ctx_size);
|
||||
ctx->first_sector = logical_sector;
|
||||
ctx->last_sector = bio_end_sector(bi);
|
||||
/*
|
||||
|
|
@ -7743,6 +7743,25 @@ static int only_parity(int raid_disk, int algo, int raid_disks, int max_degraded
|
|||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
else
|
||||
size = BITS_TO_LONGS(
|
||||
queue_max_hw_sectors(conf->mddev->gendisk->queue) >>
|
||||
RAID5_STRIPE_SHIFT(conf));
|
||||
|
||||
conf->ctx_size = struct_size(ctx, sectors_to_do, size);
|
||||
conf->ctx_pool = mempool_create_kmalloc_pool(NR_RAID_BIOS,
|
||||
conf->ctx_size);
|
||||
|
||||
return conf->ctx_pool ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
static int raid5_set_limits(struct mddev *mddev)
|
||||
{
|
||||
struct r5conf *conf = mddev->private;
|
||||
|
|
@ -7799,6 +7818,8 @@ static int raid5_set_limits(struct mddev *mddev)
|
|||
* Limit the max sectors based on this.
|
||||
*/
|
||||
lim.max_hw_sectors = RAID5_MAX_REQ_STRIPES << RAID5_STRIPE_SHIFT(conf);
|
||||
if ((lim.max_hw_sectors << 9) < lim.io_opt)
|
||||
lim.max_hw_sectors = lim.io_opt >> 9;
|
||||
|
||||
/* No restrictions on the number of segments in the request */
|
||||
lim.max_segments = USHRT_MAX;
|
||||
|
|
@ -8071,12 +8092,9 @@ static int raid5_run(struct mddev *mddev)
|
|||
goto abort;
|
||||
}
|
||||
|
||||
conf->ctx_pool = mempool_create_kmalloc_pool(NR_RAID_BIOS,
|
||||
sizeof(struct stripe_request_ctx));
|
||||
if (!conf->ctx_pool) {
|
||||
ret = -ENOMEM;
|
||||
ret = raid5_create_ctx_pool(conf);
|
||||
if (ret)
|
||||
goto abort;
|
||||
}
|
||||
|
||||
ret = log_init(conf, journal_dev, raid5_has_ppl(conf));
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -692,6 +692,7 @@ struct r5conf {
|
|||
struct r5pending_data *next_pending_data;
|
||||
|
||||
mempool_t *ctx_pool;
|
||||
int ctx_size;
|
||||
};
|
||||
|
||||
#if PAGE_SIZE == DEFAULT_STRIPE_SIZE
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user