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 <mre...@redhat.com> >> --- >> 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). Max
signature.asc
Description: OpenPGP digital signature