Merge tag 'gcc-plugins-v4.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / drivers / md / md.c
index 915e84d..eac84d8 100644 (file)
@@ -5297,6 +5297,21 @@ int md_run(struct mddev *mddev)
                return err;
        }
        if (mddev->queue) {
+               bool nonrot = true;
+
+               rdev_for_each(rdev, mddev) {
+                       if (rdev->raid_disk >= 0 &&
+                           !blk_queue_nonrot(bdev_get_queue(rdev->bdev))) {
+                               nonrot = false;
+                               break;
+                       }
+               }
+               if (mddev->degraded)
+                       nonrot = false;
+               if (nonrot)
+                       queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mddev->queue);
+               else
+                       queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, mddev->queue);
                mddev->queue->backing_dev_info.congested_data = mddev;
                mddev->queue->backing_dev_info.congested_fn = md_congested;
        }
@@ -5454,12 +5469,14 @@ static void md_clean(struct mddev *mddev)
        mddev->degraded = 0;
        mddev->safemode = 0;
        mddev->private = NULL;
+       mddev->cluster_info = NULL;
        mddev->bitmap_info.offset = 0;
        mddev->bitmap_info.default_offset = 0;
        mddev->bitmap_info.default_space = 0;
        mddev->bitmap_info.chunksize = 0;
        mddev->bitmap_info.daemon_sleep = 0;
        mddev->bitmap_info.max_write_behind = 0;
+       mddev->bitmap_info.nodes = 0;
 }
 
 static void __md_stop_writes(struct mddev *mddev)
@@ -5573,8 +5590,7 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
        mutex_lock(&mddev->open_mutex);
        if ((mddev->pers && atomic_read(&mddev->openers) > !!bdev) ||
            mddev->sync_thread ||
-           test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
-           (bdev && !test_bit(MD_STILL_CLOSED, &mddev->flags))) {
+           test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) {
                printk("md: %s still in use.\n",mdname(mddev));
                if (did_freeze) {
                        clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
@@ -5636,8 +5652,7 @@ static int do_md_stop(struct mddev *mddev, int mode,
        if ((mddev->pers && atomic_read(&mddev->openers) > !!bdev) ||
            mddev->sysfs_active ||
            mddev->sync_thread ||
-           test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
-           (bdev && !test_bit(MD_STILL_CLOSED, &mddev->flags))) {
+           test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) {
                printk("md: %s still in use.\n",mdname(mddev));
                mutex_unlock(&mddev->open_mutex);
                if (did_freeze) {
@@ -6101,9 +6116,14 @@ static int add_new_disk(struct mddev *mddev, mdu_disk_info_t *info)
                        export_rdev(rdev);
 
                if (mddev_is_clustered(mddev)) {
-                       if (info->state & (1 << MD_DISK_CANDIDATE))
-                               md_cluster_ops->new_disk_ack(mddev, (err == 0));
-                       else {
+                       if (info->state & (1 << MD_DISK_CANDIDATE)) {
+                               if (!err) {
+                                       err = md_cluster_ops->new_disk_ack(mddev,
+                                               err == 0);
+                                       if (err)
+                                               md_kick_rdev_from_array(rdev);
+                               }
+                       } else {
                                if (err)
                                        md_cluster_ops->add_new_disk_cancel(mddev);
                                else
@@ -6821,7 +6841,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
                        err = -EBUSY;
                        goto out;
                }
-               set_bit(MD_STILL_CLOSED, &mddev->flags);
+               set_bit(MD_CLOSING, &mddev->flags);
                mutex_unlock(&mddev->open_mutex);
                sync_blockdev(bdev);
        }
@@ -7070,9 +7090,13 @@ static int md_open(struct block_device *bdev, fmode_t mode)
        if ((err = mutex_lock_interruptible(&mddev->open_mutex)))
                goto out;
 
+       if (test_bit(MD_CLOSING, &mddev->flags)) {
+               mutex_unlock(&mddev->open_mutex);
+               return -ENODEV;
+       }
+
        err = 0;
        atomic_inc(&mddev->openers);
-       clear_bit(MD_STILL_CLOSED, &mddev->flags);
        mutex_unlock(&mddev->open_mutex);
 
        check_disk_change(bdev);
@@ -8873,7 +8897,9 @@ static void autostart_arrays(int part)
                list_del(&node_detected_dev->list);
                dev = node_detected_dev->dev;
                kfree(node_detected_dev);
+               mutex_unlock(&detected_devices_mutex);
                rdev = md_import_device(dev,0, 90);
+               mutex_lock(&detected_devices_mutex);
                if (IS_ERR(rdev))
                        continue;