{
        switch (cmd) {
        case ADD_NEW_DISK:
-       case BLKROSET:
        case GET_ARRAY_INFO:
        case GET_BITMAP_FILE:
        case GET_DISK_INFO:
        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))
                        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;
        }
 
        /*
 }
 #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)
 {
        /*
 #endif
        .getgeo         = md_getgeo,
        .check_events   = md_check_events,
+       .set_read_only  = md_set_read_only,
 };
 
 static int md_thread(void *arg)