block: switch partition lookup to use struct block_device
[linux-2.6-microblaze.git] / drivers / md / md.c
index 98bac4f..0065736 100644 (file)
@@ -464,7 +464,7 @@ struct md_io {
        bio_end_io_t *orig_bi_end_io;
        void *orig_bi_private;
        unsigned long start_time;
-       struct hd_struct *part;
+       struct block_device *part;
 };
 
 static void md_end_io(struct bio *bio)
@@ -2414,7 +2414,6 @@ EXPORT_SYMBOL(md_integrity_add_rdev);
 static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev)
 {
        char b[BDEVNAME_SIZE];
-       struct kobject *ko;
        int err;
 
        /* prevent duplicates */
@@ -2477,9 +2476,8 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev)
        if ((err = kobject_add(&rdev->kobj, &mddev->kobj, "dev-%s", b)))
                goto fail;
 
-       ko = &part_to_dev(rdev->bdev->bd_part)->kobj;
        /* failure here is OK */
-       err = sysfs_create_link(&rdev->kobj, ko, "block");
+       err = sysfs_create_link(&rdev->kobj, bdev_kobj(rdev->bdev), "block");
        rdev->sysfs_state = sysfs_get_dirent_safe(rdev->kobj.sd, "state");
        rdev->sysfs_unack_badblocks =
                sysfs_get_dirent_safe(rdev->kobj.sd, "unacknowledged_bad_blocks");
@@ -5355,10 +5353,9 @@ array_size_store(struct mddev *mddev, const char *buf, size_t len)
 
        if (!err) {
                mddev->array_sectors = sectors;
-               if (mddev->pers) {
-                       set_capacity(mddev->gendisk, mddev->array_sectors);
-                       revalidate_disk_size(mddev->gendisk, true);
-               }
+               if (mddev->pers)
+                       set_capacity_and_notify(mddev->gendisk,
+                                               mddev->array_sectors);
        }
        mddev_unlock(mddev);
        return err ?: len;
@@ -5765,11 +5762,12 @@ static int md_alloc(dev_t dev, char *name)
        return error;
 }
 
-static struct kobject *md_probe(dev_t dev, int *part, void *data)
+static void md_probe(dev_t dev)
 {
+       if (MAJOR(dev) == MD_MAJOR && MINOR(dev) >= 512)
+               return;
        if (create_on_open)
                md_alloc(dev, NULL);
-       return NULL;
 }
 
 static int add_named_array(const char *val, const struct kernel_param *kp)
@@ -6107,8 +6105,7 @@ int do_md_run(struct mddev *mddev)
        md_wakeup_thread(mddev->thread);
        md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
 
-       set_capacity(mddev->gendisk, mddev->array_sectors);
-       revalidate_disk_size(mddev->gendisk, true);
+       set_capacity_and_notify(mddev->gendisk, mddev->array_sectors);
        clear_bit(MD_NOT_READY, &mddev->flags);
        mddev->changed = 1;
        kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE);
@@ -6423,10 +6420,9 @@ static int do_md_stop(struct mddev *mddev, int mode,
                        if (rdev->raid_disk >= 0)
                                sysfs_unlink_rdev(mddev, rdev);
 
-               set_capacity(disk, 0);
+               set_capacity_and_notify(disk, 0);
                mutex_unlock(&mddev->open_mutex);
                mddev->changed = 1;
-               revalidate_disk_size(disk, true);
 
                if (mddev->ro)
                        mddev->ro = 0;
@@ -6535,7 +6531,7 @@ static void autorun_devices(int part)
                        break;
                }
 
-               md_probe(dev, NULL, NULL);
+               md_probe(dev);
                mddev = mddev_find(dev);
                if (!mddev || !mddev->gendisk) {
                        if (mddev)
@@ -7257,8 +7253,8 @@ static int update_size(struct mddev *mddev, sector_t num_sectors)
                if (mddev_is_clustered(mddev))
                        md_cluster_ops->update_size(mddev, old_dev_sectors);
                else if (mddev->queue) {
-                       set_capacity(mddev->gendisk, mddev->array_sectors);
-                       revalidate_disk_size(mddev->gendisk, true);
+                       set_capacity_and_notify(mddev->gendisk,
+                                               mddev->array_sectors);
                }
        }
        return rv;
