]> err.no Git - linux-2.6/blobdiff - drivers/md/md.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux-2.6] / drivers / md / md.c
index 2901d0c0ee9ec4f166e8a6b5c8a080449e571c20..1c54f3c1cca74fca038b5b4452c9a0504e481e57 100644 (file)
@@ -1298,8 +1298,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
        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);
        
@@ -1365,10 +1366,14 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
        }
        /* 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;
        }
 
@@ -2142,6 +2147,9 @@ static void analyze_sbs(mddev_t * mddev)
                        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);
                }
        }
 
@@ -3104,7 +3112,6 @@ static int do_md_run(mddev_t * mddev)
        struct gendisk *disk;
        struct mdk_personality *pers;
        char b[BDEVNAME_SIZE];
-       struct block_device *bdev;
 
        if (list_empty(&mddev->disks))
                /* cannot run an array with no devices.. */
@@ -3332,13 +3339,7 @@ static int do_md_run(mddev_t * mddev)
        md_wakeup_thread(mddev->thread);
        md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
 
-       bdev = bdget_disk(mddev->gendisk, 0);
-       if (bdev) {
-               bd_set_size(bdev, mddev->array_size << 1);
-               blkdev_ioctl(bdev->bd_inode, NULL, BLKRRPART, 0);
-               bdput(bdev);
-       }
-
+       mddev->changed = 1;
        md_new_event(mddev);
        kobject_uevent(&mddev->gendisk->kobj, KOBJ_CHANGE);
        return 0;
@@ -3460,6 +3461,7 @@ static int do_md_stop(mddev_t * mddev, int mode)
                        mddev->pers = NULL;
 
                        set_capacity(disk, 0);
+                       mddev->changed = 1;
 
                        if (mddev->ro)
                                mddev->ro = 0;
@@ -4599,6 +4601,20 @@ static int md_release(struct inode *inode, struct file * file)
        return 0;
 }
 
+static int md_media_changed(struct gendisk *disk)
+{
+       mddev_t *mddev = disk->private_data;
+
+       return mddev->changed;
+}
+
+static int md_revalidate(struct gendisk *disk)
+{
+       mddev_t *mddev = disk->private_data;
+
+       mddev->changed = 0;
+       return 0;
+}
 static struct block_device_operations md_fops =
 {
        .owner          = THIS_MODULE,
@@ -4606,6 +4622,8 @@ static struct block_device_operations md_fops =
        .release        = md_release,
        .ioctl          = md_ioctl,
        .getgeo         = md_getgeo,
+       .media_changed  = md_media_changed,
+       .revalidate_disk= md_revalidate,
 };
 
 static int md_thread(void * arg)
@@ -5093,7 +5111,7 @@ static int is_mddev_idle(mddev_t *mddev)
                 *
                 * Note: the following is an unsigned comparison.
                 */
-               if ((curr_events - rdev->last_events + 4096) > 8192) {
+               if ((long)curr_events - (long)rdev->last_events > 4096) {
                        rdev->last_events = curr_events;
                        idle = 0;
                }