On BlockBackend destruction, unref its BlockDriverState. Replaces the callers' unrefs.
This turns the pointer from BlockBackend to BlockDriverState into a strong reference, managed with bdrv_ref() / bdrv_unref(). The back-pointer remains weak. Signed-off-by: Markus Armbruster <arm...@redhat.com> Reviewed-by: Max Reitz <mre...@redhat.com> Reviewed-by: Kevin Wolf <kw...@redhat.com> --- block/block-backend.c | 6 ++---- blockdev.c | 7 +------ hw/block/xen_disk.c | 6 +++--- qemu-img.c | 35 +---------------------------------- qemu-io.c | 5 ----- qemu-nbd.c | 1 - 6 files changed, 7 insertions(+), 53 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index d4bdd48..6236b5b 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() */ @@ -119,8 +119,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 a00461d..63f797b 100644 --- a/blockdev.c +++ b/blockdev.c @@ -278,10 +278,7 @@ static void bdrv_format_print(void *opaque, const char *name) void drive_del(DriveInfo *dinfo) { - BlockBackend *blk = dinfo->bdrv->blk; - - bdrv_unref(dinfo->bdrv); - blk_unref(blk); + blk_unref(dinfo->bdrv->blk); } typedef struct { @@ -583,7 +580,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); @@ -2608,7 +2604,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 5548637..09e7e72 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(); @@ -1754,18 +1748,8 @@ out: qemu_opts_free(create_opts); qemu_vfree(buf); 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]); @@ -1903,7 +1887,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; } @@ -1913,7 +1896,6 @@ static ImageInfoList *collect_image_info_list(const char *filename, *last = elem; last = &elem->next; - bdrv_unref(bs); blk_unref(blk); filename = fmt = NULL; @@ -2202,7 +2184,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; } @@ -2327,7 +2308,6 @@ static int img_snapshot(int argc, char **argv) } /* Cleanup */ - bdrv_unref(bs); blk_unref(blk); if (ret) { return 1; @@ -2647,17 +2627,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; @@ -2783,9 +2756,6 @@ static int img_resize(int argc, char **argv) break; } out: - if (bs) { - bdrv_unref(bs); - } blk_unref(blk); if (ret) { return 1; @@ -2897,9 +2867,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 8380734..60f84dd 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; @@ -488,9 +486,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 f741973..5cd6c6d 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -775,7 +775,6 @@ int main(int argc, char **argv) } } while (state != TERMINATED); - bdrv_unref(bs); blk_unref(blk); if (sockpath) { unlink(sockpath); -- 1.9.3