diff options
author | Dan Williams <dan.j.williams@intel.com> | 2010-05-11 18:25:37 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2010-05-11 18:25:37 -0400 |
commit | e2218350465e7e0931676b4849b594c978437bce (patch) | |
tree | 395398081c277c533d28edd70d08a9394e7d8597 /drivers/md/md.c | |
parent | 627a2d3c29427637f4c5d31ccc7fcbd8d312cd71 (diff) |
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>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index a20a71e5efd3..08f665178c3b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -5489,6 +5489,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, | |||
5489 | int err = 0; | 5489 | int err = 0; |
5490 | void __user *argp = (void __user *)arg; | 5490 | void __user *argp = (void __user *)arg; |
5491 | mddev_t *mddev = NULL; | 5491 | mddev_t *mddev = NULL; |
5492 | int ro; | ||
5492 | 5493 | ||
5493 | if (!capable(CAP_SYS_ADMIN)) | 5494 | if (!capable(CAP_SYS_ADMIN)) |
5494 | return -EACCES; | 5495 | return -EACCES; |
@@ -5624,6 +5625,34 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, | |||
5624 | err = do_md_stop(mddev, 1, 1); | 5625 | err = do_md_stop(mddev, 1, 1); |
5625 | goto done_unlock; | 5626 | goto done_unlock; |
5626 | 5627 | ||
5628 | case BLKROSET: | ||
5629 | if (get_user(ro, (int __user *)(arg))) { | ||
5630 | err = -EFAULT; | ||
5631 | goto done_unlock; | ||
5632 | } | ||
5633 | err = -EINVAL; | ||
5634 | |||
5635 | /* if the bdev is going readonly the value of mddev->ro | ||
5636 | * does not matter, no writes are coming | ||
5637 | */ | ||
5638 | if (ro) | ||
5639 | goto done_unlock; | ||
5640 | |||
5641 | /* are we are already prepared for writes? */ | ||
5642 | if (mddev->ro != 1) | ||
5643 | goto done_unlock; | ||
5644 | |||
5645 | /* transitioning to readauto need only happen for | ||
5646 | * arrays that call md_write_start | ||
5647 | */ | ||
5648 | if (mddev->pers) { | ||
5649 | err = restart_array(mddev); | ||
5650 | if (err == 0) { | ||
5651 | mddev->ro = 2; | ||
5652 | set_disk_ro(mddev->gendisk, 0); | ||
5653 | } | ||
5654 | } | ||
5655 | goto done_unlock; | ||
5627 | } | 5656 | } |
5628 | 5657 | ||
5629 | /* | 5658 | /* |