From: no-reply@sashiko.virtuozzo.com
To: andrey.zhadchenko@virtuozzo.com,
Alexander Ivanov <alexander.ivanov@virtuozzo.com>
Cc: devel@openvz.org
Subject: Re: [Devel] [PATCH hci-8.1 v10 09/10] dm-qcow2: retry R1/R2 writeback that failed with ENOSPC
Date: Mon, 9 Nov 2026 12:13:53 +0000 [thread overview]
Message-ID: <010701a1c03aace3-cc8841e4-a3ff-4b96-853e-e743fb7abea9-000000@eu-central-1.amazonses.com> (raw)
In-Reply-To: <20261109115856.1362416-10-alexander.ivanov@virtuozzo.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] dm-qcow2: ENOSPC redirty re-arms slow_wb_timer before qcow2_destroy()
--
Subject: Re: [PATCH] dm-qcow2: retry R1/R2 writeback that failed with ENOSPC
commit d478597d2191e210e3a91e1dd7282242553b0e83
Author: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
dm-qcow2: retry R1/R2 writeback that failed with ENOSPC
This patch redirties an R1/R2 metadata page when its writeback fails with
-ENOSPC, so the slow writeback timer retries it. It also passes the errno
of a failed metadata write through complete_metadata_writeback() instead of
converting it to -EIO.
> diff --git a/drivers/md/dm-qcow2-map.c b/drivers/md/dm-qcow2-map.c
> --- a/drivers/md/dm-qcow2-map.c
> +++ b/drivers/md/dm-qcow2-map.c
[ ... ]
> @@ -1357,6 +1357,8 @@ static void clear_writeback_status(struct qcow2 *qcow2, struct md_page *md,
> * so here we care about R1R2 only.
> */
> md->status |= MD_WRITEBACK_ERROR;
> + if (ret == -ENOSPC && !READ_ONCE(qcow2->tgt->wants_suspend))
> + qcow2_md_make_dirty(qcow2, md, true);
[Severity: High]
Can this redirty re-arm slow_wb_timer on a path that frees the qcow2
right afterwards?
The redirty is gated only on wants_suspend. Only qcow2_presuspend() sets
wants_suspend, but qcow2_flush_deferred_activity() is also called from
paths where it is false.
One example is qcow2_merge_backward_complete():
qcow2_flush_deferred_activity(tgt, qcow2); /* Delayed md pages */
qcow2->lower = NULL;
...
qcow2_destroy(qcow2);
qcow2_flush_deferred_activity() runs only two iterations. If the
underlying fs is still full, the sequence is:
iteration 0: R1/R2 write fails with -ENOSPC, page is redirtied
iteration 1: timer handler fires, the retry fails with -ENOSPC again
clear_writeback_status()
qcow2_md_make_dirty(qcow2, md, true)
list_add_tail(&md->wb_link, &qcow2->slow_wb_batch_list)
mod_timer(&qcow2->slow_wb_timer, jiffies + WB_TIMEOUT_JI)
After the last iteration nothing drains the page or the timer.
qcow2_destroy() then only does:
WARN_ON(!list_empty(&qcow2->paused_qios) ||
!list_empty(&qcow2->wb_batch_list) ||
!list_empty(&qcow2->slow_wb_batch_list) ||
timer_pending(&qcow2->slow_wb_timer));
qcow2_free_md_pages_tree(&qcow2->md_pages);
...
kfree(qcow2);
It does not call timer_shutdown_sync() or timer_delete_sync(). Could
qcow2_slow_wb_timer_fn() then run on the freed struct qcow2 when the timer
fires, up to WB_TIMEOUT_JI later? It does timer_container_of(),
list_splice_init() and queue_work() on that memory. The WARN_ON would also
trigger.
The merge-error path in qcow2_merge_backward_work() calls
qcow2_flush_deferred_activity(tgt, lower) with wants_suspend false in the
same way. There the ENOSPC page is left redirtied and the timer re-armed
on an image that is still live but no longer being merged.
qcow2_tgt_destroy() also flushes and then calls qcow2_destroy(). It looks
protected only if presuspend ran first.
Before this patch, the completion handler never re-armed the timer after a
failed R1/R2 write, so this exposure is new.
The commit message says "A page that still fails then is not redirtied, as
wants_suspend is set, so nothing is left pending on a suspended device".
Is that true outside the suspend flush? As described above, the claim
holds only when wants_suspend is set.
Should the redirty be limited to cases where the flush cannot leave the
timer armed, or should the flush and destroy paths cancel the timer and
drain slow_wb_batch_list before the qcow2 is freed?
--
Sashiko AI review · https://sashiko.vzint.dev/#/patchset/20261109115856.1362416-1-alexander.ivanov@virtuozzo.com?part=9
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
next prev parent reply other threads:[~2026-11-09 12:15 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 11:58 [Devel] [PATCH hci-8.1 v10 00/10] dm-qcow2: truncate unused tail of image on suspend Alexander Ivanov
2026-11-09 11:58 ` [Devel] [PATCH hci-8.1 v10 01/10] dm-qcow2: add qcow2_md_page_read_sync() helper Alexander Ivanov
2026-11-09 12:03 ` no-reply
2026-11-09 11:58 ` [Devel] [PATCH hci-8.1 v10 02/10] dm-qcow2: drop duplicate prefix from QC_ERR/QC_INFO messages Alexander Ivanov
2026-11-09 12:02 ` no-reply
2026-11-09 11:58 ` [Devel] [PATCH hci-8.1 v10 03/10] dm-qcow2: extend the file for a new refblock in allocate_cluster() Alexander Ivanov
2026-11-09 12:03 ` no-reply
2026-11-09 11:58 ` [Devel] [PATCH hci-8.1 v10 04/10] dm-qcow2: complete wbd before ending the data qio Alexander Ivanov
2026-11-09 12:06 ` no-reply
2026-11-09 11:58 ` [Devel] [PATCH hci-8.1 v10 05/10] dm-qcow2: flush lower md before clearing dirty bit on merge failure Alexander Ivanov
2026-11-09 12:05 ` no-reply
2026-11-09 11:58 ` [Devel] [PATCH hci-8.1 v10 06/10] dm-qcow2: keep the dirty bit of an image that needs check Alexander Ivanov
2026-11-09 12:06 ` no-reply
2026-11-09 11:58 ` [Devel] [PATCH hci-8.1 v10 07/10] dm-qcow2: flag the image for check if reftable relocation fails late Alexander Ivanov
2026-11-09 12:09 ` no-reply
2026-11-09 12:25 ` Alexander Ivanov
2026-11-09 11:58 ` [Devel] [PATCH hci-8.1 v10 08/10] dm-qcow2: leak clusters allocated for a failed L1/L2 writeback Alexander Ivanov
2026-11-09 12:09 ` no-reply
2026-11-09 12:41 ` Alexander Ivanov
2026-11-09 11:58 ` [Devel] [PATCH hci-8.1 v10 09/10] dm-qcow2: retry R1/R2 writeback that failed with ENOSPC Alexander Ivanov
2026-11-09 12:13 ` no-reply [this message]
2026-11-09 12:45 ` Alexander Ivanov
2026-11-09 11:58 ` [Devel] [PATCH hci-8.1 v10 10/10] dm-qcow2: truncate unused tail of image on suspend Alexander Ivanov
2026-11-09 12:14 ` no-reply
2026-11-09 13:26 ` Alexander Ivanov
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=010701a1c03aace3-cc8841e4-a3ff-4b96-853e-e743fb7abea9-000000@eu-central-1.amazonses.com \
--to=no-reply@sashiko.virtuozzo.com \
--cc=alexander.ivanov@virtuozzo.com \
--cc=andrey.zhadchenko@virtuozzo.com \
--cc=devel@openvz.org \
/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.