if (!conf)
                return NULL;
 
-       mddev->private = conf;
-
        cnt = 0;
        conf->array_size = 0;
 
         * First calculate the device offsets.
         */
        conf->disks[0].offset = 0;
-       for (i=1; i<mddev->raid_disks; i++)
+       for (i = 1; i < raid_disks; i++)
                conf->disks[i].offset =
                        conf->disks[i-1].offset +
                        conf->disks[i-1].size;
             curr_offset < conf->array_size;
             curr_offset += conf->hash_spacing) {
 
-               while (i < mddev->raid_disks-1 &&
+               while (i < raid_disks-1 &&
                       curr_offset >= conf->disks[i+1].offset)
                        i++;
 
         */
        linear_conf_t *newconf;
 
-       if (rdev->raid_disk != mddev->raid_disks)
+       if (rdev->saved_raid_disk != mddev->raid_disks)
                return -EINVAL;
 
+       rdev->raid_disk = rdev->saved_raid_disk;
+
        newconf = linear_conf(mddev,mddev->raid_disks+1);
 
        if (!newconf)
 
        ITERATE_RDEV(mddev,rdev2,tmp)
                if (rdev2->desc_nr+1 > max_dev)
                        max_dev = rdev2->desc_nr+1;
-       
-       sb->max_dev = cpu_to_le32(max_dev);
+
+       if (max_dev > le32_to_cpu(sb->max_dev))
+               sb->max_dev = cpu_to_le32(max_dev);
        for (i=0; i<max_dev;i++)
                sb->dev_roles[i] = cpu_to_le16(0xfffe);
        
        }
        /* make sure rdev->size exceeds mddev->size */
        if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
-               if (mddev->pers)
-                       /* Cannot change size, so fail */
-                       return -ENOSPC;
-               else
+               if (mddev->pers) {
+                       /* Cannot change size, so fail
+                        * If mddev->level <= 0, then we don't care
+                        * about aligning sizes (e.g. linear)
+                        */
+                       if (mddev->level > 0)
+                               return -ENOSPC;
+               } else
                        mddev->size = rdev->size;
        }
 
                        rdev->desc_nr = i++;
                        rdev->raid_disk = rdev->desc_nr;
                        set_bit(In_sync, &rdev->flags);
+               } else if (rdev->raid_disk >= mddev->raid_disks) {
+                       rdev->raid_disk = -1;
+                       clear_bit(In_sync, &rdev->flags);
                }
        }