Skip to content

Commit

Permalink
block: move has_variable_length to BlockLimits
Browse files Browse the repository at this point in the history
At the protocol level, has_variable_length only needs to be true in the
very special case of host CD-ROM drives, so that they do not need an
explicit monitor command to read the new size when a disc is loaded
in the tray.

However, at the format level has_variable_length has to be true for all
raw blockdevs and for all filters, even though in practice the length
depends on the underlying file and thus will not change except in the
case of host CD-ROM drives.

As a first step towards computing an accurate value of has_variable_length,
add the value into the BlockLimits structure and initialize the field
from the BlockDriver.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20230407153303.391121-2-pbonzini@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
bonzini authored and kevmw committed Apr 11, 2023
1 parent 2b1f8fc commit 160a29e
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 1 deletion.
2 changes: 1 addition & 1 deletion block.c
Original file line number Diff line number Diff line change
Expand Up @@ -5849,7 +5849,7 @@ int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs)
if (!drv)
return -ENOMEDIUM;

if (drv->has_variable_length) {
if (bs->bl.has_variable_length) {
int ret = bdrv_co_refresh_total_sectors(bs, bs->total_sectors);
if (ret < 0) {
return ret;
Expand Down
6 changes: 6 additions & 0 deletions block/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
drv->bdrv_aio_preadv ||
drv->bdrv_co_preadv_part) ? 1 : 512;

bs->bl.has_variable_length = drv->has_variable_length;

/* Take some limits from the children as a default */
have_limits = false;
QLIST_FOREACH(c, &bs->children, next) {
Expand All @@ -190,6 +192,10 @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
bdrv_merge_limits(&bs->bl, &c->bs->bl);
have_limits = true;
}

if (c->role & BDRV_CHILD_FILTERED) {
bs->bl.has_variable_length |= c->bs->bl.has_variable_length;
}
}

if (!have_limits) {
Expand Down
8 changes: 8 additions & 0 deletions include/block/block_int-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,14 @@ typedef struct BlockLimits {

/* maximum number of iovec elements */
int max_iov;

/*
* true if the length of the underlying file can change, and QEMU
* is expected to adjust automatically. Mostly for CD-ROM drives,
* whose length is zero when the tray is empty (they don't need
* an explicit monitor command to load the disk inside the guest).
*/
bool has_variable_length;
} BlockLimits;

typedef struct BdrvOpBlocker BdrvOpBlocker;
Expand Down

0 comments on commit 160a29e

Please sign in to comment.