@@ -7480,7 +7476,6 @@ static inline bool md_ioctl_valid(unsigned int cmd)
 {
        switch (cmd) {
        case ADD_NEW_DISK:
-       case BLKROSET:
        case GET_ARRAY_INFO:
        case GET_BITMAP_FILE:
        case GET_DISK_INFO:
@@ -7507,7 +7502,6 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
        int err = 0;
        void __user *argp = (void __user *)arg;
        struct mddev *mddev = NULL;
-       int ro;
        bool did_set_md_closing = false;
 
        if (!md_ioctl_valid(cmd))
@@ -7687,35 +7681,6 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
                        goto unlock;
                }
                break;
-
-       case BLKROSET:
-               if (get_user(ro, (int __user *)(arg))) {
-                       err = -EFAULT;
-                       goto unlock;
-               }
-               err = -EINVAL;
-
-               /* if the bdev is going readonly the value of mddev->ro
-                * does not matter, no writes are coming
-                */
-               if (ro)
-                       goto unlock;
-
-               /* are we are already prepared for writes? */
-               if (mddev->ro != 1)
-                       goto unlock;
-
-               /* transitioning to readauto need only happen for
-                * arrays that call md_write_start
-                */
-               if (mddev->pers) {
-                       err = restart_array(mddev);
-                       if (err == 0) {
-                               mddev->ro = 2;
-                               set_disk_ro(mddev->gendisk, 0);
-                       }
-               }
-               goto unlock;
        }
 
        /*
@@ -7809,6 +7774,36 @@ static int md_compat_ioctl(struct block_device *bdev, fmode_t mode,
 }
 #endif /* CONFIG_COMPAT */
 
+static int md_set_read_only(struct block_device *bdev, bool ro)
+{
+       struct mddev *mddev = bdev->bd_disk->private_data;
+       int err;
+
+       err = mddev_lock(mddev);
+       if (err)
+               return err;
+
+       if (!mddev->raid_disks && !mddev->external) {
+               err = -ENODEV;
+               goto out_unlock;
+       }
+
+       /*
+        * Transitioning to read-auto need only happen for arrays that call
+        * md_write_start and which are not ready for writes yet.
+        */
+       if (!ro && mddev->ro == 1 && mddev->pers) {
+               err = restart_array(mddev);
+               if (err)
+                       goto out_unlock;
+               mddev->ro = 2;
+       }
+
+out_unlock:
+       mddev_unlock(mddev);
+       return err;
+}
+
 static int md_open(struct block_device *bdev, fmode_t mode)
 {
        /*
@@ -7886,6 +7881,7 @@ const struct block_device_operations md_fops =
 #endif
        .getgeo         = md_getgeo,
        .check_events   = md_check_events,
+       .set_read_only  = md_set_read_only,
 };
 
 static int md_thread(void *arg)
@@ -8445,7 +8441,7 @@ static int is_mddev_idle(struct mddev *mddev, int init)
        rcu_read_lock();
        rdev_for_each_rcu(rdev, mddev) {
                struct gendisk *disk = rdev->bdev->bd_disk;
-               curr_events = (int)part_stat_read_accum(&disk->part0, sectors) -
+               curr_events = (int)part_stat_read_accum(disk->part0, sectors) -
                              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
@@ -9035,10 +9031,9 @@ void md_do_sync(struct md_thread *thread)
                mddev_lock_nointr(mddev);
                md_set_array_sectors(mddev, mddev->pers->size(mddev, 0, 0));
                mddev_unlock(mddev);
-               if (!mddev_is_clustered(mddev)) {
-                       set_capacity(mddev->gendisk, mddev->array_sectors);
-                       revalidate_disk_size(mddev->gendisk, true);
-               }
+               if (!mddev_is_clustered(mddev))
+                       set_capacity_and_notify(mddev->gendisk,
+                                               mddev->array_sectors);
        }
 
        spin_lock(&mddev->lock);
@@ -9567,18 +9562,15 @@ static int __init md_init(void)
        if (!md_rdev_misc_wq)
                goto err_rdev_misc_wq;
 
-       if ((ret = register_blkdev(MD_MAJOR, "md")) < 0)
+       ret = __register_blkdev(MD_MAJOR, "md", md_probe);
+       if (ret < 0)
                goto err_md;
 
-       if ((ret = register_blkdev(0, "mdp")) < 0)
+       ret = __register_blkdev(0, "mdp", md_probe);
+       if (ret < 0)
                goto err_mdp;
        mdp_major = ret;
 
-       blk_register_region(MKDEV(MD_MAJOR, 0), 512, THIS_MODULE,
-                           md_probe, NULL, NULL);
-       blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE,
-                           md_probe, NULL, NULL);
-
        register_reboot_notifier(&md_notifier);
        raid_table_header = register_sysctl_table(raid_root_table);
 
@@ -9845,9 +9837,6 @@ static __exit void md_exit(void)
        struct list_head *tmp;
        int delay = 1;
 
-       blk_unregister_region(MKDEV(MD_MAJOR,0), 512);
-       blk_unregister_region(MKDEV(mdp_major,0), 1U << MINORBITS);
-
        unregister_blkdev(MD_MAJOR,"md");
        unregister_blkdev(mdp_major, "mdp");
        unregister_reboot_notifier(&md_notifier);