[Devel] [PATCH VZ9 v2 5/5] block/blk-cbt: add BLKCBTRENAME instead of BLKCBTSET flag
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Tue Jan 28 10:07:43 MSK 2025
On 1/28/25 08:39, Andrey Zhadchenko wrote:
> Users could rename cbts with CI_FLAG_NEW_NAME flag during
> BLKCBTSET ioctl. Set command now uses ci_name to identify
> target, so we need a new field to present updated name.
> Add new BLKCBTRENAME ioctl instead of adding new fields to
> blk_user_cbt_info.
>
> Note that we do not need to extra protect cbt->name: it is only
> used by
> - concurrent userspace commands, which are also taking cbt_mutex
> - cbt_page_alloc + CBT_DEAD bit. Fortunately CBT_DEAD bit can
> only occur during another user space command, which again is
> helding cbt_mutex.
>
> https://virtuozzo.atlassian.net/browse/VSTOR-96269
> Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
> ---
> block/blk-cbt.c | 47 ++++++++++++++++++++++++++++++++++++-----
> block/ioctl.c | 1 +
> include/uapi/linux/fs.h | 2 +-
> 3 files changed, 44 insertions(+), 6 deletions(-)
>
> diff --git a/block/blk-cbt.c b/block/blk-cbt.c
> index 3fd28ec8c0d2..dcda59240878 100644
> --- a/block/blk-cbt.c
> +++ b/block/blk-cbt.c
> @@ -946,11 +946,6 @@ static int cbt_ioc_set(struct block_device *bdev, struct blk_user_cbt_info __use
> if (!cbt)
> goto ioc_set_failed;
>
> - if (ci.ci_flags & CI_FLAG_NEW_NAME)
> - memcpy(cbt->name, &ci.ci_name, sizeof(ci.ci_name));
> - else if (memcmp(cbt->name, &ci.ci_name, sizeof(ci.ci_name)))
> - goto ioc_set_failed;
> -
> ret = -EIO;
> if (test_bit(CBT_ERROR, &cbt->flags))
> goto ioc_set_failed;
> @@ -1020,6 +1015,46 @@ static int cbt_ioc_list(struct block_device *bdev, void __user *arg)
> return 0;
> }
>
> +static int cbt_ioc_rename(struct block_device *bdev, void __user *arg)
> +{
> + struct request_queue *q = bdev_get_queue(bdev);
> + struct blk_user_cbt_list lst;
> + char name[CBT_NAME_LENGTH];
> + struct cbt_info *cbt;
> +
> + if (copy_from_user(&lst, arg, sizeof(lst)))
> + return -EFAULT;
> +
> + if (lst.count != 2)
> + return -EINVAL;
> +
> + if (copy_from_user(name, (char *)arg + sizeof(lst), CBT_NAME_LENGTH))
> + return -EFAULT;
> +
> + mutex_lock(&cbt_mutex);
> +
> + cbt = blk_cbt_find(q, name);
> + if (!cbt) {
> + mutex_unlock(&cbt_mutex);
> + return -ENOENT;
> + }
> +
> + if (copy_from_user(name, (char *)arg + sizeof(lst) + CBT_NAME_LENGTH, CBT_NAME_LENGTH)) {
> + mutex_unlock(&cbt_mutex);
> + return -EFAULT;
> + }
Moving the above user-copy to before taking mutex_lock, would 1)
decrease mutex held time, 2) save us one line as we would not need
mutex_unlock there and 3) generally make the code easier to read as
user-copies are brought together in code.
> +
> + if (blk_cbt_find(q, name)) {
> + mutex_unlock(&cbt_mutex);
> + return -EINVAL;
> + }
> +
> + memcpy(cbt->name, name, CBT_NAME_LENGTH);
> + mutex_unlock(&cbt_mutex);
> +
> + return 0;
> +}
> +
> static int cbt_ioc_misc(struct block_device *bdev, void __user *arg)
> {
> struct request_queue *q = bdev_get_queue(bdev);
> @@ -1077,6 +1112,8 @@ int blk_cbt_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
> return cbt_ioc_misc(bdev, arg);
> case BLKCBTLIST:
> return cbt_ioc_list(bdev, arg);
> + case BLKCBTRENAME:
> + return cbt_ioc_rename(bdev, arg);
> default:
> BUG();
> }
> diff --git a/block/ioctl.c b/block/ioctl.c
> index 6e76d55790ea..05d79953b2c0 100644
> --- a/block/ioctl.c
> +++ b/block/ioctl.c
> @@ -570,6 +570,7 @@ static int blkdev_common_ioctl(struct block_device *bdev, blk_mode_t mode,
> case BLKCBTCLR:
> case BLKCBTMISC:
> case BLKCBTLIST:
> + case BLKCBTRENAME:
> return blk_cbt_ioctl(bdev, cmd, (char __user *)arg);
> default:
> return -ENOIOCTLCMD;
> diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
> index 3122e2783eda..4ab115091bab 100644
> --- a/include/uapi/linux/fs.h
> +++ b/include/uapi/linux/fs.h
> @@ -151,7 +151,6 @@ struct blk_user_cbt_info {
> enum CI_FLAGS
> {
> CI_FLAG_ONCE = 1, /* BLKCBTGET will clear bits */
> - CI_FLAG_NEW_NAME = 2 /* BLKCBTSET update name */
> };
>
> /* Extension of cbt ioctls: */
> @@ -189,6 +188,7 @@ struct blk_user_cbt_list {
> #define BLKCBTCLR _IOR(0x12,204,struct blk_user_cbt_info)
> #define BLKCBTMISC _IOWR(0x12,205,struct blk_user_cbt_misc_info)
> #define BLKCBTLIST _IOWR(0x12, 206, struct blk_user_cbt_list)
> +#define BLKCBTRENAME _IOWR(0x12, 207, struct blk_user_cbt_list)
>
> /*
> * Flags for the fsx_xflags field
--
Best regards, Tikhomirov Pavel
Senior Software Developer, Virtuozzo.
More information about the Devel
mailing list