drivers/md/raid10.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
From: Yu Kuai <yukuai@fygo.io>
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.
Signed-off-by: Yu Kuai <yukuai@fygo.io>
---
drivers/md/raid10.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index c69ef76c89e1..40000b867136 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -4379,10 +4379,16 @@ static int raid10_start_reshape(struct mddev *mddev)
int spares = 0;
int ret;
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;
before_length = ((1 << conf->prev.chunk_shift) *
@@ -4692,10 +4698,17 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
if (need_flush ||
time_after(jiffies, conf->reshape_checkpoint + 10*HZ)) {
/* Need to update reshape_position in metadata */
wait_barrier(conf, false);
+ 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)
- conf->reshape_progress;
else
@@ -4890,13 +4903,23 @@ static void reshape_request_write(struct mddev *mddev, struct r10bio *r10_bio)
end_reshape_request(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);
smp_wmb();
conf->reshape_progress = MaxSector;
@@ -5024,14 +5047,19 @@ 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;
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
}
@@ -5054,10 +5082,19 @@ static void raid10_finish_reshape(struct mddev *mddev)
mddev->reshape_position = MaxSector;
mddev->delta_disks = 0;
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 = {
.type = MD_PERSONALITY,
.id = ID_RAID10,
@@ -5080,10 +5117,12 @@ static struct md_personality raid10_personality =
.takeover = raid10_takeover,
.check_reshape = raid10_check_reshape,
.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)
{
return register_md_submodule(&raid10_personality.head);
--
2.51.0
© 2016 - 2026 Red Hat, Inc.