On BlockBackend destruction, unref its BlockDriverState. Replaces the callers' unrefs.
Signed-off-by: Markus Armbruster <arm...@redhat.com> --- block/block-backend.c | 6 ++---- blockdev.c | 8 ++------ hw/block/xen_disk.c | 6 +++--- qemu-img.c | 35 +---------------------------------- qemu-io.c | 5 ----- qemu-nbd.c | 1 - 6 files changed, 8 insertions(+), 53 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index be9acda..ed4873e 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -54,8 +54,6 @@ BlockBackend *blk_new(const char *name, Error **errp) /* * Create a new BlockBackend with a new BlockDriverState attached. - * Both have a reference count of one. Caller owns *both* references. - * TODO Let caller own only the BlockBackend reference * Otherwise just like blk_new(), which see. */ BlockBackend *blk_new_with_bs(const char *name, Error **errp) @@ -83,7 +81,9 @@ static void blk_delete(BlockBackend *blk) { assert(!blk->refcnt); if (blk->bs) { + assert(blk->bs->blk == blk); blk->bs->blk = NULL; + bdrv_unref(blk->bs); blk->bs = NULL; } /* Avoid double-remove after blk_hide_on_behalf_of_do_drive_del() */ @@ -121,8 +121,6 @@ void blk_ref(BlockBackend *blk) * Decrement @blk's reference count. * If this drops it to zero, destroy @blk. * For convenience, do nothing if @blk is null. - * Does *not* touch the attached BlockDriverState's reference count. - * TODO Decrement it! */ void blk_unref(BlockBackend *blk) { diff --git a/blockdev.c b/blockdev.c index 1c97faa..3a6fd46 100644 --- a/blockdev.c +++ b/blockdev.c @@ -108,7 +108,7 @@ void blockdev_auto_del(BlockDriverState *bs) DriveInfo *dinfo = blk_legacy_dinfo(blk); if (dinfo && dinfo->auto_del) { - drive_del(dinfo); + blk_unref(blk); } } @@ -219,7 +219,6 @@ static void bdrv_format_print(void *opaque, const char *name) void drive_del(DriveInfo *dinfo) { - bdrv_unref(dinfo->bdrv); blk_unref(blk_by_legacy_dinfo(dinfo)); } @@ -522,7 +521,6 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, return blk; err: - bdrv_unref(bs); blk_unref(blk); early_err: qemu_opts_del(opts); @@ -1782,9 +1780,8 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) /* Further I/O must not pause the guest */ bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT); - /* FIXME bs->blk leaked when bs dies */ } else { - drive_del(dinfo); + blk_unref(blk); } aio_context_release(aio_context); @@ -2521,7 +2518,6 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp) } if (bdrv_key_required(blk_bs(blk))) { - bdrv_unref(blk_bs(blk)); blk_unref(blk); error_setg(errp, "blockdev-add doesn't support encrypted devices"); goto fail; diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 0022083..feb227f 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -872,7 +872,6 @@ static int blk_connect(struct XenDevice *xendev) xen_be_printf(&blkdev->xendev, 0, "error: %s\n", error_get_pretty(local_err)); error_free(local_err); - bdrv_unref(blkdev->bs); blk_unref(blk); blkdev->bs = NULL; return -1; @@ -888,7 +887,9 @@ static int blk_connect(struct XenDevice *xendev) } /* blkdev->bs is not create by us, we get a reference * so we can bdrv_unref() unconditionally */ - bdrv_ref(blkdev->bs); + /* Except we don't bdrv_unref() anymore, we blk_unref(). + * Conditionally, because we can't easily blk_ref() here. + * TODO Clean this up! */ } bdrv_attach_dev_nofail(blkdev->bs, blkdev); blkdev->file_size = bdrv_getlength(blkdev->bs); @@ -988,7 +989,6 @@ static void blk_disconnect(struct XenDevice *xendev) if (blkdev->bs) { bdrv_detach_dev(blkdev->bs, blkdev); - bdrv_unref(blkdev->bs); if (!blkdev->dinfo) { blk_unref(blk_by_name(blkdev->dev)); } diff --git a/qemu-img.c b/qemu-img.c index 206a513..40bd129 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -329,7 +329,6 @@ static BlockBackend *img_open(const char *id, const char *filename, } return blk; fail: - bdrv_unref(bs); blk_unref(blk); return NULL; } @@ -712,9 +711,7 @@ static int img_check(int argc, char **argv) fail: qapi_free_ImageCheck(check); - bdrv_unref(bs); blk_unref(blk); - return ret; } @@ -786,7 +783,6 @@ static int img_commit(int argc, char **argv) break; } - bdrv_unref(bs); blk_unref(blk); if (ret) { return 1; @@ -1196,10 +1192,8 @@ static int img_compare(int argc, char **argv) out: qemu_vfree(buf1); qemu_vfree(buf2); - bdrv_unref(bs2); blk_unref(blk2); out2: - bdrv_unref(bs1); blk_unref(blk1); out3: qemu_progress_end(); @@ -1756,18 +1750,8 @@ out: if (sn_opts) { qemu_opts_del(sn_opts); } - if (out_bs) { - bdrv_unref(out_bs); - } blk_unref(out_blk); - if (bs) { - for (bs_i = 0; bs_i < bs_n; bs_i++) { - if (bs[bs_i]) { - bdrv_unref(bs[bs_i]); - } - } - g_free(bs); - } + g_free(bs); if (blk) { for (bs_i = 0; bs_i < bs_n; bs_i++) { blk_unref(blk[bs_i]); @@ -1905,7 +1889,6 @@ static ImageInfoList *collect_image_info_list(const char *filename, if (err) { error_report("%s", error_get_pretty(err)); error_free(err); - bdrv_unref(bs); blk_unref(blk); goto err; } @@ -1915,7 +1898,6 @@ static ImageInfoList *collect_image_info_list(const char *filename, *last = elem; last = &elem->next; - bdrv_unref(bs); blk_unref(blk); filename = fmt = NULL; @@ -2204,7 +2186,6 @@ static int img_map(int argc, char **argv) dump_map_entry(output_format, &curr, NULL); out: - bdrv_unref(bs); blk_unref(blk); return ret < 0; } @@ -2329,7 +2310,6 @@ static int img_snapshot(int argc, char **argv) } /* Cleanup */ - bdrv_unref(bs); blk_unref(blk); if (ret) { return 1; @@ -2649,17 +2629,10 @@ out: qemu_progress_end(); /* Cleanup */ if (!unsafe) { - if (bs_old_backing != NULL) { - bdrv_unref(bs_old_backing); - } blk_unref(blk_old_backing); - if (bs_new_backing != NULL) { - bdrv_unref(bs_new_backing); - } blk_unref(blk_new_backing); } - bdrv_unref(bs); blk_unref(blk); if (ret) { return 1; @@ -2785,9 +2758,6 @@ static int img_resize(int argc, char **argv) break; } out: - if (bs) { - bdrv_unref(bs); - } blk_unref(blk); if (ret) { return 1; @@ -2899,9 +2869,6 @@ static int img_amend(int argc, char **argv) } out: - if (bs) { - bdrv_unref(bs); - } blk_unref(blk); qemu_opts_del(opts); qemu_opts_free(create_opts); diff --git a/qemu-io.c b/qemu-io.c index ef1d3ea..45e8167 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -38,7 +38,6 @@ static ReadLineState *readline_state; static int close_f(BlockDriverState *bs, int argc, char **argv) { - bdrv_unref(bs); blk_unref(qemuio_blk); qemuio_bs = NULL; qemuio_blk = NULL; @@ -74,7 +73,6 @@ static int openfile(char *name, int flags, int growable, QDict *opts) name ? " device " : "", name ?: "", error_get_pretty(local_err)); error_free(local_err); - bdrv_unref(qemuio_bs); blk_unref(qemuio_blk); qemuio_bs = NULL; qemuio_blk = NULL; @@ -483,9 +481,6 @@ int main(int argc, char **argv) */ bdrv_drain_all(); - if (qemuio_bs) { - bdrv_unref(qemuio_bs); - } blk_unref(qemuio_blk); g_free(readline_state); return 0; diff --git a/qemu-nbd.c b/qemu-nbd.c index 24808e8..c973569 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -771,7 +771,6 @@ int main(int argc, char **argv) } } while (state != TERMINATED); - bdrv_unref(bs); blk_unref(blk); if (sockpath) { unlink(sockpath); -- 1.9.3