Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2218350 authored by Dan Williams's avatar Dan Williams Committed by NeilBrown
Browse files

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: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent 627a2d3c
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -5489,6 +5489,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
	int err = 0;
	void __user *argp = (void __user *)arg;
	mddev_t *mddev = NULL;
	int ro;

	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;
@@ -5624,6 +5625,34 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
			err = do_md_stop(mddev, 1, 1);
			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;
	}

	/*