[Devel] [PATCH RHEL9 COMMIT] block/blk-cbt: add BLKCBTLIST ioctl

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 3684562b9ec0e5fe8d9362ff0d006da3a86aecf0
Author: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
Date:   Tue Jan 28 11:15:08 2025 +0300

    block/blk-cbt: add BLKCBTLIST ioctl
    
    so user can query the list of active bitmaps.
    
    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 ++++++++++++++++++++++++++++++++++++
 block/ioctl.c           |  1 +
 include/uapi/linux/fs.h |  9 +++++++++
 3 files changed, 46 insertions(+)

diff --git a/block/blk-cbt.c b/block/blk-cbt.c
index 2543bf1e846c..5e5f224cf8f4 100644
--- a/block/blk-cbt.c
+++ b/block/blk-cbt.c
@@ -986,6 +986,40 @@ static int cbt_ioc_set(struct block_device *bdev, struct blk_user_cbt_info __use
 	return ret;
 }
 
+static int cbt_ioc_list(struct block_device *bdev, void __user *arg)
+{
+	void __user *name_ptr = (void *)((size_t)arg + sizeof(struct blk_user_cbt_list));
+	struct request_queue *q = bdev_get_queue(bdev);
+	struct blk_user_cbt_list lst;
+	struct cbt_info *cbt;
+	__u32 total = 0;
+
+	if (copy_from_user(&lst, arg, sizeof(lst)))
+		return -EFAULT;
+
+	if (!access_ok(name_ptr,
+		       lst.count * CBT_NAME_LENGTH))
+		return -EFAULT;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(cbt, &q->cbt_list, list) {
+		if (total < lst.count) {
+			if (copy_to_user(name_ptr, cbt->name, CBT_NAME_LENGTH))
+				return -EFAULT;
+			name_ptr = (void *)((size_t)name_ptr + CBT_NAME_LENGTH);
+		}
+		total++;
+	}
+	rcu_read_unlock();
+
+	lst.count = total;
+
+	if (copy_to_user(arg, &lst, sizeof(lst)))
+		return -EFAULT;
+
+	return 0;
+}
+
 static int cbt_ioc_misc(struct block_device *bdev, void __user *arg)
 {
 	struct request_queue *q = bdev_get_queue(bdev);
@@ -1041,6 +1075,8 @@ int blk_cbt_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
 		return cbt_ioc_set(bdev, ucbt_ioc, 0);
 	case BLKCBTMISC:
 		return cbt_ioc_misc(bdev, arg);
+	case BLKCBTLIST:
+		return cbt_ioc_list(bdev, arg);
 	default:
 		BUG();
 	}
diff --git a/block/ioctl.c b/block/ioctl.c
index b2d3dbe5bef5..6e76d55790ea 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -569,6 +569,7 @@ static int blkdev_common_ioctl(struct block_device *bdev, blk_mode_t mode,
 	case BLKCBTSET:
 	case BLKCBTCLR:
 	case BLKCBTMISC:
+	case BLKCBTLIST:
 		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 2aaee5257477..3122e2783eda 100644
--- a/include/uapi/linux/fs.h
+++ b/include/uapi/linux/fs.h
@@ -174,12 +174,21 @@ struct blk_user_cbt_snap_create {
 	__u64 size;
 };
 
+struct blk_user_cbt_list {
+	__u32 version;		/* API version */
+	__u32 count;		/* Amount of name entries in names
+				 * in - available, out - filled
+				 */
+	__u8 names[0];		/* Array of CBT_NAME_LENGTH long names */
+};
+
 #define BLKCBTSTART _IOR(0x12,200, struct blk_user_cbt_info)
 #define BLKCBTSTOP _IOR(0x12, 201, struct blk_user_cbt_info)
 #define BLKCBTGET _IOWR(0x12,202,struct blk_user_cbt_info)
 #define BLKCBTSET _IOR(0x12,203,struct blk_user_cbt_info)
 #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)
 
 /*
  * Flags for the fsx_xflags field


More information about the Devel mailing list