All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: "Denis V. Lunev" <den@openvz.org>
Cc: qemu-devel@nongnu.org, qemu-block@nongnu.org
Subject: Re: [PATCH 1/4] block: notify the parent when a replaced child has a different size
Date: Tue, 3 Nov 2026 11:02:16 +0100	[thread overview]
Message-ID: <aumxKEG88eJAAupA@redhat.com> (raw)
In-Reply-To: <20260812121500.1034178-2-den@openvz.org>

Am 12.08.2026 um 14:14 hat Denis V. Lunev geschrieben:
> bdrv_replace_child_bs() swaps the node a BdrvChild points to without
> telling the parent anything about it, so a parent which tracks the size of
> its child never learns that it changed. Every other way the size of a node
> changes goes through bdrv_co_truncate(), which does notify.
> 
> The device models which care all register the same BlockDevOps hook:
> 
>   virtio-blk  resize_cb = virtio_blk_resize(), ending up in
>               virtio_notify_config()
>   ide/ahci    resize_cb = ide_resize_cb(), refreshing the cached size
>               and the IDENTIFY data
>   scsi-disk   resize_cb = scsi_disk_resize_cb(), reporting
>               CAPACITY DATA HAS CHANGED
>   xen-block   resize_cb = xen_block_resize_cb()
> 
> Only scsi-disk is really hurt by the missing notification, because it is
> the one which validates guest requests against a cached size.
> virtio_blk_sect_range_ok() and ide_sect_range_ok() both call
> blk_get_geometry() for every request, so a missing notification leaves
> those guests with a stale idea of the size but never refuses I/O which the
> node underneath can serve. check_lba_range() compares against
> SCSIDevice.max_lba, filled in by scsi_disk_reset() and updated only by the
> READ CAPACITY(10) and (16) handlers, so with nothing to make the guest
> re-read the capacity every request past the end of the old node is refused
> for the whole life of the device.
> 
> This is reachable with qom-set of the 'drive' property, which is allowed
> on a realized device, and it is silent on the host: out-of-range requests
> are answered by scsi_check_condition() and never reach
> scsi_handle_rw_error(), so there is no BLOCK_IO_ERROR event and io-status
> stays 'ok'. The guest sees ILLEGAL REQUEST / LOGICAL BLOCK ADDRESS OUT OF
> RANGE, which Linux turns into EREMOTEIO for reads as well as writes.
> 
> Emit the notification from bdrv_replace_child_bs(), so that every device
> model gets it through the path it already implements rather than any of
> them being special cased. Send it only when the size really changed, which
> keeps the callback out of the common case of a replacement by an equally
> sized node.
> 
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> ---
>  block.c                      | 13 +++++++++++++
>  include/block/block_int-io.h |  3 +++
>  2 files changed, 16 insertions(+)
> 
> diff --git a/block.c b/block.c
> index f0a6042e61..1fe66caf8d 100644
> --- a/block.c
> +++ b/block.c
> @@ -5524,9 +5524,12 @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs,
>      Transaction *tran = tran_new();
>      g_autoptr(GSList) refresh_list = NULL;
>      BlockDriverState *old_bs = child->bs;
> +    int64_t old_len;
>  
>      GLOBAL_STATE_CODE();
>  
> +    old_len = bdrv_getlength(old_bs);
> +
>      bdrv_ref(old_bs);
>      bdrv_drained_begin(old_bs);
>      bdrv_drained_begin(new_bs);

bdrv_drained_begin() involves nested event loops. Can't old_len become
stale here? It would feel safer to query it after draining.

> @@ -5542,6 +5545,16 @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs,
>      tran_finalize(tran, ret);
>  
>      bdrv_graph_wrunlock();
> +
> +    /* A parent caching the child size has to learn that it changed */
> +    if (ret == 0) {
> +        int64_t new_len = bdrv_getlength(new_bs);
> +
> +        if (new_len >= 0 && new_len != old_len) {
> +            bdrv_parent_cb_resize(new_bs);

This notifies other parents of the new node as well even though nothing
changed for them.

Especially since you already query old_len/new_len to avoid unnecessary
notifications, we should probably call only child->klass->resize(child)
through a coroutine wrapper here to notify only the BdrvChild that we
actually changed.

> +        }
> +    }
> +
>      bdrv_drained_end(old_bs);
>      bdrv_drained_end(new_bs);
>      bdrv_unref(old_bs);

Kevin



  parent reply	other threads:[~2026-11-03 10:02 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-12 12:14 [PATCH 0/4] block, scsi-disk: honour a size change on child replacement Denis V. Lunev
2026-08-12 12:14 ` [PATCH 1/4] block: notify the parent when a replaced child has a different size Denis V. Lunev
2026-08-26 10:53   ` Philippe Mathieu-Daudé
2026-11-03 10:02   ` Kevin Wolf [this message]
2026-11-04 14:50     ` Denis V. Lunev
2026-11-05 15:41       ` Kevin Wolf
2026-11-05 15:50         ` Denis V. Lunev
2026-08-12 12:14 ` [PATCH 2/4] scsi-disk: refresh the cached capacity from the resize callback Denis V. Lunev
2026-08-26 10:45   ` Philippe Mathieu-Daudé
2026-08-12 12:14 ` [PATCH 3/4] tests/qtest/virtio-scsi: cover a replacement that changes the size Denis V. Lunev
2026-08-26 10:46   ` Philippe Mathieu-Daudé
2026-08-12 12:15 ` [PATCH 4/4] tests/qemu-iotests/qom-set-drive: replace with a differently sized node Denis V. Lunev
2026-08-26 10:47   ` Philippe Mathieu-Daudé
2026-08-19  9:36 ` [PATCH 0/4] block, scsi-disk: honour a size change on child replacement Denis V. Lunev
2026-08-26 10:22 ` Denis V. Lunev
2026-09-02 15:39 ` Denis V. Lunev
2026-09-09 18:08   ` Denis V. Lunev
2026-09-21 19:39 ` Denis V. Lunev
2026-09-29 15:42 ` Denis V. Lunev
2026-10-05  8:58 ` Denis V. Lunev
2026-10-30 11:08 ` Denis V. Lunev
2026-11-02 16:30   ` Eric Blake
2026-11-02 16:32     ` Denis V. Lunev

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=aumxKEG88eJAAupA@redhat.com \
    --to=kwolf@redhat.com \
    --cc=den@openvz.org \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.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.