From: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
To: no-reply@sashiko.virtuozzo.com, andrey.zhadchenko@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 13:45:00 +0100 [thread overview]
Message-ID: <0002f039-6cca-4e75-92ea-f74e2b924e94@virtuozzo.com> (raw)
In-Reply-To: <010701a1c03aace3-cc8841e4-a3ff-4b96-853e-e743fb7abea9-000000@eu-central-1.amazonses.com>
>> @@ -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?
Fixed in the previous fixes. The redirty is no longer gated on
wants_suspend.
qcow2_flush_deferred_activity() sets md_wb_no_retry for its last
iteration on
every caller (suspend, merge complete/error, tgt destroy). The md wb qio
drops its inflight ref only after do_md_page_write_complete(), so the
retry's
completion runs while the flag is still set. A page that fails again is
not redirtied,
and the timer is not re-armed before qcow2_destroy().
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
next prev parent reply other threads:[~2026-11-09 12:46 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
2026-11-09 12:45 ` Alexander Ivanov [this message]
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=0002f039-6cca-4e75-92ea-f74e2b924e94@virtuozzo.com \
--to=alexander.ivanov@virtuozzo.com \
--cc=andrey.zhadchenko@virtuozzo.com \
--cc=devel@openvz.org \
--cc=no-reply@sashiko.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