Commit d58aa811 authored by Neil Brown's avatar Neil Brown Committed by Trond Myklebust

[PATCH] MD - Add "degraded" field to md device

Add "degraded" field to md device

This is used to determine if a spare should be added
without relying on the superblock.
parent 8ee83145
...@@ -3354,7 +3354,7 @@ void md_do_recovery(void *data) ...@@ -3354,7 +3354,7 @@ void md_do_recovery(void *data)
wake_up(&resync_wait); wake_up(&resync_wait);
} }
if (sb->active_disks < sb->raid_disks) { if (mddev->degraded) {
mddev->spare = get_spare(mddev); mddev->spare = get_spare(mddev);
if (!mddev->spare) if (!mddev->spare)
printk(KERN_ERR "md%d: no spare disk to reconstruct array! " printk(KERN_ERR "md%d: no spare disk to reconstruct array! "
......
...@@ -581,8 +581,10 @@ static void mark_disk_bad(mddev_t *mddev, int failed) ...@@ -581,8 +581,10 @@ static void mark_disk_bad(mddev_t *mddev, int failed)
mark_disk_faulty(sb->disks+mirror->number); mark_disk_faulty(sb->disks+mirror->number);
mark_disk_nonsync(sb->disks+mirror->number); mark_disk_nonsync(sb->disks+mirror->number);
mark_disk_inactive(sb->disks+mirror->number); mark_disk_inactive(sb->disks+mirror->number);
if (!mirror->write_only) if (!mirror->write_only) {
sb->active_disks--; sb->active_disks--;
mddev->degraded++;
}
sb->working_disks--; sb->working_disks--;
sb->failed_disks++; sb->failed_disks++;
mddev->sb_dirty = 1; mddev->sb_dirty = 1;
...@@ -758,6 +760,7 @@ static int raid1_spare_active(mddev_t *mddev) ...@@ -758,6 +760,7 @@ static int raid1_spare_active(mddev_t *mddev)
*/ */
conf->working_disks++; conf->working_disks++;
mddev->degraded--;
abort: abort:
spin_unlock_irq(&conf->device_lock); spin_unlock_irq(&conf->device_lock);
...@@ -1338,6 +1341,7 @@ static int run(mddev_t *mddev) ...@@ -1338,6 +1341,7 @@ static int run(mddev_t *mddev)
goto out_free_conf; goto out_free_conf;
} }
mddev->degraded = 0;
for (i = 0; i < MD_SB_DISKS; i++) { for (i = 0; i < MD_SB_DISKS; i++) {
descriptor = sb->disks+i; descriptor = sb->disks+i;
...@@ -1355,6 +1359,8 @@ static int run(mddev_t *mddev) ...@@ -1355,6 +1359,8 @@ static int run(mddev_t *mddev)
disk->used_slot = 1; disk->used_slot = 1;
disk->head_position = 0; disk->head_position = 0;
} }
if (!disk->used_slot && disk_idk < conf->raid_disks)
mddev->degraded++;
} }
/* /*
......
...@@ -460,6 +460,7 @@ static int error(mddev_t *mddev, struct block_device *bdev) ...@@ -460,6 +460,7 @@ static int error(mddev_t *mddev, struct block_device *bdev)
sb->working_disks--; sb->working_disks--;
sb->failed_disks++; sb->failed_disks++;
mddev->sb_dirty = 1; mddev->sb_dirty = 1;
mddev->degraded++;
conf->working_disks--; conf->working_disks--;
conf->failed_disks++; conf->failed_disks++;
printk (KERN_ALERT printk (KERN_ALERT
...@@ -1500,7 +1501,7 @@ static int run (mddev_t *mddev) ...@@ -1500,7 +1501,7 @@ static int run (mddev_t *mddev)
/* /*
* 0 for a fully functional array, 1 for a degraded array. * 0 for a fully functional array, 1 for a degraded array.
*/ */
conf->failed_disks = conf->raid_disks - conf->working_disks; mddev->degraded = conf->failed_disks = conf->raid_disks - conf->working_disks;
conf->mddev = mddev; conf->mddev = mddev;
conf->chunk_size = sb->chunk_size; conf->chunk_size = sb->chunk_size;
conf->level = sb->level; conf->level = sb->level;
...@@ -1523,12 +1524,12 @@ static int run (mddev_t *mddev) ...@@ -1523,12 +1524,12 @@ static int run (mddev_t *mddev)
printk(KERN_ERR "raid5: unsupported parity algorithm %d for md%d\n", conf->algorithm, mdidx(mddev)); printk(KERN_ERR "raid5: unsupported parity algorithm %d for md%d\n", conf->algorithm, mdidx(mddev));
goto abort; goto abort;
} }
if (conf->failed_disks > 1) { if (mddev->degraded > 1) {
printk(KERN_ERR "raid5: not enough operational devices for md%d (%d/%d failed)\n", mdidx(mddev), conf->failed_disks, conf->raid_disks); printk(KERN_ERR "raid5: not enough operational devices for md%d (%d/%d failed)\n", mdidx(mddev), conf->failed_disks, conf->raid_disks);
goto abort; goto abort;
} }
if (conf->failed_disks == 1 && if (mddev->degraded == 1 &&
!(sb->state & (1<<MD_SB_CLEAN))) { !(sb->state & (1<<MD_SB_CLEAN))) {
printk(KERN_ERR "raid5: cannot start dirty degraded array for md%d\n", mdidx(mddev)); printk(KERN_ERR "raid5: cannot start dirty degraded array for md%d\n", mdidx(mddev));
goto abort; goto abort;
...@@ -1783,6 +1784,7 @@ static int raid5_spare_active(mddev_t *mddev) ...@@ -1783,6 +1784,7 @@ static int raid5_spare_active(mddev_t *mddev)
* non-operational disk slot in the 'low' area of * non-operational disk slot in the 'low' area of
* the disk array. * the disk array.
*/ */
mddev->degraded--;
conf->failed_disks--; conf->failed_disks--;
conf->working_disks++; conf->working_disks++;
conf->spare = NULL; conf->spare = NULL;
......
...@@ -192,6 +192,10 @@ struct mddev_s ...@@ -192,6 +192,10 @@ struct mddev_s
atomic_t active; atomic_t active;
mdp_disk_t *spare; mdp_disk_t *spare;
int degraded; /* whether md should consider
* adding a spare
*/
atomic_t recovery_active; /* blocks scheduled, but not written */ atomic_t recovery_active; /* blocks scheduled, but not written */
wait_queue_head_t recovery_wait; wait_queue_head_t recovery_wait;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment