From: Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>
Subject: Re: [Devel] [PATCH VZ10 v2 02/10] drivers/md/dm-qcow2: generalize COW index update machinery
Date: Wed, 19 Aug 2026 11:05:02 +0000 [thread overview]
Message-ID: <178713750239.404937.136053867657961562.b4-review@b4> (raw)
In-Reply-To: <20260812202005.288994-3-andrey.zhadchenko@virtuozzo.com>
> The two-stage L1/L2 entry update pipeline is not COW-specific:
> backward merge already uses it to zero L2 entries, and upcoming
> discard support will be the third user. Rename it to reflect
> what it does.
>
> No functional changes.
>
> 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 2cd8e174049f..08d46eb177dd 100644
> --- a/drivers/md/dm-qcow2-map.c
> +++ b/drivers/md/dm-qcow2-map.c
> @@ -2579,10 +2579,10 @@ static int prepare_l1l2_allocation(struct qcow2 *qcow2, struct qio *qio,
> * we have to wait all previous READs. We do that around
> * index wb. See md->wpc_noread_count update details.
> */
> -static int prepare_l_entry_cow(struct qcow2 *qcow2, struct qcow2_map *map,
> - struct qio *qio, struct md_page *md,
> - u32 index_in_page, loff_t cow_clu_pos,
> - loff_t cow_clu_end, u8 cow_level)
> +static int prepare_l_entry_replace(struct qcow2 *qcow2, struct qcow2_map *map,
> + struct qio *qio, struct md_page *md,
> + u32 index_in_page, loff_t unuse_clu_pos,
> + loff_t unuse_clu_end, u8 lx_level)
> {
> struct lock_desc *lockd = NULL;
> struct qio_ext *ext;
> @@ -2591,9 +2591,9 @@ static int prepare_l_entry_cow(struct qcow2 *qcow2, struct qcow2_map *map,
> return -ENOMEM;
>
> ext = qio->ext;
> - ext->cow_clu_pos = cow_clu_pos;
> - ext->cow_clu_end = cow_clu_end;
> - ext->cow_level = cow_level;
> + ext->unuse_clu_pos = unuse_clu_pos;
> + ext->unuse_clu_end = unuse_clu_end;
> + ext->lx_level = lx_level;
>
> spin_lock_irq(&qcow2->md_pages_lock);
> if (!md->lockd) {
> @@ -2614,23 +2614,23 @@ static int prepare_l_entry_cow(struct qcow2 *qcow2, struct qcow2_map *map,
> return 1;
> }
>
> -static int prepare_l1l2_cow(struct qcow2 *qcow2, struct qio *qio,
> - struct qcow2_map *map)
> +static int prepare_l1l2_replace(struct qcow2 *qcow2, struct qio *qio,
> + struct qcow2_map *map)
> {
> if (WARN_ON_ONCE(!(map->level & L1_LEVEL)))
> return -EIO; /* Sanity check: L1 must be cached */
>
> if (!(map->level & L2_LEVEL)) {
> - return prepare_l_entry_cow(qcow2, map, qio, map->l1.md,
> - map->l1.index_in_page,
> - map->cow_clu_pos,
> - map->cow_clu_end, L1_LEVEL);
> + return prepare_l_entry_replace(qcow2, map, qio, map->l1.md,
> + map->l1.index_in_page,
> + map->cow_clu_pos,
> + map->cow_clu_end, L1_LEVEL);
> }
>
> - return prepare_l_entry_cow(qcow2, map, qio, map->l2.md,
> - map->l2.index_in_page,
> - map->cow_clu_pos,
> - map->cow_clu_end, L2_LEVEL);
> + return prepare_l_entry_replace(qcow2, map, qio, map->l2.md,
> + map->l2.index_in_page,
> + map->cow_clu_pos,
> + map->cow_clu_end, L2_LEVEL);
> }
>
> static void backward_merge_write_complete(struct qcow2_target *tgt, struct qio *unused,
> @@ -2648,7 +2648,7 @@ static void backward_merge_write_complete(struct qcow2_target *tgt, struct qio *
> WARN_ON_ONCE(qio->flags & QIO_IS_DISCARD_FL);
> qio->flags |= QIO_IS_DISCARD_FL;
>
> - qio->queue_list_id = QLIST_COW_INDEXES;
> + qio->queue_list_id = QLIST_INDEXES_WRITE;
> qcow2_dispatch_qios(qcow2, qio, NULL);
> }
>
> @@ -2704,7 +2704,7 @@ static int prepare_backward_merge(struct qcow2 *qcow2, struct qio **qio,
> if (!op_is_write((*qio)->bi_op)) {
> /*
> * READ qio may data may be contained in several deltas.
> - * We can't read lower delta after prepare_l1l2_cow()
> + * We can't read lower delta after prepare_l1l2_replace()
> * prepares us.
> */
> aux_qio = qcow2_alloc_qio(qcow2->tgt->qio_pool, true);
> @@ -2725,10 +2725,10 @@ static int prepare_backward_merge(struct qcow2 *qcow2, struct qio **qio,
> }
>
> /*
> - * Mark as COW, as this completely defers any parallel qios.
> - * @qio is COW status holder.
> + * Lock the entry, as this completely defers any parallel qios.
> + * @qio is the lock holder.
> */
> - ret = prepare_l1l2_cow(qcow2, *qio, map);
> + ret = prepare_l1l2_replace(qcow2, *qio, map);
> if (ret < 0) {
> (*qio)->bi_status = errno_to_blk_status(ret);
> goto endio;
> @@ -2736,13 +2736,13 @@ static int prepare_backward_merge(struct qcow2 *qcow2, struct qio **qio,
>
> if (!map->clu_is_cow) {
> /* Forced set these to unuse them after discard */
> - (*qio)->ext->cow_clu_pos = map->data_clu_pos;
> - (*qio)->ext->cow_clu_end = map->data_clu_pos + qcow2->clu_size;
> + (*qio)->ext->unuse_clu_pos = map->data_clu_pos;
> + (*qio)->ext->unuse_clu_end = map->data_clu_pos + qcow2->clu_size;
> }
>
> return 1;
> endio:
> - qio_endio(*qio); /* Breaks COW set in prepare_l1l2_cow() */
> + qio_endio(*qio); /* Releases the lock set in prepare_l1l2_replace() */
> return 0;
> }
>
> @@ -3348,7 +3348,7 @@ static int handle_metadata(struct qcow2 *qcow2, struct qio **qio,
> (!qio_is_fully_alloced(qcow2, *qio, map) || map->clu_is_cow)) {
> if (map->clu_is_cow) {
> /* COW to compressed or shared with snapshot cluster */
> - ret = prepare_l1l2_cow(qcow2, *qio, map);
> + ret = prepare_l1l2_replace(qcow2, *qio, map);
> } else if ((map->level & L2_LEVEL) &&
> qio_border_is_inside_unmapped_unit(qcow2, *qio, map) &&
> maybe_mapped_in_lower_delta(qcow2, *qio)) {
> @@ -3358,7 +3358,7 @@ static int handle_metadata(struct qcow2 *qcow2, struct qio **qio,
> * snapshots). Here is data COW on L2_LEVEL.
> */
> map->backing_file_cow = true;
> - ret = prepare_l1l2_cow(qcow2, *qio, map);
> + 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) {
> @@ -3837,7 +3837,7 @@ static void cow_data_write_endio(struct qcow2_target *tgt, struct qio *unused,
> qio->bi_status = bi_status;
> qio_endio(qio);
> } else {
> - qio->queue_list_id = QLIST_COW_INDEXES;
> + qio->queue_list_id = QLIST_INDEXES_WRITE;
> qcow2_dispatch_qios(qcow2, qio, NULL);
> }
> }
> @@ -3885,7 +3885,7 @@ static void sliced_cow_data_write_complete(struct qcow2_target *tgt, struct qio
> qio->bi_status = bi_status;
> qio_endio(qio);
> } else {
> - qio->queue_list_id = QLIST_COW_INDEXES;
> + qio->queue_list_id = QLIST_INDEXES_WRITE;
> qcow2_dispatch_qios(qcow2, qio, NULL);
> }
> }
> @@ -3919,7 +3919,7 @@ static void process_cow_data_write(struct qcow2 *qcow2, struct list_head *cow_li
> ext = qio->ext;
>
> if (ext->only_set_ext_l2) {
> - WARN_ON_ONCE(ext->cow_level != L2_LEVEL);
> + WARN_ON_ONCE(ext->lx_level != L2_LEVEL);
> pos = ext->allocated_clu_pos;
> goto submit;
> }
> @@ -3938,14 +3938,14 @@ static void process_cow_data_write(struct qcow2 *qcow2, struct list_head *cow_li
> ext->allocated_clu_pos = pos;
> ext->cleanup_mask |= FREE_ALLOCATED_CLU;
> submit:
> - if (ext->cow_level == L2_LEVEL)
> + if (ext->lx_level == L2_LEVEL)
> submit_sliced_cow_data_write(qcow2, qio, pos);
> else
> submit_cow_data_write(qcow2, qio, pos);
> }
> }
>
> -static void process_cow_indexes_write(struct qcow2 *qcow2,
> +static void process_indexes_write(struct qcow2 *qcow2,
> struct list_head *qio_list)
> {
NIT: qvec is unused. Its only set here, so lets just drop it since we touch this
function.
--
Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>
next prev parent 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 [this message]
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
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.136053867657961562.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.