md: set mddev readonly flag on blkdev BLKROSET ioctl
When the user sets the block device to readwrite then the mddev should follow suit. Otherwise, the BUG_ON in md_write_start() will be set to trigger. The reverse direction, setting mddev->ro to match a set readonly request, can be ignored because the blkdev level readonly flag precludes the need to have mddev->ro set correctly. Nevermind the fact that setting mddev->ro to 1 may fail if the array is in use. Cc: <stable@kernel.org> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
@@ -5489,6 +5489,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
void __user *argp = (void __user *)arg;
|
void __user *argp = (void __user *)arg;
|
||||||
mddev_t *mddev = NULL;
|
mddev_t *mddev = NULL;
|
||||||
|
int ro;
|
||||||
|
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
@@ -5624,6 +5625,34 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
|
|||||||
err = do_md_stop(mddev, 1, 1);
|
err = do_md_stop(mddev, 1, 1);
|
||||||
goto done_unlock;
|
goto done_unlock;
|
||||||
|
|
||||||
|
case BLKROSET:
|
||||||
|
if (get_user(ro, (int __user *)(arg))) {
|
||||||
|
err = -EFAULT;
|
||||||
|
goto done_unlock;
|
||||||
|
}
|
||||||
|
err = -EINVAL;
|
||||||
|
|
||||||
|
/* if the bdev is going readonly the value of mddev->ro
|
||||||
|
* does not matter, no writes are coming
|
||||||
|
*/
|
||||||
|
if (ro)
|
||||||
|
goto done_unlock;
|
||||||
|
|
||||||
|
/* are we are already prepared for writes? */
|
||||||
|
if (mddev->ro != 1)
|
||||||
|
goto done_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 done_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user