Commit 118cf084 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

md: implement ->set_read_only to hook into BLKROSET processing



Implement the ->set_read_only method instead of parsing the actual
ioctl command.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: default avatarSong Liu <song@kernel.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 34919e3b
Loading
Loading
Loading
Loading
+31 −31
Original line number Diff line number Diff line
@@ -7480,7 +7480,6 @@ static inline bool md_ioctl_valid(unsigned int cmd)
{
	switch (cmd) {
	case ADD_NEW_DISK:
	case BLKROSET:
	case GET_ARRAY_INFO:
	case GET_BITMAP_FILE:
	case GET_DISK_INFO:
@@ -7507,7 +7506,6 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
	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))
@@ -7687,35 +7685,6 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
			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;
	}

	/*
@@ -7809,6 +7778,36 @@ static int md_compat_ioctl(struct block_device *bdev, fmode_t mode,
}
#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)
{
	/*
@@ -7886,6 +7885,7 @@ const struct block_device_operations md_fops =
#endif
	.getgeo		= md_getgeo,
	.check_events	= md_check_events,
	.set_read_only	= md_set_read_only,
};

static int md_thread(void *arg)