md: implement ->set_read_only to hook into BLKROSET processing
[ Upstream commit 118cf084adb3964d06e1667cf7d702e56e5cd2c5 ] Implement the ->set_read_only method instead of parsing the actual ioctl command. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Song Liu <song@kernel.org> Signed-off-by: Jens Axboe <axboe@kernel.dk> Stable-dep-of: 9674f54e41ff ("md: Don't clear MD_CLOSING when the raid is about to stop") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
2a0f8202f7
commit
ab25f7cd49
@ -7536,7 +7536,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:
|
||||
@ -7563,7 +7562,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))
|
||||
@ -7746,35 +7744,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;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -7868,6 +7837,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)
|
||||
{
|
||||
/*
|
||||
@ -7944,6 +7943,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)
|
||||
|
Loading…
Reference in New Issue
Block a user