]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] MD - Add "degraded" field to md device
authorNeil Brown <neilb@cse.unsw.edu.au>
Fri, 19 Jul 2002 02:09:48 +0000 (19:09 -0700)
committerTrond Myklebust <trond.myklebust@fys.uio.no>
Fri, 19 Jul 2002 02:09:48 +0000 (19:09 -0700)
Add "degraded" field to md device

This is used to determine if a spare should be added
without relying on the superblock.

drivers/md/md.c
drivers/md/raid1.c
drivers/md/raid5.c
include/linux/raid/md_k.h

index 64dd07bf36a061470ca39fb27b32ce3d0ee8c62d..98544cd02a8b58354e30da6ceb265c800ce443b0 100644 (file)
@@ -3354,7 +3354,7 @@ void md_do_recovery(void *data)
                        wake_up(&resync_wait);
                }
 
-               if (sb->active_disks < sb->raid_disks) {
+               if (mddev->degraded) {
                        mddev->spare = get_spare(mddev);
                        if (!mddev->spare)
                                printk(KERN_ERR "md%d: no spare disk to reconstruct array! "
index 971a30c9ed0bf914e1b4257d120bc63f3f8b3e4f..e684d856efd2e92770c1a7584c08d7521ef7bc66 100644 (file)
@@ -581,8 +581,10 @@ static void mark_disk_bad(mddev_t *mddev, int failed)
        mark_disk_faulty(sb->disks+mirror->number);
        mark_disk_nonsync(sb->disks+mirror->number);
        mark_disk_inactive(sb->disks+mirror->number);
-       if (!mirror->write_only)
+       if (!mirror->write_only) {
                sb->active_disks--;
+               mddev->degraded++;
+       }
        sb->working_disks--;
        sb->failed_disks++;
        mddev->sb_dirty = 1;
@@ -758,6 +760,7 @@ static int raid1_spare_active(mddev_t *mddev)
         */
 
        conf->working_disks++;
+       mddev->degraded--;
 abort:
        spin_unlock_irq(&conf->device_lock);
 
@@ -1338,6 +1341,7 @@ static int run(mddev_t *mddev)
                goto out_free_conf;
        }
 
+       mddev->degraded = 0;
        for (i = 0; i < MD_SB_DISKS; i++) {
 
                descriptor = sb->disks+i;
@@ -1355,6 +1359,8 @@ static int run(mddev_t *mddev)
                        disk->used_slot = 1;
                        disk->head_position = 0;
                }
+               if (!disk->used_slot && disk_idk < conf->raid_disks)
+                       mddev->degraded++;
        }
 
        /*
index 09e4735e3a9f77bbaf3a161f01ff09c886935d6c..029aa430bfceb8fb906d5bd8cd5c577932e24b64 100644 (file)
@@ -460,6 +460,7 @@ static int error(mddev_t *mddev, struct block_device *bdev)
                        sb->working_disks--;
                        sb->failed_disks++;
                        mddev->sb_dirty = 1;
+                       mddev->degraded++;
                        conf->working_disks--;
                        conf->failed_disks++;
                        printk (KERN_ALERT
@@ -1500,7 +1501,7 @@ static int run (mddev_t *mddev)
        /*
         * 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->chunk_size = sb->chunk_size;
        conf->level = sb->level;
@@ -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));
                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);
                goto abort;
        }
 
-       if (conf->failed_disks == 1 &&
+       if (mddev->degraded == 1 &&
            !(sb->state & (1<<MD_SB_CLEAN))) {
                printk(KERN_ERR "raid5: cannot start dirty degraded array for md%d\n", mdidx(mddev));
                goto abort;
@@ -1783,6 +1784,7 @@ static int raid5_spare_active(mddev_t *mddev)
         * non-operational disk slot in the 'low' area of
         * the disk array.
         */
+       mddev->degraded--;
        conf->failed_disks--;
        conf->working_disks++;
        conf->spare = NULL;
index f3c8dcc7d8a8f9e19623d328bc5f88277429d5fa..369a2e56d22cfc1d152c06c47bfd73155d8ac583 100644 (file)
@@ -192,6 +192,10 @@ struct mddev_s
        atomic_t                        active;
        mdp_disk_t                      *spare;
 
+       int                             degraded;       /* whether md should consider
+                                                        * adding a spare
+                                                        */
+
        atomic_t                        recovery_active; /* blocks scheduled, but not written */
        wait_queue_head_t               recovery_wait;