Am 30.11.2015 um 18:22 hat Max Reitz geschrieben: > On 30.11.2015 16:36, Kevin Wolf wrote: > > Am 09.11.2015 um 23:39 hat Max Reitz geschrieben: > >> The NBD code uses the BDS close notifier to determine when a medium is > >> ejected. However, now it should use the BB's BDS removal notifier for > >> that instead of the BDS's close notifier. > >> > >> Signed-off-by: Max Reitz <[email protected]> > >> --- > >> blockdev-nbd.c | 37 +------------------------------------ > >> nbd.c | 13 +++++++++++++ > >> 2 files changed, 14 insertions(+), 36 deletions(-) > >> > >> diff --git a/blockdev-nbd.c b/blockdev-nbd.c > >> index bcdd18b..b28a55b 100644 > >> --- a/blockdev-nbd.c > >> +++ b/blockdev-nbd.c > >> @@ -46,37 +46,11 @@ void qmp_nbd_server_start(SocketAddress *addr, Error > >> **errp) > >> } > >> } > >> > >> -/* > >> - * Hook into the BlockBackend notifiers to close the export when the > >> - * backend is closed. > >> - */ > >> -typedef struct NBDCloseNotifier { > >> - Notifier n; > >> - NBDExport *exp; > >> - QTAILQ_ENTRY(NBDCloseNotifier) next; > >> -} NBDCloseNotifier; > >> - > >> -static QTAILQ_HEAD(, NBDCloseNotifier) close_notifiers = > >> - QTAILQ_HEAD_INITIALIZER(close_notifiers); > >> - > >> -static void nbd_close_notifier(Notifier *n, void *data) > >> -{ > >> - NBDCloseNotifier *cn = DO_UPCAST(NBDCloseNotifier, n, n); > >> - > >> - notifier_remove(&cn->n); > >> - QTAILQ_REMOVE(&close_notifiers, cn, next); > >> - > >> - nbd_export_close(cn->exp); > >> - nbd_export_put(cn->exp); > > > > Here you remove a close/put pair, but in the new code you only add the > > close call. Why is this correct? > > Thanks for putting so much unfounded faith in me. :-) > > After having put quite some time into looking into it, first I have to > say that it's a very good question. > > First off, it's wrong. This is because I thought every export would have > a refcount of one. Turns out this is wrong, they have a refcount of two: > It is created with a refcount of one, and then it gains another by > giving it a name and entering it into the export list. > > I did know about the second but I completely forgot about the former. > And indeed I do think it is wrong. qmp_nbd_server_add() does not keep > the reference to the export, once the function returns, it is gone. > Therefore, it should call nbd_export_put() before returning. > > So in my opinion the current code is wrong and I didn't fix it enough. > *cough* > > So, with the nbd_export_put() added to qmp_nbd_server_add(), every > export will have a refcount of 1 + |clients|. The eject notifier will > call nbd_close_notifier(), which first disconnects the clients, thus > reducing the refcount by |clients|, and then sets the name to NULL, thus > dropping the final refcount and destroying the export. > > In the old code, we needed another nbd_export_put() because of the > superfluous reference from nbd_export_new(), which doesn't actually > exist for blockdev-nbd (it does for qemu-nbd, though).
Okay, that makes sense to me. So first a patch that moves the existing nbd_export_put() call from nbd_close_notifier() to qmp_nbd_server_add() and then this one on top? Kevin
pgplz8g5MQBdx.pgp
Description: PGP signature
