]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
md:Add support for Raid0->Raid5 takeover
authorTrela Maciej <Maciej.Trela@intel.com>
Mon, 8 Mar 2010 05:02:42 +0000 (16:02 +1100)
committerNeilBrown <neilb@suse.de>
Tue, 18 May 2010 05:27:47 +0000 (15:27 +1000)
Signed-off-by: Maciej Trela <maciej.trela@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
drivers/md/md.c
drivers/md/raid5.c

index 2a64cba9ea72f534f202fee7c059ba59d5f9dea5..22c630b7ba6ca48f94aa5a24bf2c345353345c52 100644 (file)
@@ -3017,6 +3017,20 @@ level_store(mddev_t *mddev, const char *buf, size_t len)
                        mddev->to_remove = &md_redundancy_group;
        }
 
+       if (mddev->pers->sync_request == NULL &&
+           mddev->external) {
+               /* We are converting from a no-redundancy array
+                * to a redundancy array and metadata is managed
+                * externally so we need to be sure that writes
+                * won't block due to a need to transition
+                *      clean->dirty
+                * until external management is started.
+                */
+               mddev->in_sync = 0;
+               mddev->safemode_delay = 0;
+               mddev->safemode = 0;
+       }
+
        module_put(mddev->pers->owner);
        /* Invalidate devices that are now superfluous */
        list_for_each_entry(rdev, &mddev->disks, same_set)
index 10af3715b1fca00606fbd93fe57c7382baebb9ea..bb28fd6b44feea0ba44405df2970b16cd460b7e2 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/cpu.h>
 #include "md.h"
 #include "raid5.h"
+#include "raid0.h"
 #include "bitmap.h"
 
 /*
@@ -5619,6 +5620,21 @@ static void raid5_quiesce(mddev_t *mddev, int state)
 }
 
 
+static void *raid5_takeover_raid0(mddev_t *mddev)
+{
+
+       mddev->new_level = 5;
+       mddev->new_layout = ALGORITHM_PARITY_N;
+       mddev->new_chunk_sectors = mddev->chunk_sectors;
+       mddev->raid_disks += 1;
+       mddev->delta_disks = 1;
+       /* make sure it will be not marked as dirty */
+       mddev->recovery_cp = MaxSector;
+
+       return setup_conf(mddev);
+}
+
+
 static void *raid5_takeover_raid1(mddev_t *mddev)
 {
        int chunksect;
@@ -5748,6 +5764,16 @@ static void *raid5_takeover(mddev_t *mddev)
         *  raid4 - trivial - just use a raid4 layout.
         *  raid6 - Providing it is a *_6 layout
         */
+       if (mddev->level == 0) {
+               /* for raid0 takeover only one zone is supported */
+               struct raid0_private_data *raid0_priv
+                       = mddev->private;
+               if (raid0_priv->nr_strip_zones > 1) {
+                       printk(KERN_ERR "md: cannot takeover raid 0 with more than one zone.\n");
+                       return ERR_PTR(-EINVAL);
+               }
+               return raid5_takeover_raid0(mddev);
+       }
 
        if (mddev->level == 1)
                return raid5_takeover_raid1(mddev);