summaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorJonathan E Brassow <jbrassow@redhat.com>2012-03-07 19:09:47 +0000
committerAlasdair G Kergon <agk@redhat.com>2012-03-07 19:09:47 +0000
commit3aa3b2b2b1edb813dc5342d0108befc39541542d (patch)
tree151000a59d089231fcefbf44539c89ee56436c84 /drivers/md
parentaf63bcb817cf708f53bcae6edc2e3fb7dd7d8051 (diff)
downloadlinux-3aa3b2b2b1edb813dc5342d0108befc39541542d.tar.gz
linux-3aa3b2b2b1edb813dc5342d0108befc39541542d.tar.bz2
linux-3aa3b2b2b1edb813dc5342d0108befc39541542d.zip
dm raid: set MD_CHANGE_DEVS when rebuilding
The 'rebuild' parameter is used to rebuild individual devices in an array (e.g. resynchronize a RAID1 device or recalculate a parity device in higher RAID). The MD_CHANGE_DEVS flag must be set when this parameter is given in order to write out the superblocks and make the change take immediate effect. The code that handles new devices in super_load already sets MD_CHANGE_DEVS and 'FirstUse'. (The 'FirstUse' flag was being set as a special case for rebuilds in super_init_validation.) Add a condition for rebuilds in super_load to take care of both flags without the special case in 'super_init_validation'. Signed-off-by: Jonathan Brassow <jbrassow@redhat.com> Cc: stable@kernel.org Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-raid.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 86cb7e5d83d5..f53bb389c18f 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -668,7 +668,14 @@ static int super_load(struct md_rdev *rdev, struct md_rdev *refdev)
return ret;
sb = page_address(rdev->sb_page);
- if (sb->magic != cpu_to_le32(DM_RAID_MAGIC)) {
+
+ /*
+ * Two cases that we want to write new superblocks and rebuild:
+ * 1) New device (no matching magic number)
+ * 2) Device specified for rebuild (!In_sync w/ offset == 0)
+ */
+ if ((sb->magic != cpu_to_le32(DM_RAID_MAGIC)) ||
+ (!test_bit(In_sync, &rdev->flags) && !rdev->recovery_offset)) {
super_sync(rdev->mddev, rdev);
set_bit(FirstUse, &rdev->flags);
@@ -745,11 +752,8 @@ static int super_init_validation(struct mddev *mddev, struct md_rdev *rdev)
*/
rdev_for_each(r, t, mddev) {
if (!test_bit(In_sync, &r->flags)) {
- if (!test_bit(FirstUse, &r->flags))
- DMERR("Superblock area of "
- "rebuild device %d should have been "
- "cleared.", r->raid_disk);
- set_bit(FirstUse, &r->flags);
+ DMINFO("Device %d specified for rebuild: "
+ "Clearing superblock", r->raid_disk);
rebuilds++;
} else if (test_bit(FirstUse, &r->flags))
new_devs++;