[Devel] [PATCH vz9] dm-qcow2: fix qcow2 decompression

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Mon Feb 17 11:28:56 MSK 2025


Reviewed-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>

Note: due to the way pos is calculated it can't be more than long long 
max, so this conversion should not overflow (as offset_bits <= 62).

On 2/17/25 14:13, Alexander Atanasov wrote:
> Two problems - using wrong size type:
> 
> - process_compressed_read used blk_status_t for ret which is u8
> so it can not process negative error codes and larger sizes
> properly - fix this by changing it to int
> 
> - decompression fails for images with size larger than 2GB
> due to wrong return type of parse_compressed_l2 - the calculations
> are performed properly in u64 type but on return result is truncated
> Fix this by changing the return type to loff_t
> 
> https://virtuozzo.atlassian.net/browse/VSTOR-98868
> Signed-off-by: Alexander Atanasov <alexander.atanasov at virtuozzo.com>
> ---
>   drivers/md/dm-qcow2-map.c | 6 +++---
>   1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/md/dm-qcow2-map.c b/drivers/md/dm-qcow2-map.c
> index 54bb8bd713be..ccc8d4484049 100644
> --- a/drivers/md/dm-qcow2-map.c
> +++ b/drivers/md/dm-qcow2-map.c
> @@ -1729,7 +1729,7 @@ static loff_t parse_l1(struct qcow2 *qcow2, struct qcow2_map *map,
>   	return ret;
>   }
>   
> -static int parse_compressed_l2(struct qcow2 *qcow2, struct qcow2_map *map,
> +static loff_t parse_compressed_l2(struct qcow2 *qcow2, struct qcow2_map *map,
>   			       struct qio **qio, bool write, u64 entry)
>   {
>   	u8 offset_bits = 62 - (qcow2->hdr.cluster_bits - 8);
> @@ -3660,7 +3660,7 @@ static void process_compressed_read(struct qcow2 *qcow2, struct list_head *read_
>   {
>   	struct qcow2_bvec *qvec;
>   	struct qio_ext *ext;
> -	blk_status_t ret;
> +	int ret;
>   	void *buf = NULL, *arg;
>   	struct qio *qio;
>   	bool for_cow;
> @@ -3698,7 +3698,7 @@ static void process_compressed_read(struct qcow2 *qcow2, struct list_head *read_
>   
>   		ret = extract_one_compressed(qcow2, buf, qvec,
>   				    ext->zdata_off, qio->ret, arg);
> -		if (ret)
> +		if (ret <= 0)
>   			goto err;
>   
>   		for_cow = op_is_write(qio->bi_op);

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



More information about the Devel mailing list