mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 23:09:29 +02:00
md/raid10: resize r10bio_pool for reshape
When reshape grows raid_disks, the pool must also switch to new geometry object size , and allocate a new geometry size pool and replace the old. But not for shrinking reshape, because regular I/O can still use the prev geo for sectors that have not crossed reshape_progress yet. Signed-off-by: Chen Cheng <chencheng@fnnas.com> Link: https://patch.msgid.link/20260711100352.425177-3-chencheng@fnnas.com Signed-off-by: Yu Kuai <yukuai@fygo.io>
This commit is contained in:
+33
-13
@@ -103,13 +103,23 @@ static inline struct r10bio *get_resync_r10bio(struct bio *bio)
|
||||
return get_resync_pages(bio)->raid_bio;
|
||||
}
|
||||
|
||||
static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
|
||||
static inline int calc_r10bio_size(unsigned int raid_disks)
|
||||
{
|
||||
struct r10conf *conf = data;
|
||||
int size = offsetof(struct r10bio, devs[conf->geo.raid_disks]);
|
||||
return offsetof(struct r10bio, devs[raid_disks]);
|
||||
}
|
||||
|
||||
/* allocate a r10bio with room for raid_disks entries in the
|
||||
* bios array */
|
||||
static mempool_t *create_r10bio_pool(unsigned int raid_disks)
|
||||
{
|
||||
int size = calc_r10bio_size(raid_disks);
|
||||
|
||||
return mempool_create_kmalloc_pool(NR_RAID_BIOS, size);
|
||||
}
|
||||
|
||||
static struct r10bio *alloc_r10bio(unsigned int raid_disks, gfp_t gfp_flags)
|
||||
{
|
||||
int size = calc_r10bio_size(raid_disks);
|
||||
|
||||
/* allocate a r10bio sized for current geometry */
|
||||
return kzalloc(size, gfp_flags);
|
||||
}
|
||||
|
||||
@@ -137,7 +147,7 @@ static void * r10buf_pool_alloc(gfp_t gfp_flags, void *data)
|
||||
int nalloc, nalloc_rp;
|
||||
struct resync_pages *rps;
|
||||
|
||||
r10_bio = r10bio_pool_alloc(gfp_flags, conf);
|
||||
r10_bio = alloc_r10bio(conf->geo.raid_disks, gfp_flags);
|
||||
if (!r10_bio)
|
||||
return NULL;
|
||||
|
||||
@@ -277,7 +287,7 @@ static void free_r10bio(struct r10bio *r10_bio)
|
||||
struct r10conf *conf = r10_bio->mddev->private;
|
||||
|
||||
put_all_bios(conf, r10_bio);
|
||||
mempool_free(r10_bio, &conf->r10bio_pool);
|
||||
mempool_free(r10_bio, conf->r10bio_pool);
|
||||
}
|
||||
|
||||
static void put_buf(struct r10bio *r10_bio)
|
||||
@@ -1492,7 +1502,7 @@ static bool __make_request(struct mddev *mddev, struct bio *bio, int sectors)
|
||||
struct r10conf *conf = mddev->private;
|
||||
struct r10bio *r10_bio;
|
||||
|
||||
r10_bio = mempool_alloc(&conf->r10bio_pool, GFP_NOIO);
|
||||
r10_bio = mempool_alloc(conf->r10bio_pool, GFP_NOIO);
|
||||
|
||||
r10_bio->master_bio = bio;
|
||||
r10_bio->sectors = sectors;
|
||||
@@ -1688,7 +1698,7 @@ static int raid10_handle_discard(struct mddev *mddev, struct bio *bio)
|
||||
(last_stripe_index << geo->chunk_shift);
|
||||
|
||||
retry_discard:
|
||||
r10_bio = mempool_alloc(&conf->r10bio_pool, GFP_NOIO);
|
||||
r10_bio = mempool_alloc(conf->r10bio_pool, GFP_NOIO);
|
||||
r10_bio->mddev = mddev;
|
||||
r10_bio->state = 0;
|
||||
r10_bio->sectors = 0;
|
||||
@@ -3790,7 +3800,7 @@ static void raid10_free_conf(struct r10conf *conf)
|
||||
if (!conf)
|
||||
return;
|
||||
|
||||
mempool_exit(&conf->r10bio_pool);
|
||||
mempool_destroy(conf->r10bio_pool);
|
||||
kfree(conf->mirrors);
|
||||
kfree(conf->mirrors_old);
|
||||
kfree(conf->mirrors_new);
|
||||
@@ -3837,9 +3847,8 @@ static struct r10conf *setup_conf(struct mddev *mddev)
|
||||
|
||||
conf->geo = geo;
|
||||
conf->copies = copies;
|
||||
err = mempool_init(&conf->r10bio_pool, NR_RAID_BIOS, r10bio_pool_alloc,
|
||||
rbio_pool_free, conf);
|
||||
if (err)
|
||||
conf->r10bio_pool = create_r10bio_pool(conf->geo.raid_disks);
|
||||
if (!conf->r10bio_pool)
|
||||
goto out;
|
||||
|
||||
err = bioset_init(&conf->bio_split, BIO_POOL_SIZE, 0, 0);
|
||||
@@ -4333,6 +4342,7 @@ static int raid10_start_reshape(struct mddev *mddev)
|
||||
struct md_rdev *rdev;
|
||||
int spares = 0;
|
||||
int ret;
|
||||
mempool_t *new_pool = NULL;
|
||||
|
||||
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
|
||||
return -EBUSY;
|
||||
@@ -4369,6 +4379,11 @@ static int raid10_start_reshape(struct mddev *mddev)
|
||||
return -EINVAL;
|
||||
|
||||
conf->offset_diff = min_offset_diff;
|
||||
if (mddev->delta_disks > 0) {
|
||||
new_pool = create_r10bio_pool(new.raid_disks);
|
||||
if (!new_pool)
|
||||
return -ENOMEM;
|
||||
}
|
||||
spin_lock_irq(&conf->device_lock);
|
||||
if (conf->mirrors_new) {
|
||||
memcpy(conf->mirrors_new, conf->mirrors,
|
||||
@@ -4469,6 +4484,10 @@ out:
|
||||
mddev->raid_disks = conf->geo.raid_disks;
|
||||
mddev->reshape_position = conf->reshape_progress;
|
||||
set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags);
|
||||
if (new_pool) {
|
||||
mempool_destroy(conf->r10bio_pool);
|
||||
conf->r10bio_pool = new_pool;
|
||||
}
|
||||
|
||||
clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
|
||||
clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
|
||||
@@ -4491,6 +4510,7 @@ abort:
|
||||
conf->reshape_safe = MaxSector;
|
||||
mddev->reshape_position = MaxSector;
|
||||
spin_unlock_irq(&conf->device_lock);
|
||||
mempool_destroy(new_pool);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ struct r10conf {
|
||||
*/
|
||||
wait_queue_head_t wait_barrier;
|
||||
|
||||
mempool_t r10bio_pool;
|
||||
mempool_t *r10bio_pool;
|
||||
mempool_t r10buf_pool;
|
||||
struct page *tmppage;
|
||||
struct bio_set bio_split;
|
||||
|
||||
Reference in New Issue
Block a user