mirror of
https://github.com/torvalds/linux.git
synced 2024-11-05 03:21:32 +00:00
rbd: add ioctl for rbd
When running the following commands: [root@ceph0 mnt]# blockdev --setro /dev/rbd1 [root@ceph0 mnt]# blockdev --getro /dev/rbd1 0 The block setro didn't take effect, it is because the rbd doesn't support ioctl of block driver. This resolves: http://tracker.ceph.com/issues/6265 Signed-off-by: Guangliang Zhao <guangliang@unitedstack.com> Reviewed-by: Alex Elder <elder@linaro.org> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
This commit is contained in:
parent
4e217b5dc8
commit
131fd9f6fc
@ -559,10 +559,69 @@ static void rbd_release(struct gendisk *disk, fmode_t mode)
|
||||
put_device(&rbd_dev->dev);
|
||||
}
|
||||
|
||||
static int rbd_ioctl_set_ro(struct rbd_device *rbd_dev, unsigned long arg)
|
||||
{
|
||||
int val;
|
||||
bool ro;
|
||||
|
||||
if (get_user(val, (int __user *)(arg)))
|
||||
return -EFAULT;
|
||||
|
||||
ro = val ? true : false;
|
||||
/* Snapshot doesn't allow to write*/
|
||||
if (rbd_dev->spec->snap_id != CEPH_NOSNAP && !ro)
|
||||
return -EROFS;
|
||||
|
||||
if (rbd_dev->mapping.read_only != ro) {
|
||||
rbd_dev->mapping.read_only = ro;
|
||||
set_disk_ro(rbd_dev->disk, ro ? 1 : 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rbd_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct rbd_device *rbd_dev = bdev->bd_disk->private_data;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock_irq(&rbd_dev->lock);
|
||||
/* prevent others open this device */
|
||||
if (rbd_dev->open_count > 1) {
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case BLKROSET:
|
||||
ret = rbd_ioctl_set_ro(rbd_dev, arg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock_irq(&rbd_dev->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static int rbd_compat_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
return rbd_ioctl(bdev, mode, cmd, arg);
|
||||
}
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
static const struct block_device_operations rbd_bd_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = rbd_open,
|
||||
.release = rbd_release,
|
||||
.ioctl = rbd_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = rbd_compat_ioctl,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@ -3114,7 +3173,6 @@ static void rbd_request_fn(struct request_queue *q)
|
||||
__releases(q->queue_lock) __acquires(q->queue_lock)
|
||||
{
|
||||
struct rbd_device *rbd_dev = q->queuedata;
|
||||
bool read_only = rbd_dev->mapping.read_only;
|
||||
struct request *rq;
|
||||
int result;
|
||||
|
||||
@ -3150,7 +3208,7 @@ static void rbd_request_fn(struct request_queue *q)
|
||||
|
||||
if (write_request) {
|
||||
result = -EROFS;
|
||||
if (read_only)
|
||||
if (rbd_dev->mapping.read_only)
|
||||
goto end_request;
|
||||
rbd_assert(rbd_dev->spec->snap_id == CEPH_NOSNAP);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user