[Devel] [PATCH RHEL9 COMMIT] block/blk-cbt: add BLKCBTRENAME instead of BLKCBTSET flag

Konstantin Khorenko khorenko at virtuozzo.com
Tue Jan 28 17:39:58 MSK 2025


The commit is pushed to "branch-rh9-5.14.0-427.44.1.vz9.80.x-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git
after rh9-5.14.0-427.44.1.vz9.80.7
------>
commit a9f7d2a1874eca7f2a4f1f3ade3ee8a23e750c0e
Author: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
Date:   Tue Jan 28 11:15:09 2025 +0300

    block/blk-cbt: add BLKCBTRENAME instead of BLKCBTSET flag
    
    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>
    Reviewed-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
    
    ======
    Patchset description:
    blk-cbt: improvements
    
    Currently blk-cbt use UUID as a name. This is a big limitation.
    We are going to expose bitmap names to libvirt, so we should
    not expect users to follow this. Moreover, even VHI backup
    utilities use non-UUID names sometimes. Technically QEMU
    allows us bitmap names up to 1024 bytes, but 128 should be
    fine.
    Multiple simultaneous bitmaps are needed for backup plans,
    so allow them.
    Add new API to list bitmap names, adjust most of the API to
    make operations on bitmap with user-provided name.
    
    Andrey Zhadchenko (5):
      block/blk-cbt: rework uuid field
      block/blk-cbt: allow multiple cbts in a single queue
      blk-cbt: introduce ABI versioning
      block/blk-cbt: add BLKCBTLIST ioctl
      block/blk-cbt: add BLKCBTRENAME instead of BLKCBTSET flag
    
    Feature: cbt: changed block tracking (for backup)
---
 block/blk-cbt.c         | 45 ++++++++++++++++++++++++++++++++++++++++-----
 block/ioctl.c           |  1 +
 include/uapi/linux/fs.h |  2 +-
 3 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/block/blk-cbt.c b/block/blk-cbt.c
index 5e5f224cf8f4..fa472aa5d006 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,44 @@ 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 from[CBT_NAME_LENGTH], to[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(from, (char *)arg + sizeof(lst), CBT_NAME_LENGTH))
+		return -EFAULT;
+
+	if (copy_from_user(to, (char *)arg + sizeof(lst) + CBT_NAME_LENGTH, CBT_NAME_LENGTH))
+		return -EFAULT;
+
+	mutex_lock(&cbt_mutex);
+
+	cbt = blk_cbt_find(q, from);
+	if (!cbt) {
+		mutex_unlock(&cbt_mutex);
+		return -ENOENT;
+	}
+
+	if (blk_cbt_find(q, to)) {
+		mutex_unlock(&cbt_mutex);
+		return -EINVAL;
+	}
+
+	memcpy(cbt->name, to, 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 +1110,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


More information about the Devel mailing list