Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5cfb22a1 authored by NeilBrown's avatar NeilBrown
Browse files

md/raid5: prefer replacing failed devices over want-replacement devices.



If a RAID5 has both a failed device and a device marked as
'WantReplacement', then we should preferentially replace the failed
device.
However the current code replaces whichever is found first.
So split into 2 loops, check fail failed/missing first, and only check
for WantReplacement if nothing is failed or missing.

Reported-by: default avatarmajianpeng <majianpeng@gmail.com>
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent fc448a18
Loading
Loading
Loading
Loading
+8 −5
Original line number Original line Diff line number Diff line
@@ -5465,10 +5465,9 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev)
	if (rdev->saved_raid_disk >= 0 &&
	if (rdev->saved_raid_disk >= 0 &&
	    rdev->saved_raid_disk >= first &&
	    rdev->saved_raid_disk >= first &&
	    conf->disks[rdev->saved_raid_disk].rdev == NULL)
	    conf->disks[rdev->saved_raid_disk].rdev == NULL)
		disk = rdev->saved_raid_disk;
		first = rdev->saved_raid_disk;
	else

		disk = first;
	for (disk = first; disk <= last; disk++) {
	for ( ; disk <= last ; disk++) {
		p = conf->disks + disk;
		p = conf->disks + disk;
		if (p->rdev == NULL) {
		if (p->rdev == NULL) {
			clear_bit(In_sync, &rdev->flags);
			clear_bit(In_sync, &rdev->flags);
@@ -5477,8 +5476,11 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev)
			if (rdev->saved_raid_disk != disk)
			if (rdev->saved_raid_disk != disk)
				conf->fullsync = 1;
				conf->fullsync = 1;
			rcu_assign_pointer(p->rdev, rdev);
			rcu_assign_pointer(p->rdev, rdev);
			break;
			goto out;
		}
		}
	}
	for (disk = first; disk <= last; disk++) {
		p = conf->disks + disk;
		if (test_bit(WantReplacement, &p->rdev->flags) &&
		if (test_bit(WantReplacement, &p->rdev->flags) &&
		    p->replacement == NULL) {
		    p->replacement == NULL) {
			clear_bit(In_sync, &rdev->flags);
			clear_bit(In_sync, &rdev->flags);
@@ -5490,6 +5492,7 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev)
			break;
			break;
		}
		}
	}
	}
out:
	print_raid5_conf(conf);
	print_raid5_conf(conf);
	return err;
	return err;
}
}