All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
From: Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>
Subject: Re: [Devel] [PATCH VZ10 v2 04/10] drivers/md/dm-qcow2: never trigger COW or allocation on discard
Date: Wed, 19 Aug 2026 11:05:02 +0000	[thread overview]
Message-ID: <178713750239.404937.3004358185512206751.b4-review@b4> (raw)
In-Reply-To: <20260812202005.288994-5-andrey.zhadchenko@virtuozzo.com>

> In handle_metadata() the partial cluster discard fallback is checked
> only after the COW branches. As a result a discard, whose range
> touches a shared (snapshot or compressed) cluster or crosses an
> unmapped unit border over a backing file, is routed into the data COW
> machinery. COW then tries to submit the discard payload as a data
> write, but discard qios carry no bvec array: the iov_iter is built
> from garbage, which triggers the WARN_ON() in __submit_rw_mapped()
> and writes random kernel memory into the COW'ed cluster.
> 
> Check for discard before the COW branches: discard is advisory and
> carries no data, so it must never COW or allocate. End discard
> early while handling metadata if possible. Otherwise do discard
> operations before COWs.
> 
> Feature: dm-qcow2: block device over QCOW2 files driver
> https://virtuozzo.atlassian.net/browse/VSTOR-139406
> Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko@virtuozzo.com>
>
> diff --git a/drivers/md/dm-qcow2-map.c b/drivers/md/dm-qcow2-map.c
> index 8d2c4e78a4c5..dcc65735881d 100644
> --- a/drivers/md/dm-qcow2-map.c
> +++ b/drivers/md/dm-qcow2-map.c
> @@ -3431,9 +3431,18 @@ static int handle_metadata(struct qcow2 *qcow2, struct qio **qio,
>  		/* Nothing to COW or L1 is mapped exactly once */
>  		qio_endio(*qio);
>  		ret = 0;
> -	} else if (unlikely(op_is_discard((*qio)->bi_op)) &&
> -		   qio_discard_updates_metadata(qcow2, *qio, map)) {
> -		ret = prepare_cluster_discard(qcow2, qio, map);
> +	} else if (unlikely(op_is_discard((*qio)->bi_op))) {
> +		/*
> +		 * Discard carries no data and advisory. If it does not
NIT: no data and is advisory
> +		 * trigger metadata changes or to-be-discarded cluster
> +		 * is not present, end early.
> +		 */
> +		if (qio_discard_updates_metadata(qcow2, *qio, map)) {
> +			ret = prepare_cluster_discard(qcow2, qio, map);
> +		} else if (!map->data_clu_alloced || map->clu_is_cow) {
> +			qio_endio(*qio);
> +			ret = 0;
> +		}
>  	} else if (write &&
>  		   (!qio_is_fully_alloced(qcow2, *qio, map) || map->clu_is_cow)) {
>  		if (map->clu_is_cow) {
> @@ -3449,13 +3458,6 @@ static int handle_metadata(struct qcow2 *qcow2, struct qio **qio,
>  			 */
>  			map->backing_file_cow = true;
>  			ret = prepare_l1l2_replace(qcow2, *qio, map);
> -		} else if (unlikely(op_is_discard((*qio)->bi_op) &&
> -				    (map->level & L2_LEVEL))) {
> -			if (!map->data_clu_alloced) {
> -				qio_endio(*qio);
> -				ret = 0;
> -			}
> -			/* Otherwise issue_discard(). */
>  		} else {
>  			/* Wants L1 or L2 entry allocation */
>  			ret = prepare_l1l2_allocation(qcow2, *qio, map);
> @@ -3569,8 +3571,8 @@ static void process_one_qio(struct qcow2 *qcow2, struct qio *qio)
>  
>  	write = op_is_write(qio->bi_op);
>  
> -	/* Discard with prepared metadata update, see prepare_cluster_discard() */
> -	if (unlikely(qio->flags & QIO_IS_DISCARD_FL)) {
> +	/* Process discard early. Don't do COW just to discard */
> +	if (unlikely(op_is_discard(qio->bi_op))) {
>  		issue_discard(&map, qio);
>  		return;
>  	}
> @@ -3588,8 +3590,6 @@ static void process_one_qio(struct qcow2 *qcow2, struct qio *qio)
>  			submit_read_whole_cow_clu(&map, qio);
>  		else if (unlikely(map.clu_is_cow || map.backing_file_cow))
>  			submit_read_sliced_cow_clu(&map, qio);
> -		else if (unlikely(op_is_discard(qio->bi_op)))
> -			issue_discard(&map, qio);
>  		else
>  			perform_rw_mapped(&map, qio);
>  	}
side note: for single-bio discard requests bi_io_vec is actually
a garbage pointer set in prepare_one_embedded_qio in the else 
branch. We set bvec to rq->bio->bi_inline_vecs which is never null its a
flexible array. I think we guard in all places for discards based on op so
we don't meet any issue but just wanted to point it out.

-- 
Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>

  reply	other threads:[~2026-08-19 11:05 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-12 20:19 [Devel] [PATCH VZ10 v2 00/10] dm-qcow2: improve discard and read-only merge handling Andrey Zhadchenko
2026-08-12 20:19 ` [Devel] [PATCH VZ10 v2 01/10] drivers/md/dm-qcow2: fix revert_cluster_alloc() for ext_l2 case Andrey Zhadchenko
2026-08-19 10:27   ` Pavel Tikhomirov
2026-08-12 20:19 ` [Devel] [PATCH VZ10 v2 02/10] drivers/md/dm-qcow2: generalize COW index update machinery Andrey Zhadchenko
2026-08-19 11:05   ` Vasileios Almpanis
2026-08-12 20:19 ` [Devel] [PATCH VZ10 v2 03/10] drivers/md/dm-qcow2: update metadata on whole cluster discard Andrey Zhadchenko
2026-08-19 10:43   ` Pavel Tikhomirov
2026-08-12 20:19 ` [Devel] [PATCH VZ10 v2 04/10] drivers/md/dm-qcow2: never trigger COW or allocation on discard Andrey Zhadchenko
2026-08-19 11:05   ` Vasileios Almpanis [this message]
2026-08-12 20:20 ` [Devel] [PATCH VZ10 v2 05/10] drivers/md/dm-qcow2: set L2_READS_ALL_ZEROES after some discards Andrey Zhadchenko
2026-08-19 11:05   ` Pavel Tikhomirov
2026-08-20  9:04     ` Andrey Zhadchenko
2026-08-20 10:21       ` Pavel Tikhomirov
2026-08-12 20:20 ` [Devel] [PATCH VZ10 v2 06/10] drivers/md/dm-qcow2: update metadata on subclusters discard Andrey Zhadchenko
2026-08-12 20:20 ` [Devel] [PATCH VZ10 v2 07/10] drivers/md/dm-qcow2: unmap cluster when discard clears last allocated subclusters Andrey Zhadchenko
2026-08-12 20:20 ` [Devel] [PATCH VZ10 v2 08/10] drivers/md/dm-qcow2: do discards during backward merge only for writable image Andrey Zhadchenko
2026-08-12 20:20 ` [Devel] [PATCH VZ10 v2 09/10] drivers/md/dm-qcow2: allow shared L1 entries during merge from RO image Andrey Zhadchenko
2026-08-21 10:43   ` Pavel Tikhomirov
2026-08-21 10:44     ` Pavel Tikhomirov
2026-08-12 20:20 ` [Devel] [PATCH VZ10 v2 10/10] drivers/md/dm-qcow2: respect zeroes during merge Andrey Zhadchenko
2026-08-19 11:05 ` [Devel] [PATCH VZ10 v2 00/10] dm-qcow2: improve discard and read-only merge handling Vasileios Almpanis
2026-08-21 11:38 ` 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=178713750239.404937.3004358185512206751.b4-review@b4 \
    --to=vasileios.almpanis@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.