This enum indicates whether a file is stored on a rotating disk or a solid-state drive. Drivers report it via the .bdrv_get_info() callback, and if they do not, the global bdrv_get_info() implementation automatically takes it from bs->file or bs->backing, if available.
On the QAPI side, we report the value as part of the ImageInfo structure. Signed-off-by: Max Reitz <mre...@redhat.com> --- qapi/block-core.json | 19 ++++++++++++++++++- include/block/block.h | 7 +++++++ block.c | 20 +++++++++++++++++++- block/qapi.c | 3 +++ 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 3e4042be7f..80b9f2a69c 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -130,6 +130,20 @@ 'luks': 'QCryptoBlockInfoLUKS' } } +## +# @ImageRotationalInfo: +# +# Indicates whether an image is stored on a rotating disk or not. +# +# @solid-state: Image is stored on a solid-state drive +# +# @rotating: Image is stored on a rotating disk +# +# Since: 4.1 +## +{ 'enum': 'ImageRotationalInfo', + 'data': [ 'solid-state', 'rotating' ] } + ## # @ImageInfo: # @@ -161,6 +175,9 @@ # # @backing-image: info of the backing image (since 1.6) # +# @rotational: indicates whether the image is stored on a rotating +# disk or not (since 4.1) +# # @format-specific: structure supplying additional format-specific # information (since 1.7) # @@ -173,7 +190,7 @@ '*cluster-size': 'int', '*encrypted': 'bool', '*compressed': 'bool', '*backing-filename': 'str', '*full-backing-filename': 'str', '*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'], - '*backing-image': 'ImageInfo', + '*backing-image': 'ImageInfo', '*rotational': 'ImageRotationalInfo', '*format-specific': 'ImageInfoSpecific' } } ## diff --git a/include/block/block.h b/include/block/block.h index 531cf595cf..dc0f8a4671 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -31,6 +31,13 @@ typedef struct BlockDriverInfo { * True if this block driver only supports compressed writes */ bool needs_compressed_writes; + + /* + * Indicates whether this image file is stored on a rotating disk + * or a solid-state drive. + */ + bool has_rotational_info; + ImageRotationalInfo rotational_info; } BlockDriverInfo; typedef struct BlockFragInfo { diff --git a/block.c b/block.c index 4c3902508d..e6b2d6d23b 100644 --- a/block.c +++ b/block.c @@ -4950,6 +4950,8 @@ void bdrv_get_backing_filename(BlockDriverState *bs, int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) { BlockDriver *drv = bs->drv; + int ret; + /* if bs->drv == NULL, bs is closed, so there's nothing to do here */ if (!drv) { return -ENOMEDIUM; @@ -4960,8 +4962,24 @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) } return -ENOTSUP; } + memset(bdi, 0, sizeof(*bdi)); - return drv->bdrv_get_info(bs, bdi); + ret = drv->bdrv_get_info(bs, bdi); + if (ret < 0) { + return ret; + } + + if (!bdi->has_rotational_info && (bs->file || bs->backing)) { + BlockDriverState *child = bs->file ? bs->file->bs : bs->backing->bs; + BlockDriverInfo child_bdi; + + if (bdrv_get_info(child, &child_bdi) >= 0) { + bdi->rotational_info = child_bdi.rotational_info; + bdi->has_rotational_info = child_bdi.has_rotational_info; + } + } + + return 0; } ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs, diff --git a/block/qapi.c b/block/qapi.c index 0c13c86f4e..48ebfbdcc1 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -286,6 +286,9 @@ void bdrv_query_image_info(BlockDriverState *bs, } info->dirty_flag = bdi.is_dirty; info->has_dirty_flag = true; + + info->rotational = bdi.rotational_info; + info->has_rotational = bdi.has_rotational_info; } info->format_specific = bdrv_get_specific_info(bs, &err); if (err) { -- 2.21.0