diff options
author | Li Nan <linan122@huawei.com> | 2023-06-27 09:43:32 +0800 |
---|---|---|
committer | Song Liu <song@kernel.org> | 2023-07-27 00:13:30 -0700 |
commit | ffb1e7a03f966065323b18c96da23a2118a19529 (patch) | |
tree | 2d01975892cbe811b803af0ebbc5880418cd261b /drivers/md | |
parent | dd9a68601409d905810a936a7c4e1241b604013f (diff) | |
download | lwn-ffb1e7a03f966065323b18c96da23a2118a19529.tar.gz lwn-ffb1e7a03f966065323b18c96da23a2118a19529.zip |
md/raid1: prioritize adding disk to 'removed' mirror
New disk should be added to "removed" position first instead of to be a
replacement. Commit 6090368abcb4 ("md/raid10: prioritize adding disk to
'removed' mirror") has fixed this issue for raid10. Fix it for raid1 now.
Signed-off-by: Li Nan <linan122@huawei.com>
Reviewed-by: Yu Kuai <yukuai3@huawei.com>
Link: https://lore.kernel.org/r/20230627014332.3810102-1-linan666@huaweicloud.com
Signed-off-by: Song Liu <song@kernel.org>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/raid1.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 06fa1580501f..f834d99a36f6 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1764,7 +1764,7 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev) { struct r1conf *conf = mddev->private; int err = -EEXIST; - int mirror = 0; + int mirror = 0, repl_slot = -1; struct raid1_info *p; int first = 0; int last = conf->raid_disks - 1; @@ -1807,17 +1807,21 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev) break; } if (test_bit(WantReplacement, &p->rdev->flags) && - p[conf->raid_disks].rdev == NULL) { - /* Add this device as a replacement */ - clear_bit(In_sync, &rdev->flags); - set_bit(Replacement, &rdev->flags); - rdev->raid_disk = mirror; - err = 0; - conf->fullsync = 1; - rcu_assign_pointer(p[conf->raid_disks].rdev, rdev); - break; - } + p[conf->raid_disks].rdev == NULL && repl_slot < 0) + repl_slot = mirror; } + + if (err && repl_slot >= 0) { + /* Add this device as a replacement */ + p = conf->mirrors + repl_slot; + clear_bit(In_sync, &rdev->flags); + set_bit(Replacement, &rdev->flags); + rdev->raid_disk = repl_slot; + err = 0; + conf->fullsync = 1; + rcu_assign_pointer(p[conf->raid_disks].rdev, rdev); + } + print_conf(conf); return err; } |