[Devel] [PATCH RHEL9 COMMIT] block/blk-cbt: rework uuid field

Konstantin Khorenko khorenko at virtuozzo.com
Tue Jan 28 17:39:56 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 5eb9590b303d5f92a72ecb39d7cc3c0ed1b27b01
Author: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
Date:   Tue Jan 28 11:15:05 2025 +0300

    block/blk-cbt: rework uuid field
    
    Using uuid as a bitmap name is too restrictive. We are going to
    expose bitmap names to libvirt where we cannot expect users to
    follow such constraint.
    QEMU allows bitmap names up to 1024 symbols, but this seems too
    big for the structure. We do not want to mess with dynamic length,
    so set the max length to 128.
    
    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         | 36 ++++++++++++++++++------------------
 include/uapi/linux/fs.h |  7 ++++---
 2 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/block/blk-cbt.c b/block/blk-cbt.c
index 73f28d8ccf6d..8ae993143098 100644
--- a/block/blk-cbt.c
+++ b/block/blk-cbt.c
@@ -38,7 +38,7 @@ struct cbt_extent{
 };
 
 struct cbt_info {
-	__u8 	 uuid[16];
+	__u8 name[CBT_NAME_LENGTH];
 	struct request_queue *queue;
 	blkcnt_t block_max;
 	blkcnt_t block_bits;
@@ -263,7 +263,7 @@ inline void blk_cbt_bio_queue(struct request_queue *q, struct bio *bio)
 	blk_cbt_add(q, bio->bi_iter.bi_sector << 9, bio->bi_iter.bi_size);
 }
 
