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.zhadche...@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; + } + + 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 -- 2.39.3 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel