Max Reitz <mre...@redhat.com> writes:

> On 16.09.2014 20:12, 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/Makefile.objs            |   2 +-
>>   block/block-backend.c          | 120 
>> +++++++++++++++++++++++++++++++++++++++++
>>   blockdev.c                     |  11 +++-
>>   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 +-
>>   9 files changed, 243 insertions(+), 11 deletions(-)
>>   create mode 100644 block/block-backend.c
>>   create mode 100644 include/sysemu/block-backend.h
>
> [snip]
>
>> diff --git a/blockdev.c b/blockdev.c
>> index c9463e3..583235a 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>
> [snip]
>
>> @@ -1791,6 +1799,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, 
>> QObject **ret_data)
>>       } else {
>>           drive_del(dinfo);
>>       }
>> +    blk_unref(blk_by_name(id));
>>         aio_context_release(aio_context);
>>       return 0;
>
> Well, now if a BB is created by blockdev_init() but not deleted from
> the monitor, it will not be unref'd. But first of all this is not bad,
> because the time it should be unref'd is exactly when qemu is exiting
> anyway and second, the BDS is not unref'd either.

Yes.  Such a BDS can get destroyed either by explicit monitor command
(here), or when the device using it is unplugged (blockdev_auto_del(),
but only when blockdev_init() created it on behalf of drive_new()).

In this patch, the idea is to match the BB's lifetime to its BDS's
lifetime.

> Therefore:
>
> Reviewed-by: Max Reitz <mre...@redhat.com>

Thanks!

Reply via email to