[Devel] [PATCH RHEL9 COMMIT] dm-qcow2: Fix md_page id overflow

Konstantin Khorenko khorenko at virtuozzo.com
Thu Nov 21 19:15:32 MSK 2024


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.1
------>
commit 31d38adaf16a250bedc3d0f99bf92a4a04f92275
Author: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Date:   Wed Nov 20 19:07:21 2024 +0800

    dm-qcow2: Fix md_page id overflow
    
    In dmesg we see messages from place_r2():
    
      dm-qcow2: dm-44846: Can't alloc: ret=-17, page_id=4294967296
    
    It tries to insert the page at 16TB offset to qcow2->md_pages rb-tree
    and fails, as index is put to (unsigned int) which overflows to 0, and 0
    page is already there.
    
    Let's switch the type of variables which store this index to u64.
    
    Fixes: 9e684aa07ce39 ("dm-qcow2: Introduce driver to create block devices over QCOW2 files")
    Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
    
    Feature: dm-qcow2: block device over QCOW2 files driver
---
 drivers/md/dm-qcow2-target.c | 11 +++++------
 drivers/md/dm-qcow2.h        |  6 +++---
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/md/dm-qcow2-target.c b/drivers/md/dm-qcow2-target.c
index 276eab9acc4f..1278a9af52b9 100644
--- a/drivers/md/dm-qcow2-target.c
+++ b/drivers/md/dm-qcow2-target.c
@@ -267,7 +267,7 @@ static void qcow2_tgt_destroy(struct qcow2_target *tgt)
 	kfree(tgt);
 }
 
-static struct md_page *__md_page_find(struct qcow2 *qcow2, unsigned int id)
+static struct md_page *__md_page_find(struct qcow2 *qcow2, u64 id)
 {
 	struct rb_node *node = qcow2->md_pages.rb_node;
 	struct md_page *md;
@@ -287,7 +287,7 @@ static struct md_page *__md_page_find(struct qcow2 *qcow2, unsigned int id)
 	return NULL;
 }
 
-static struct md_page *qcow2_md_page_find(struct qcow2 *qcow2, unsigned int id)
+static struct md_page *qcow2_md_page_find(struct qcow2 *qcow2, u64 id)
 {
 	struct md_page *md;
 
@@ -302,7 +302,7 @@ ALLOW_ERROR_INJECTION(qcow2_md_page_find, NULL);
  * This returns md if it's found and up to date, or NULL.
  * @qio is zeroed if it's postponed.
  */
-struct md_page *qcow2_md_page_find_or_postpone(struct qcow2 *qcow2, unsigned int id,
+struct md_page *qcow2_md_page_find_or_postpone(struct qcow2 *qcow2, u64 id,
 					 struct qio **qio)
 {
 	struct md_page *md;
@@ -324,7 +324,7 @@ ALLOW_ERROR_INJECTION(qcow2_md_page_find_or_postpone, NULL);
 static int md_page_try_insert(struct qcow2 *qcow2, struct md_page *new_md)
 {
 	struct rb_root *root = &qcow2->md_pages;
-	unsigned int new_id = new_md->id;
+	u64 new_id = new_md->id;
 	struct rb_node *parent, **node;
 	struct md_page *md;
 
@@ -354,8 +354,7 @@ void qcow2_md_page_erase(struct qcow2 *qcow2, struct md_page *md)
 	rb_erase(&md->node, &qcow2->md_pages);
 }
 
-struct md_page *qcow2_md_page_renumber(struct qcow2 *qcow2, unsigned int id,
-						      unsigned int new_id)
+struct md_page *qcow2_md_page_renumber(struct qcow2 *qcow2, u64 id, u64 new_id)
 {
 	struct md_page *md;
 
diff --git a/drivers/md/dm-qcow2.h b/drivers/md/dm-qcow2.h
index 42f041a82a5b..7efd49ffae72 100644
--- a/drivers/md/dm-qcow2.h
+++ b/drivers/md/dm-qcow2.h
@@ -310,9 +310,9 @@ void do_qcow2_fsync_work(struct work_struct *ws);
 int qcow2_alloc_and_insert_md_page(struct qcow2 *qcow2, u64 index,
 					struct md_page **md);
 struct md_page *qcow2_md_page_find_or_postpone(struct qcow2 *qcow2,
-					unsigned int id, struct qio **qio);
-struct md_page *qcow2_md_page_renumber(struct qcow2 *qcow2, unsigned int id,
-					unsigned int new_id);
+					       u64 id, struct qio **qio);
+struct md_page *qcow2_md_page_renumber(struct qcow2 *qcow2, u64 id,
+				       u64 new_id);
 void qcow2_md_page_erase(struct qcow2 *qcow2, struct md_page *md);
 void qcow2_free_md_page(struct md_page *md);
 void qcow2_zero_fill_page_from(struct page *page, unsigned int from);


More information about the Devel mailing list