diff options
author | Goldwyn Rodrigues <rgoldwyn@suse.com> | 2015-08-21 10:33:39 -0500 |
---|---|---|
committer | Goldwyn Rodrigues <rgoldwyn@suse.com> | 2015-10-12 01:34:48 -0500 |
commit | 70bcecdb1534a7dcd82503b705c27a048d568c9d (patch) | |
tree | 62139e038abf1eabe175920911215825eaeba83b /drivers/md/raid1.c | |
parent | 2910ff17d154baa5eb50e362a91104e831eb2bb6 (diff) | |
download | linux-70bcecdb1534a7dcd82503b705c27a048d568c9d.tar.gz linux-70bcecdb1534a7dcd82503b705c27a048d568c9d.tar.bz2 linux-70bcecdb1534a7dcd82503b705c27a048d568c9d.zip |
md-cluster: Improve md_reload_sb to be less error prone
md_reload_sb is too simplistic and it explicitly needs to determine
the changes made by the writing node. However, there are multiple areas
where a simple reload could fail.
Instead, read the superblock of one of the "good" rdevs and update
the necessary information:
- read the superblock into a newly allocated page, by temporarily
swapping out rdev->sb_page and calling ->load_super.
- if that fails return
- if it succeeds, call check_sb_changes
1. iterates over list of active devices and checks the matching
dev_roles[] value.
If that is 'faulty', the device must be marked as faulty
- call md_error to mark the device as faulty. Make sure
not to set CHANGE_DEVS and wakeup mddev->thread or else
it would initiate a resync process, which is the responsibility
of the "primary" node.
- clear the Blocked bit
- Call remove_and_add_spares() to hot remove the device.
If the device is 'spare':
- call remove_and_add_spares() to get the number of spares
added in this operation.
- Reduce mddev->degraded to mark the array as not degraded.
2. reset recovery_cp
- read the rest of the rdevs to update recovery_offset. If recovery_offset
is equal to MaxSector, call spare_active() to set it In_sync
This required that recovery_offset be initialized to MaxSector, as
opposed to zero so as to communicate the end of sync for a rdev.
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
Diffstat (limited to 'drivers/md/raid1.c')
-rw-r--r-- | drivers/md/raid1.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 1dd13bb52940..b54fefc85b66 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1592,6 +1592,15 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev) if (rdev->raid_disk >= 0) first = last = rdev->raid_disk; + /* + * find the disk ... but prefer rdev->saved_raid_disk + * if possible. + */ + if (rdev->saved_raid_disk >= 0 && + rdev->saved_raid_disk >= first && + conf->mirrors[rdev->saved_raid_disk].rdev == NULL) + first = last = rdev->saved_raid_disk; + for (mirror = first; mirror <= last; mirror++) { p = conf->mirrors+mirror; if (!p->rdev) { |