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

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Fri Nov 22 06:15:30 MSK 2024



On 11/20/24 19:07, Pavel Tikhomirov wrote:
> 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")

Sorry, forgot bug link:
https://virtuozzo.atlassian.net/browse/VSTOR-94419

> 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 276eab9acc4f3..1278a9af52b9d 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 42f041a82a5b0..7efd49ffae72a 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);

-- 
Best regards, Tikhomirov Pavel
Senior Software Developer, Virtuozzo.



More information about the Devel mailing list