aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2010-05-11 18:25:37 -0400
committerNeilBrown <neilb@suse.de>2010-05-11 18:25:37 -0400
commite2218350465e7e0931676b4849b594c978437bce (patch)
tree395398081c277c533d28edd70d08a9394e7d8597 /drivers/md/md.c
parent627a2d3c29427637f4c5d31ccc7fcbd8d312cd71 (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.c29
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 /*