OpenVZ / Virtuozzo kernel development (devel@openvz.org)
 help / color / mirror / Atom feed
From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Subject: Re: [Devel] [PATCH VZ10 2/6] drivers/md/dm-qcow2: keep seek parse window within limit
Date: Fri, 14 Aug 2026 11:55:26 +0200	[thread overview]
Message-ID: <23cafc93-d83e-4cf9-9c7b-4f6e0e317d02@virtuozzo.com> (raw)
In-Reply-To: <20260810123000.19834-3-andrey.zhadchenko@virtuozzo.com>



On 8/10/26 14:29, Andrey Zhadchenko wrote:
> seek_qio_next_clu() always sets the window size to the whole
> cluster, so the window may cross the scan limit. The top level qio
> then parses metadata past the virtual disk end if the disk size is
> not cluster aligned, and SEEK_HOLE may report "sector + size" past
> the limit.
> This is especially painful for lower delta seeks, since at top
> level this is luckily alleviated by blkdev_llseek_wrapper().
> 
> Add seek_qio_set_sector(), which sets bi_sector and also clamps
> bi_size if needed.
> 
> https://virtuozzo.atlassian.net/browse/VSTOR-139407
> Feature: dm-qcow2: block device over QCOW2 files driver
> Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko@virtuozzo.com>
> ---
>  drivers/md/dm-qcow2-map.c | 29 +++++++++++++++++------------
>  1 file changed, 17 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/md/dm-qcow2-map.c b/drivers/md/dm-qcow2-map.c
> index 542c7949321e5..342e4af688509 100644
> --- a/drivers/md/dm-qcow2-map.c
> +++ b/drivers/md/dm-qcow2-map.c
> @@ -4352,6 +4352,16 @@ struct qio_data_llseek_hole {
>  
>  #define SEEK_QIO_DATA(qio) ((struct qio_data_llseek_hole *)qio->data)
>  
> +static void seek_qio_set_sector(struct qio *qio, sector_t bi_sector)
> +{
> +	loff_t pos = to_bytes(bi_sector);
> +	loff_t end = round_up(pos + 1, qio->qcow2->clu_size);
> +
> +	qio->bi_iter.bi_sector = bi_sector;
> +	end = min_t(loff_t, end, SEEK_QIO_DATA(qio)->lim);
> +	qio->bi_iter.bi_size = end > pos ? end - pos : 0;
> +}
> +
>  static struct qio *alloc_seek_qio(struct qcow2 *qcow2, struct qio *parent, loff_t new_lim)
>  {
>  	struct qio_data_llseek_hole *data;
> @@ -4376,12 +4386,7 @@ static struct qio *alloc_seek_qio(struct qcow2 *qcow2, struct qio *parent, loff_
>  
>  	if (parent) {
>  		data->higher = parent;
> -		qio->bi_iter.bi_sector = parent->bi_iter.bi_sector;
> -
> -		if (to_bytes(qio->bi_iter.bi_sector) + parent->bi_iter.bi_size > new_lim)
> -			qio->bi_iter.bi_size = new_lim - to_bytes(qio->bi_iter.bi_sector);
> -		else
> -			qio->bi_iter.bi_size = parent->bi_iter.bi_size;
> +		seek_qio_set_sector(qio, parent->bi_iter.bi_sector);

Can new_lim be smaller than the end derived from qio->qcow2->clu_size?
It looks like now we ignore new_lim completely.

>  	}
>  
>  	return qio;
> @@ -4422,16 +4427,18 @@ static inline sector_t get_next_clu(struct qio *qio)
>  
>  static inline void seek_qio_next_clu(struct qio *qio, struct qcow2_map *map)
>  {
> +	sector_t bi_sector;
> +
>  	/*
>  	 * Whole L2 table is unmapped - skip to next l2 table,
>  	 * but only if there is no backing image
>  	 */
>  	if (map && !(map->level & L2_LEVEL) && !qio->qcow2->lower)
> -		qio->bi_iter.bi_sector = get_next_l2(qio);
> +		bi_sector = get_next_l2(qio);
>  	else
> -		qio->bi_iter.bi_sector = get_next_clu(qio);
> +		bi_sector = get_next_clu(qio);
>  
> -	qio->bi_iter.bi_size = qio->qcow2->clu_size;
> +	seek_qio_set_sector(qio, bi_sector);
>  }
>  
>  static struct qio *advance_and_spawn_lower_seek_qio(struct qio *old_qio, u32 size)
> @@ -4567,9 +4574,7 @@ loff_t qcow2_llseek_hole(struct dm_target *ti, loff_t offset, int whence)
>  	if (!qio)
>  		return -ENOMEM;
>  
> -	qio->bi_iter.bi_sector = to_sector(offset);
> -	qio->bi_iter.bi_size = qcow2->clu_size -
> -			       to_bytes(qio->bi_iter.bi_sector) % qcow2->clu_size;
> +	seek_qio_set_sector(qio, to_sector(offset));
>  
>  	ret = qcow2_llseek_hole_qio(qio, whence, &result);
>  	/* In case of error remap ENXIO as it have special meaning for llseek */

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


  reply	other threads:[~2026-08-14  9:55 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-10 12:29 [Devel] [PATCH VZ10 0/6] dm-qcow: lseek improvements Andrey Zhadchenko
2026-08-10 12:29 ` [Devel] [PATCH VZ10 1/6] drivers/md/dm-qcow2: fix lower delta seek window clamp Andrey Zhadchenko
2026-08-10 12:29 ` [Devel] [PATCH VZ10 2/6] drivers/md/dm-qcow2: keep seek parse window within limit Andrey Zhadchenko
2026-08-14  9:55   ` Pavel Tikhomirov [this message]
2026-08-14 10:26     ` Andrey Zhadchenko
2026-08-10 12:29 ` [Devel] [PATCH VZ10 3/6] drivers/md/dm-qcow2: fix seek constant comparison Andrey Zhadchenko
2026-08-10 12:29 ` [Devel] [PATCH VZ10 4/6] drivers/md/dm-qcow2: fix seek skip to the next L2 table Andrey Zhadchenko
2026-08-14 10:25   ` Pavel Tikhomirov
2026-08-14 10:33     ` Andrey Zhadchenko
2026-08-10 12:29 ` [Devel] [PATCH VZ10 5/6] drivers/md/dm-qcow2: scan lower delta in one pass over empty L1 entry Andrey Zhadchenko
2026-08-14 11:09   ` Pavel Tikhomirov
2026-08-14 12:00     ` Andrey Zhadchenko
2026-08-10 12:30 ` [Devel] [PATCH VZ10 6/6] drivers/md/dm-qcow2: seek unallocated L2 entries in one pass within md Andrey Zhadchenko
2026-08-12 12:42   ` Vasileios Almpanis
2026-08-12 12:50     ` Andrey Zhadchenko
2026-08-14 11:55 ` [Devel] [PATCH VZ10 0/6] dm-qcow: lseek improvements Pavel Tikhomirov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=23cafc93-d83e-4cf9-9c7b-4f6e0e317d02@virtuozzo.com \
    --to=ptikhomirov@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox