summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Brassow <jbrassow@redhat.com>2012-05-22 13:55:30 +1000
committerNeilBrown <neilb@suse.de>2012-05-22 13:55:30 +1000
commit81f382f9e0b25ef56b1c0283c900b86b91a5e4c7 (patch)
tree992f754485b3f78503b7e4f68835da4438786c09
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>
-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 ea2d90c78f7..f1797c4f09c 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)
static void super_sync(struct mddev *mddev, struct md_rdev *rdev)
{
- struct md_rdev *r;
+ int i;
uint64_t failed_devices;
struct dm_raid_superblock *sb;
+ struct raid_set *rs = container_of(mddev, struct raid_set, md);
sb = page_address(rdev->sb_page);
failed_devices = le64_to_cpu(sb->failed_devices);
- rdev_for_each(r, mddev)
- if ((r->raid_disk >= 0) && test_bit(Faulty, &r->flags))
- failed_devices |= (1ULL << r->raid_disk);
+ for (i = 0; i < mddev->raid_disks; i++)
+ if (!rs->dev[i].data_dev ||
+ test_bit(Faulty, &(rs->dev[i].rdev.flags)))
+ failed_devices |= (1ULL << i);
memset(sb, 0, sizeof(*sb));
@@ -1249,6 +1251,7 @@ static void raid_resume(struct dm_target *ti)
{
struct raid_set *rs = ti->private;
+ set_bit(MD_CHANGE_DEVS, &rs->md.flags);
if (!rs->bitmap_loaded) {
bitmap_load(&rs->md);
rs->bitmap_loaded = 1;