]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/md/md.c
md: Allow metadata_version to be updated for externally managed metadata.
[karo-tx-linux.git] / drivers / md / md.c
index deeac4b44173d959b2fca6ca7f9abf57aa419f55..13dd7b276150d3e695fccffe82279603f60b8313 100644 (file)
@@ -1464,10 +1464,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
        if ((err = kobject_add(&rdev->kobj, &mddev->kobj, "dev-%s", b)))
                goto fail;
 
-       if (rdev->bdev->bd_part)
-               ko = &rdev->bdev->bd_part->dev.kobj;
-       else
-               ko = &rdev->bdev->bd_disk->dev.kobj;
+       ko = &part_to_dev(rdev->bdev->bd_part)->kobj;
        if ((err = sysfs_create_link(&rdev->kobj, ko, "block"))) {
                kobject_del(&rdev->kobj);
                goto fail;
@@ -2109,8 +2106,6 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
 
        if (strict_strtoull(buf, 10, &size) < 0)
                return -EINVAL;
-       if (size < my_mddev->size)
-               return -EINVAL;
        if (my_mddev->pers && rdev->raid_disk >= 0) {
                if (my_mddev->persistent) {
                        size = super_types[my_mddev->major_version].
@@ -2121,9 +2116,9 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                        size = (rdev->bdev->bd_inode->i_size >> 10);
                        size -= rdev->data_offset/2;
                }
-               if (size < my_mddev->size)
-                       return -EINVAL; /* component must fit device */
        }
+       if (size < my_mddev->size)
+               return -EINVAL; /* component must fit device */
 
        rdev->size = size;
        if (size > oldsize && my_mddev->external) {
@@ -2948,7 +2943,13 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len)
 {
        int major, minor;
        char *e;
-       if (!list_empty(&mddev->disks))
+       /* Changing the details of 'external' metadata is
+        * always permitted.  Otherwise there must be
+        * no devices attached to the array.
+        */
+       if (mddev->external && strncmp(buf, "external:", 9) == 0)
+               ;
+       else if (!list_empty(&mddev->disks))
                return -EBUSY;
 
        if (cmd_match(buf, "none")) {
@@ -3470,8 +3471,8 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
        disk->queue = mddev->queue;
        add_disk(disk);
        mddev->gendisk = disk;
-       error = kobject_init_and_add(&mddev->kobj, &md_ktype, &disk->dev.kobj,
-                                    "%s", "md");
+       error = kobject_init_and_add(&mddev->kobj, &md_ktype,
+                                    &disk_to_dev(disk)->kobj, "%s", "md");
        mutex_unlock(&disks_mutex);
        if (error)
                printk(KERN_WARNING "md: cannot register %s/md - name in use\n",
@@ -3761,7 +3762,7 @@ static int do_md_run(mddev_t * mddev)
        sysfs_notify(&mddev->kobj, NULL, "array_state");
        sysfs_notify(&mddev->kobj, NULL, "sync_action");
        sysfs_notify(&mddev->kobj, NULL, "degraded");
-       kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE);
+       kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE);
        return 0;
 }
 
@@ -5549,8 +5550,8 @@ static int is_mddev_idle(mddev_t *mddev)
        rcu_read_lock();
        rdev_for_each_rcu(rdev, mddev) {
                struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
-               curr_events = disk_stat_read(disk, sectors[0]) + 
-                               disk_stat_read(disk, sectors[1]) - 
+               curr_events = part_stat_read(&disk->part0, sectors[0]) +
+                               part_stat_read(&disk->part0, sectors[1]) -
                                atomic_read(&disk->sync_io);
                /* sync IO will cause sync_io to increase before the disk_stats
                 * as sync_io is counted when a request starts, and