-static struct cbt_info* do_cbt_alloc(struct request_queue *q, __u8 *uuid,
+static struct cbt_info *do_cbt_alloc(struct request_queue *q, __u8 *name,
 				     loff_t size, loff_t blocksize)
 {
 	struct cbt_info *cbt;
@@ -275,7 +275,7 @@ static struct cbt_info* do_cbt_alloc(struct request_queue *q, __u8 *uuid,
 	cbt->block_bits = ilog2(blocksize);
 	cbt->block_max  = DIV_ROUND_UP(size, blocksize);
 	spin_lock_init(&cbt->lock);
-	memcpy(cbt->uuid, uuid, sizeof(cbt->uuid));
+	memcpy(cbt->name, name, sizeof(cbt->name));
 	cbt->cache = alloc_percpu(struct cbt_extent);
 	if (!cbt->cache)
 		goto err_cbt;
@@ -365,7 +365,7 @@ static int copy_cbt_to_user(struct page **map, unsigned long size,
         return 0;
 }
 
-static int blk_cbt_snap_create(struct request_queue *q, __u8 *uuid,
+static int blk_cbt_snap_create(struct request_queue *q, __u8 *name,
 			       struct blk_user_cbt_snap_create __user *arg)
 {
 	unsigned long size;
@@ -392,7 +392,7 @@ static int blk_cbt_snap_create(struct request_queue *q, __u8 *uuid,
 	BUG_ON(!cbt->map);
 	BUG_ON(!cbt->block_max);
 
-	if (!uuid || memcmp(uuid, cbt->uuid, sizeof(cbt->uuid))) {
+	if (!name || memcmp(name, cbt->name, sizeof(cbt->name))) {
 		mutex_unlock(&cbt_mutex);
 		return -EINVAL;
 	}
@@ -453,7 +453,7 @@ static int blk_cbt_snap_create(struct request_queue *q, __u8 *uuid,
 	return -ENOMEM;
 }
 
-static int blk_cbt_snap_drop(struct request_queue *q, __u8 *uuid)
+static int blk_cbt_snap_drop(struct request_queue *q, __u8 *name)
 {
 	struct cbt_info *cbt;
 	unsigned long npages;
@@ -471,7 +471,7 @@ static int blk_cbt_snap_drop(struct request_queue *q, __u8 *uuid)
 	BUG_ON(!cbt->block_max);
 
 	ret = -EINVAL;
-	if (!uuid || memcmp(uuid, cbt->uuid, sizeof(cbt->uuid)))
+	if (!name || memcmp(name, cbt->name, sizeof(cbt->name)))
 		goto out;
 
 	ret = -ENODEV;
@@ -502,7 +502,7 @@ static void blk_cbt_page_merge(struct page *pg_from, struct page *pg_to)
 	}
 }
 
-static int blk_cbt_snap_merge_back(struct request_queue *q, __u8 *uuid)
+static int blk_cbt_snap_merge_back(struct request_queue *q, __u8 *name)
 {
 	struct cbt_info *cbt;
 	blkcnt_t block_max;
@@ -521,7 +521,7 @@ static int blk_cbt_snap_merge_back(struct request_queue *q, __u8 *uuid)
 	BUG_ON(!cbt->block_max);
 
 	ret = -EINVAL;
-	if (!uuid || memcmp(uuid, cbt->uuid, sizeof(cbt->uuid)))
+	if (!name || memcmp(name, cbt->name, sizeof(cbt->name)))
 		goto out;
 
 	map = cbt->snp_map;
@@ -591,7 +591,7 @@ void blk_cbt_update_size(struct block_device *bdev)
 	if (DIV_ROUND_UP(new_sz, bsz) <= cbt->block_max)
 		goto err_mtx;
 
-	new = do_cbt_alloc(q, cbt->uuid, new_sz, bsz);
+	new = do_cbt_alloc(q, cbt->name, new_sz, bsz);
 	if (IS_ERR(new)) {
 		set_bit(CBT_ERROR, &cbt->flags);
 		goto err_mtx;
@@ -636,7 +636,7 @@ static int cbt_ioc_init(struct block_device *bdev, struct blk_user_cbt_info __us
 		ret = -EBUSY;
 		goto err_mtx;
 	}
-	cbt = do_cbt_alloc(q, ci.ci_uuid, i_size_read(bdev->bd_inode), ci.ci_blksize);
+	cbt = do_cbt_alloc(q, ci.ci_name, i_size_read(bdev->bd_inode), ci.ci_blksize);
 	if (IS_ERR(cbt))
 		ret = PTR_ERR(cbt);
 	else
@@ -849,7 +849,7 @@ static int cbt_ioc_get(struct block_device *bdev, struct blk_user_cbt_info __use
 		goto ioc_get_failed;
 	cbt_flush_cache(cbt);
 
-	memcpy(&ci.ci_uuid, cbt->uuid, sizeof(cbt->uuid));
+	memcpy(&ci.ci_name, cbt->name, sizeof(cbt->name));
 	ci.ci_blksize = 1UL << cbt->block_bits;
 	block = ci.ci_start >> cbt->block_bits;
 	end = (ci.ci_start + ci.ci_length) >> cbt->block_bits;
@@ -929,9 +929,9 @@ 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_UUID)
-		memcpy(cbt->uuid, &ci.ci_uuid, sizeof(ci.ci_uuid));
-	else if (memcmp(cbt->uuid, &ci.ci_uuid, sizeof(ci.ci_uuid)))
+	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;
@@ -979,11 +979,11 @@ static int cbt_ioc_misc(struct block_device *bdev, void __user *arg)
 
 	switch (cmi.action) {
 	case CBT_SNAP_CREATE:
-		return blk_cbt_snap_create(q, cmi.uuid, arg);
+		return blk_cbt_snap_create(q, cmi.name, arg);
 	case CBT_SNAP_DROP:
-		return blk_cbt_snap_drop(q, cmi.uuid);
+		return blk_cbt_snap_drop(q, cmi.name);
 	case CBT_SNAP_MERGE_BACK:
-		return blk_cbt_snap_merge_back(q, cmi.uuid);
+		return blk_cbt_snap_merge_back(q, cmi.name);
 	default:
 		return -ENOTSUPP;
 	}
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
index a5c8a57d8f29..4820d5923b89 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -128,8 +128,9 @@ struct blk_user_cbt_extent {
 	__u64 ce_reserved64[1];
 };
 
+#define CBT_NAME_LENGTH 128
 struct blk_user_cbt_info {
-	__u8  ci_uuid[16];	/* Bitmap UUID */
+	__u8  ci_name[CBT_NAME_LENGTH];	/* CBT name */
 	__u64 ci_start;		/* start phisical range of mapping which
 				   userspace wants (in) */
 	__u64 ci_length;	/* phisical length of mapping which
@@ -145,12 +146,12 @@ struct blk_user_cbt_info {
 enum CI_FLAGS
 {
 	CI_FLAG_ONCE = 1, /* BLKCBTGET will clear bits */
-	CI_FLAG_NEW_UUID = 2 /* BLKCBTSET update uuid */
+	CI_FLAG_NEW_NAME = 2 /* BLKCBTSET update name */
 };
 
 /* Extension of cbt ioctls:  */
 struct blk_user_cbt_misc_info {
-	__u8 uuid[16]; /* Bitmap UUID */
+	__u8 name[CBT_NAME_LENGTH]; /* Bitmap name */
 /* Allocate and move pending map to CBT snapshot */
 #define CBT_SNAP_CREATE		0
 /* Drop CBT snapshot */


More information about the Devel mailing list