Some features, like I/O throttling, are implemented outside block-backend.c, but still want to keep BlockBackends in a list. In order to avoid exposing the whole struct layout in the public header file, this patch introduces an embedded public struct where list entry structs can be added and a pair of functions to convert between BlockBackend and BlockBackendPublic.
Signed-off-by: Kevin Wolf <kw...@redhat.com> --- block/block-backend.c | 17 +++++++++++++++++ include/sysemu/block-backend.h | 9 +++++++++ 2 files changed, 26 insertions(+) diff --git a/block/block-backend.c b/block/block-backend.c index df8f717..4394950 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -33,6 +33,7 @@ struct BlockBackend { DriveInfo *legacy_dinfo; /* null unless created by drive_new() */ QTAILQ_ENTRY(BlockBackend) link; /* for block_backends */ QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */ + BlockBackendPublic public; void *dev; /* attached device model, if any */ /* TODO change to DeviceState when all users are qdevified */ @@ -410,6 +411,22 @@ BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo) } /* + * Returns a pointer to the publicly accessible fields of @blk. + */ +BlockBackendPublic *blk_get_public(BlockBackend *blk) +{ + return &blk->public; +} + +/* + * Returns a BlockBackend given the associated @public fields. + */ +BlockBackend *blk_by_public(BlockBackendPublic *public) +{ + return container_of(public, BlockBackend, public); +} + +/* * Disassociates the currently associated BlockDriverState from @blk. */ void blk_remove_bs(BlockBackend *blk) diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index d839bff..bb4ff6f 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -59,6 +59,12 @@ typedef struct BlockDevOps { void (*resize_cb)(void *opaque); } BlockDevOps; +/* This struct is embedded in (the private) BlockBackend struct and contains + * fields that must be public. This is in particular for QLIST_ENTRY() and + * friends so that BlockBackends can be kept in lists outside block-backend.c */ +typedef struct BlockBackendPublic { +} BlockBackendPublic; + BlockBackend *blk_new(Error **errp); BlockBackend *blk_new_with_bs(Error **errp); BlockBackend *blk_new_open(const char *filename, const char *reference, @@ -74,6 +80,9 @@ BlockDriverState *blk_next_root_bs(BlockDriverState *bs); bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp); void monitor_remove_blk(BlockBackend *blk); +BlockBackendPublic *blk_get_public(BlockBackend *blk); +BlockBackend *blk_by_public(BlockBackendPublic *public); + BlockDriverState *blk_bs(BlockBackend *blk); void blk_remove_bs(BlockBackend *blk); void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs); -- 1.8.3.1