[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