md/raid10: set dev_sectors properly when resizing devices in array.
[pandora-kernel.git] / drivers / md / raid0.c
index 6f31f55..de63a1f 100644 (file)
@@ -407,6 +407,8 @@ static sector_t raid0_size(struct mddev *mddev, sector_t sectors, int raid_disks
        return array_sectors;
 }
 
+static int raid0_stop(struct mddev *mddev);
+
 static int raid0_run(struct mddev *mddev)
 {
        struct r0conf *conf;
@@ -454,7 +456,12 @@ static int raid0_run(struct mddev *mddev)
 
        blk_queue_merge_bvec(mddev->queue, raid0_mergeable_bvec);
        dump_zones(mddev);
-       return md_integrity_register(mddev);
+
+       ret = md_integrity_register(mddev);
+       if (ret)
+               raid0_stop(mddev);
+
+       return ret;
 }
 
 static int raid0_stop(struct mddev *mddev)
@@ -625,6 +632,7 @@ static void *raid0_takeover_raid10(struct mddev *mddev)
 static void *raid0_takeover_raid1(struct mddev *mddev)
 {
        struct r0conf *priv_conf;
+       int chunksect;
 
        /* Check layout:
         *  - (N - 1) mirror drives must be already faulty
@@ -635,10 +643,25 @@ static void *raid0_takeover_raid1(struct mddev *mddev)
                return ERR_PTR(-EINVAL);
        }
 
+       /*
+        * a raid1 doesn't have the notion of chunk size, so
+        * figure out the largest suitable size we can use.
+        */
+       chunksect = 64 * 2; /* 64K by default */
+
+       /* The array must be an exact multiple of chunksize */
+       while (chunksect && (mddev->array_sectors & (chunksect - 1)))
+               chunksect >>= 1;
+
+       if ((chunksect << 9) < PAGE_SIZE)
+               /* array size does not allow a suitable chunk size */
+               return ERR_PTR(-EINVAL);
+
        /* Set new parameters */
        mddev->new_level = 0;
        mddev->new_layout = 0;
-       mddev->new_chunk_sectors = 128; /* by default set chunk size to 64k */
+       mddev->new_chunk_sectors = chunksect;
+       mddev->chunk_sectors = chunksect;
        mddev->delta_disks = 1 - mddev->raid_disks;
        mddev->raid_disks = 1;
        /* make sure it will be not marked as dirty */