DM RAID: Record and handle missing devices
authorJonathan Brassow <jbrassow@redhat.com>
Tue, 22 May 2012 03:55:30 +0000 (13:55 +1000)
committerNeilBrown <neilb@suse.de>
Tue, 22 May 2012 03:55:30 +0000 (13:55 +1000)
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>
drivers/md/dm-raid.c

index ea2d90c78f788adf906fbd0f7b9aef7b7f4ec36e..f1797c4f09c40dbd61348029f4bc12c105295c8c 100644 (file)
@@ -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;
This page took 0.025814 seconds and 5 git commands to generate.