summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorJingbo Xu <jefflexu@linux.alibaba.com>2023-06-13 11:40:07 +0300
committerJens Axboe <axboe@kernel.dk>2023-06-20 21:49:23 +0300
commit12629621669b239445727256d1a5dab616b30deb (patch)
treef1aea1b4d235f0faf6a23c8b2deecec34bd7cfef /block
parentc576c4bf9ecfa3fb9f7b11681cc2f60aba5276c4 (diff)
downloadlinux-12629621669b239445727256d1a5dab616b30deb.tar.xz
block: disallow Persistent Reservation on partitions
Refuse Persistent Reservation operations on partitions as reservation on partitions doesn't make sense. Besides, introduce blkdev_pr_allowed() helper, where more policies could be placed here later. Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20230613084008.93795-2-jefflexu@linux.alibaba.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r--block/ioctl.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/block/ioctl.c b/block/ioctl.c
index 61bb94fd4281..c75299006bdd 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -254,13 +254,25 @@ int blkdev_compat_ptr_ioctl(struct block_device *bdev, blk_mode_t mode,
EXPORT_SYMBOL(blkdev_compat_ptr_ioctl);
#endif
+static bool blkdev_pr_allowed(struct block_device *bdev)
+{
+ /* no sense to make reservations for partitions */
+ if (bdev_is_partition(bdev))
+ return false;
+
+ if (capable(CAP_SYS_ADMIN))
+ return true;
+
+ return false;
+}
+
static int blkdev_pr_register(struct block_device *bdev,
struct pr_registration __user *arg)
{
const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
struct pr_registration reg;
- if (!capable(CAP_SYS_ADMIN))
+ if (!blkdev_pr_allowed(bdev))
return -EPERM;
if (!ops || !ops->pr_register)
return -EOPNOTSUPP;
@@ -278,7 +290,7 @@ static int blkdev_pr_reserve(struct block_device *bdev,
const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
struct pr_reservation rsv;
- if (!capable(CAP_SYS_ADMIN))
+ if (!blkdev_pr_allowed(bdev))
return -EPERM;
if (!ops || !ops->pr_reserve)
return -EOPNOTSUPP;
@@ -296,7 +308,7 @@ static int blkdev_pr_release(struct block_device *bdev,
const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
struct pr_reservation rsv;
- if (!capable(CAP_SYS_ADMIN))
+ if (!blkdev_pr_allowed(bdev))
return -EPERM;
if (!ops || !ops->pr_release)
return -EOPNOTSUPP;
@@ -314,7 +326,7 @@ static int blkdev_pr_preempt(struct block_device *bdev,
const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
struct pr_preempt p;
- if (!capable(CAP_SYS_ADMIN))
+ if (!blkdev_pr_allowed(bdev))
return -EPERM;
if (!ops || !ops->pr_preempt)
return -EOPNOTSUPP;
@@ -332,7 +344,7 @@ static int blkdev_pr_clear(struct block_device *bdev,
const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
struct pr_clear c;
- if (!capable(CAP_SYS_ADMIN))
+ if (!blkdev_pr_allowed(bdev))
return -EPERM;
if (!ops || !ops->pr_clear)
return -EOPNOTSUPP;