aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJonathan Brassow <jbrassow@redhat.com>2012-05-21 23:55:30 -0400
committerNeilBrown <neilb@suse.de>2012-05-21 23:55:30 -0400
commit81f382f9e0b25ef56b1c0283c900b86b91a5e4c7 (patch)
tree992f754485b3f78503b7e4f68835da4438786c09 /drivers
parent47525e59e40ffb8cbc944c0055e9c4902cd3ee99 (diff)
DM RAID: Record and handle missing devices
Missing dm-raid devices should be recorded in the superblock When specifying the devices that compose a DM RAID array, it is possible to denote failed or missing devices with '-'s. When this occurs, we must record this in the superblock. We do this by checking if the array position's data device is missing and then forcing MD to record the superblock by setting 'MD_CHANGE_DEVS' in 'raid_resume'. If we do not cause the superblock to be rewritten by the resume function, it is possible for a stale superblock to be written by an out-going in-active table (during 'raid_dtr'). Signed-off-by: Jonathan Brassow <jbrassow@redhat.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/dm-raid.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index ea2d90c78f78..f1797c4f09c4 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -614,16 +614,18 @@ static int read_disk_sb(struct md_rdev *rdev, int size)
614 614
615static void super_sync(struct mddev *mddev, struct md_rdev *rdev) 615static void super_sync(struct mddev *mddev, struct md_rdev *rdev)
616{ 616{
617 struct md_rdev *r; 617 int i;
618 uint64_t failed_devices; 618 uint64_t failed_devices;
619 struct dm_raid_superblock *sb; 619 struct dm_raid_superblock *sb;
620 struct raid_set *rs = container_of(mddev, struct raid_set, md);
620 621
621 sb = page_address(rdev->sb_page); 622 sb = page_address(rdev->sb_page);
622 failed_devices = le64_to_cpu(sb->failed_devices); 623 failed_devices = le64_to_cpu(sb->failed_devices);
623 624
624 rdev_for_each(r, mddev) 625 for (i = 0; i < mddev->raid_disks; i++)
625 if ((r->raid_disk >= 0) && test_bit(Faulty, &r->flags)) 626 if (!rs->dev[i].data_dev ||
626 failed_devices |= (1ULL << r->raid_disk); 627 test_bit(Faulty, &(rs->dev[i].rdev.flags)))
628 failed_devices |= (1ULL << i);
627 629
628 memset(sb, 0, sizeof(*sb)); 630 memset(sb, 0, sizeof(*sb));
629 631
@@ -1249,6 +1251,7 @@ static void raid_resume(struct dm_target *ti)
1249{ 1251{
1250 struct raid_set *rs = ti->private; 1252 struct raid_set *rs = ti->private;
1251 1253
1254 set_bit(MD_CHANGE_DEVS, &rs->md.flags);
1252 if (!rs->bitmap_loaded) { 1255 if (!rs->bitmap_loaded) {
1253 bitmap_load(&rs->md); 1256 bitmap_load(&rs->md);
1254 rs->bitmap_loaded = 1; 1257 rs->bitmap_loaded = 1;