From 116e113e46ab3e455647ee389199acb6fb5741f6 Mon Sep 17 00:00:00 2001 From: caleb Date: Mon, 30 Sep 2024 11:13:28 -0400 Subject: [PATCH] wire up ioctl read keys/reservation in uapi --- block/ioctl.c | 48 +++++++++++++++++++++++++++++++++++++++++ include/linux/pr.h | 12 ----------- include/uapi/linux/pr.h | 15 ++++++++++++- 3 files changed, 62 insertions(+), 13 deletions(-) diff --git a/block/ioctl.c b/block/ioctl.c index 378603334284..201c137fc1a8 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -363,6 +363,50 @@ static int blkdev_pr_clear(struct block_device *bdev, blk_mode_t mode, return ops->pr_clear(bdev, c.key); } +static int blkdev_pr_read_keys(struct block_device *bdev, blk_mode_t mode, + struct pr_keys __user *argp) +{ + const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; + struct pr_keys k; + int err; + + if (!blkdev_pr_allowed(bdev, mode)) + return -EPERM; + if (!ops || !ops->pr_read_keys) + return -EOPNOTSUPP; + if (copy_from_user(&k, argp, sizeof(k))) + return -EFAULT; + + err = ops->pr_read_keys(bdev, &k); + if (err == 0) { + if (copy_to_user(argp, &k, sizeof(k))) + err = -EFAULT; + } + return err; +} + +static int blkdev_pr_read_reservation(struct block_device *bdev, + blk_mode_t mode, struct pr_held_reservation __user *argp) +{ + const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; + struct pr_held_reservation r; + int err; + + if (!blkdev_pr_allowed(bdev, mode)) + return -EPERM; + if (!ops || !ops->pr_read_reservation) + return -EOPNOTSUPP; + if (copy_from_user(&r, argp, sizeof(r))) + return -EFAULT; + + err = ops->pr_read_reservation(bdev, &r); + if (err == 0) { + if (copy_to_user(argp, &r, sizeof(r))) + err = -EFAULT; + } + return err; +} + static int blkdev_flushbuf(struct block_device *bdev, unsigned cmd, unsigned long arg) { @@ -571,6 +615,10 @@ static int blkdev_common_ioctl(struct block_device *bdev, blk_mode_t mode, return blkdev_pr_preempt(bdev, mode, argp, true); case IOC_PR_CLEAR: return blkdev_pr_clear(bdev, mode, argp); + case IOC_PR_READ_KEYS: + return blkdev_pr_read_keys(bdev, argp); + case IOC_PR_READ_RESV: + return blkdev_pr_read_reservation(bdev, argp); default: return -ENOIOCTLCMD; } diff --git a/include/linux/pr.h b/include/linux/pr.h index 3003daec28a5..e3ccfbd9dfba 100644 --- a/include/linux/pr.h +++ b/include/linux/pr.h @@ -4,18 +4,6 @@ #include -struct pr_keys { - u32 generation; - u32 num_keys; - u64 keys[]; -}; - -struct pr_held_reservation { - u64 key; - u32 generation; - enum pr_type type; -}; - struct pr_ops { int (*pr_register)(struct block_device *bdev, u64 old_key, u64 new_key, u32 flags); diff --git a/include/uapi/linux/pr.h b/include/uapi/linux/pr.h index d8126415966f..9fb89c09ccb7 100644 --- a/include/uapi/linux/pr.h +++ b/include/uapi/linux/pr.h @@ -56,6 +56,18 @@ struct pr_clear { __u32 __pad; }; +struct pr_keys { + u32 generation; + u32 num_keys; + u64 keys[]; +}; + +struct pr_held_reservation { + u64 key; + u32 generation; + enum pr_type type; +}; + #define PR_FL_IGNORE_KEY (1 << 0) /* ignore existing key */ #define IOC_PR_REGISTER _IOW('p', 200, struct pr_registration) @@ -64,5 +76,6 @@ struct pr_clear { #define IOC_PR_PREEMPT _IOW('p', 203, struct pr_preempt) #define IOC_PR_PREEMPT_ABORT _IOW('p', 204, struct pr_preempt) #define IOC_PR_CLEAR _IOW('p', 205, struct pr_clear) - +#define IOC_PR_READ_KEYS _IOW('p', 206, struct pr_keys) +#define IOC_PR_READ_RESV _IOW('p', 207, struct pr_held_reservation) #endif /* _UAPI_PR_H */