Max Reitz <mre...@redhat.com> writes: > On 13.09.2014 17:00, Markus Armbruster wrote: >> A block device consists of a frontend device model and a backend. >> >> A block backend has a tree of block drivers doing the actual work. >> The tree is managed by the block layer. >> >> We currently use a single abstraction BlockDriverState both for tree >> nodes and the backend as a whole. Drawbacks: >> >> * Its API includes both stuff that makes sense only at the block >> backend level (root of the tree) and stuff that's only for use >> within the block layer. This makes the API bigger and more complex >> than necessary. Moreover, it's not obvious which interfaces are >> meant for device models, and which really aren't. >> >> * Since device models keep a reference to their backend, the backend >> object can't just be destroyed. But for media change, we need to >> replace the tree. Our solution is to make the BlockDriverState >> generic, with actual driver state in a separate object, pointed to >> by member opaque. That lets us replace the tree by deinitializing >> and reinitializing its root. This special need of the root makes >> the data structure awkward everywhere in the tree. >> >> The general plan is to separate the APIs into "block backend", for use >> by device models, monitor and whatever other code dealing with block >> backends, and "block driver", for use by the block layer and whatever >> other code (if any) dealing with trees and tree nodes. >> >> Code dealing with block backends, device models in particular, should >> become completely oblivious of BlockDriverState. This should let us >> clean up both APIs, and the tree data structures. >> >> This commit is a first step. It creates a minimal "block backend" >> API: type BlockBackend and functions to create, destroy and find them. >> >> BlockBackend objects are created and destroyed exactly when root >> BlockDriverState objects are created and destroyed. "Root" in the >> sense of "in bdrv_states". They're not yet used for anything; that'll >> come shortly. >> >> BlockBackend is reference-counted. Its reference count never exceeds >> one so far, but that's going to change. >> >> Signed-off-by: Markus Armbruster <arm...@redhat.com> >> --- >> block.c | 3 +- >> block/Makefile.objs | 2 +- >> block/block-backend.c | 119 >> +++++++++++++++++++++++++++++++++++++++++ >> blockdev.c | 21 +++++++- >> hw/block/xen_disk.c | 11 ++++ >> include/qemu/typedefs.h | 1 + >> include/sysemu/block-backend.h | 26 +++++++++ >> qemu-img.c | 70 +++++++++++++++++++++--- >> qemu-io.c | 8 +++ >> qemu-nbd.c | 5 +- >> 10 files changed, 253 insertions(+), 13 deletions(-) >> create mode 100644 block/block-backend.c >> create mode 100644 include/sysemu/block-backend.h > > [snip] > >> diff --git a/qemu-img.c b/qemu-img.c >> index 58d59d0..acb272e 100644 >> --- a/qemu-img.c >> +++ b/qemu-img.c > > [snip] > >> @@ -942,6 +952,7 @@ static int check_empty_sectors(BlockDriverState *bs, >> int64_t sect_num, >> static int img_compare(int argc, char **argv) >> { >> const char *fmt1 = NULL, *fmt2 = NULL, *cache, *filename1, *filename2; >> + BlockBackend *blk1, *blk2; >> BlockDriverState *bs1, *bs2; > > By initializing all of these to NULL we could remove out1, out2 and > out3, and just always go to out. But of course it's not wrong this > way.
Indeed, and I actually like that way to free stuff on error. But it would be yet another preliminary cleanup patch. If you guys want it, I'll cook it up. > Reviewed-by: Max Reitz <mre...@redhat.com> Thanks!