md/raid10: wire llbitmap reshape lifecycle

Prepare llbitmap before RAID10 starts growing, checkpoint the bitmap
before advancing reshape_position, finish the llbitmap geometry update
when reshape completes, and export the old and new tracked sizes.

Tested-by: Mykola Marzhan <mykola@meshstor.io>
Link: https://patch.msgid.link/20260802195038.164272-25-yukuai@kernel.org
Signed-off-by: Yu Kuai <yukuai@fygo.io>
This commit is contained in:
Yu Kuai 2026-08-03 03:50:33 +08:00
parent ecb66a97af
commit b109d437db

View File

@ -4356,6 +4356,12 @@ static int raid10_start_reshape(struct mddev *mddev)
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
return -EBUSY;
if (md_bitmap_enabled(mddev, false) &&
mddev->bitmap_ops->reshape_can_start) {
ret = mddev->bitmap_ops->reshape_can_start(mddev);
if (ret)
return ret;
}
if (setup_geo(&new, mddev, geo_start) != conf->copies)
return -EINVAL;
@ -4679,6 +4685,13 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
time_after(jiffies, conf->reshape_checkpoint + 10*HZ)) {
/* Need to update reshape_position in metadata */
wait_barrier(conf);
if (md_bitmap_enabled(mddev, false) &&
mddev->bitmap_ops->reshape_mark &&
conf->reshape_safe != conf->reshape_progress) {
mddev->bitmap_ops->reshape_mark(mddev, conf->reshape_safe,
conf->reshape_progress);
mddev->bitmap_ops->unplug(mddev, true);
}
mddev->reshape_position = conf->reshape_progress;
if (mddev->reshape_backwards)
mddev->curr_resync_completed = raid10_size(mddev, 0, 0)
@ -4877,9 +4890,19 @@ static void reshape_request_write(struct mddev *mddev, struct r10bio *r10_bio)
static void end_reshape(struct r10conf *conf)
{
struct mddev *mddev = conf->mddev;
if (test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery))
return;
if (md_bitmap_enabled(mddev, false) &&
mddev->bitmap_ops->reshape_mark &&
conf->reshape_safe != conf->reshape_progress) {
mddev->bitmap_ops->reshape_mark(mddev, conf->reshape_safe,
conf->reshape_progress);
mddev->bitmap_ops->unplug(mddev, true);
}
spin_lock_irq(&conf->device_lock);
conf->prev = conf->geo;
md_finish_reshape(conf->mddev);
@ -5011,10 +5034,15 @@ static void end_reshape_request(struct r10bio *r10_bio)
static void raid10_finish_reshape(struct mddev *mddev)
{
struct r10conf *conf = mddev->private;
bool llbitmap = mddev->bitmap_id == ID_LLBITMAP &&
md_bitmap_enabled(mddev, false);
if (test_bit(MD_RECOVERY_INTR, &mddev->recovery))
return;
if (llbitmap && mddev->bitmap_ops->reshape_finish)
mddev->bitmap_ops->reshape_finish(mddev);
if (mddev->delta_disks > 0) {
if (mddev->resync_offset > mddev->resync_max_sectors) {
mddev->resync_offset = mddev->resync_max_sectors;
@ -5041,6 +5069,15 @@ static void raid10_finish_reshape(struct mddev *mddev)
mddev->reshape_backwards = 0;
}
static sector_t raid10_bitmap_sync_size(struct mddev *mddev, bool previous)
{
struct r10conf *conf = mddev->private;
if (previous)
return raid10_size(mddev, 0, 0);
return raid10_size(mddev, 0, conf->geo.raid_disks);
}
static struct md_personality raid10_personality =
{
.head = {
@ -5067,6 +5104,8 @@ static struct md_personality raid10_personality =
.start_reshape = raid10_start_reshape,
.finish_reshape = raid10_finish_reshape,
.update_reshape_pos = raid10_update_reshape_pos,
.bitmap_sync_size = raid10_bitmap_sync_size,
.bitmap_array_sectors = raid10_bitmap_sync_size,
};
static int __init raid10_init(void)