diff options
author | Eric Blake <eblake@redhat.com> | 2019-01-11 13:47:19 -0600 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2019-01-14 10:09:46 -0600 |
commit | 678ba275c77b5b12f3bc9bb369a1b824fc9f679f (patch) | |
tree | 9421848ee26b56cfb7a30eaff385d7f621152dd4 /nbd | |
parent | 7dc570b3806e5b0a4c9219061556ed5a4a0de80c (diff) |
nbd: Merge nbd_export_bitmap into nbd_export_new
We only have one caller that wants to export a bitmap name,
which it does right after creation of the export. But there is
still a brief window of time where an NBD client could see the
export but not the dirty bitmap, which a robust client would
have to interpret as meaning the entire image should be treated
as dirty. Better is to eliminate the window entirely, by
inlining nbd_export_bitmap() into nbd_export_new(), and refusing
to create the bitmap in the first place if the requested bitmap
can't be located.
We also no longer need logic for setting a different bitmap
name compared to the bitmap being exported.
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20190111194720.15671-8-eblake@redhat.com>
Diffstat (limited to 'nbd')
-rw-r--r-- | nbd/server.c | 87 |
1 files changed, 40 insertions, 47 deletions
diff --git a/nbd/server.c b/nbd/server.c index bb5438c448..e8c56607ef 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1457,9 +1457,9 @@ static void nbd_eject_notifier(Notifier *n, void *data) NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size, const char *name, const char *description, - uint16_t nbdflags, void (*close)(NBDExport *), - bool writethrough, BlockBackend *on_eject_blk, - Error **errp) + const char *bitmap, uint16_t nbdflags, + void (*close)(NBDExport *), bool writethrough, + BlockBackend *on_eject_blk, Error **errp) { AioContext *ctx; BlockBackend *blk; @@ -1507,6 +1507,43 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size, } exp->size -= exp->size % BDRV_SECTOR_SIZE; + if (bitmap) { + BdrvDirtyBitmap *bm = NULL; + BlockDriverState *bs = blk_bs(blk); + + while (true) { + bm = bdrv_find_dirty_bitmap(bs, bitmap); + if (bm != NULL || bs->backing == NULL) { + break; + } + + bs = bs->backing->bs; + } + + if (bm == NULL) { + error_setg(errp, "Bitmap '%s' is not found", bitmap); + goto fail; + } + + if ((nbdflags & NBD_FLAG_READ_ONLY) && bdrv_is_writable(bs) && + bdrv_dirty_bitmap_enabled(bm)) { + error_setg(errp, + "Enabled bitmap '%s' incompatible with readonly export", + bitmap); + goto fail; + } + + if (bdrv_dirty_bitmap_user_locked(bm)) { + error_setg(errp, "Bitmap '%s' is in use", bitmap); + goto fail; + } + + bdrv_dirty_bitmap_set_qmp_locked(bm, true); + exp->export_bitmap = bm; + exp->export_bitmap_context = g_strdup_printf("qemu:dirty-bitmap:%s", + bitmap); + } + exp->close = close; exp->ctx = blk_get_aio_context(blk); blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, exp); @@ -2424,47 +2461,3 @@ void nbd_client_new(QIOChannelSocket *sioc, co = qemu_coroutine_create(nbd_co_client_start, client); qemu_coroutine_enter(co); } - -void nbd_export_bitmap(NBDExport *exp, const char *bitmap, - const char *bitmap_export_name, Error **errp) -{ - BdrvDirtyBitmap *bm = NULL; - BlockDriverState *bs = blk_bs(exp->blk); - - if (exp->export_bitmap) { - error_setg(errp, "Export bitmap is already set"); - return; - } - - while (true) { - bm = bdrv_find_dirty_bitmap(bs, bitmap); - if (bm != NULL || bs->backing == NULL) { - break; - } - - bs = bs->backing->bs; - } - - if (bm == NULL) { - error_setg(errp, "Bitmap '%s' is not found", bitmap); - return; - } - - if ((exp->nbdflags & NBD_FLAG_READ_ONLY) && bdrv_is_writable(bs) && - bdrv_dirty_bitmap_enabled(bm)) { - error_setg(errp, - "Enabled bitmap '%s' incompatible with readonly export", - bitmap); - return; - } - - if (bdrv_dirty_bitmap_user_locked(bm)) { - error_setg(errp, "Bitmap '%s' is in use", bitmap); - return; - } - - bdrv_dirty_bitmap_set_qmp_locked(bm, true); - exp->export_bitmap = bm; - exp->export_bitmap_context = - g_strdup_printf("qemu:dirty-bitmap:%s", bitmap_export_name); -} |