From 8f3a73bc57ea83e5b3930d14fc596ea51859987a Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 29 Jan 2016 20:49:10 +0100 Subject: block: Add blk_dev_has_tray() Pull out the check whether a block device has a tray from blk_dev_is_tray_open() into its own function so both attributes (whether there is a tray vs. whether that tray is open) can be queried independently. Cc: qemu-stable Signed-off-by: Max Reitz Reviewed-by: Eric Blake Reviewed-by: Alberto Garcia Message-id: 1454096953-31773-2-git-send-email-mreitz@redhat.com --- block/block-backend.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'block') diff --git a/block/block-backend.c b/block/block-backend.c index efd6146..a4208f1 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -459,6 +459,14 @@ bool blk_dev_has_removable_media(BlockBackend *blk) } /* + * Does @blk's attached device model have a tray? + */ +bool blk_dev_has_tray(BlockBackend *blk) +{ + return blk->dev_ops && blk->dev_ops->is_tray_open; +} + +/* * Notify @blk's attached device model of a media eject request. * If @force is true, the medium is about to be yanked out forcefully. */ @@ -474,7 +482,7 @@ void blk_dev_eject_request(BlockBackend *blk, bool force) */ bool blk_dev_is_tray_open(BlockBackend *blk) { - if (blk->dev_ops && blk->dev_ops->is_tray_open) { + if (blk_dev_has_tray(blk)) { return blk->dev_ops->is_tray_open(blk->dev_opaque); } return false; -- cgit v1.1 From 327032ce74d0d9fbd4e18528d0f124b68bc56cea Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 29 Jan 2016 20:49:13 +0100 Subject: block/qapi: Emit tray_open only if there is a tray Signed-off-by: Max Reitz Reviewed-by: Eric Blake Reviewed-by: Alberto Garcia Message-id: 1454096953-31773-5-git-send-email-mreitz@redhat.com --- block/qapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'block') diff --git a/block/qapi.c b/block/qapi.c index a49c118..bbe0c9d 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -300,7 +300,7 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info, info->locked = blk_dev_is_medium_locked(blk); info->removable = blk_dev_has_removable_media(blk); - if (blk_dev_has_removable_media(blk)) { + if (blk_dev_has_tray(blk)) { info->has_tray_open = true; info->tray_open = blk_dev_is_tray_open(blk); } -- cgit v1.1 From 3db1d98a20262228373bb973ca62b1ab64b29af4 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Mon, 25 Jan 2016 10:26:23 +0800 Subject: vmdk: Fix converting to streamOptimized Commit d62d9dc4b8 lifted streamOptimized images's version to 3, but we now refuse to open version 3 images read-write. We need to make streamOptimized an exception to allow converting to it. This fixes the accidentally broken iotests case 059 for the same reason. Signed-off-by: Fam Zheng Signed-off-by: Kevin Wolf Signed-off-by: Max Reitz --- block/vmdk.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'block') diff --git a/block/vmdk.c b/block/vmdk.c index 698679d..4a5850b 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -571,6 +571,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs, VmdkExtent *extent; BDRVVmdkState *s = bs->opaque; int64_t l1_backup_offset = 0; + bool compressed; ret = bdrv_pread(file->bs, sizeof(magic), &header, sizeof(header)); if (ret < 0) { @@ -645,6 +646,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs, header = footer.header; } + compressed = + le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE; if (le32_to_cpu(header.version) > 3) { char buf[64]; snprintf(buf, sizeof(buf), "VMDK version %" PRId32, @@ -652,7 +655,8 @@ static int vmdk_open_vmdk4(BlockDriverState *bs, error_setg(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE, bdrv_get_device_or_node_name(bs), "vmdk", buf); return -ENOTSUP; - } else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR)) { + } else if (le32_to_cpu(header.version) == 3 && (flags & BDRV_O_RDWR) && + !compressed) { /* VMware KB 2064959 explains that version 3 added support for * persistent changed block tracking (CBT), and backup software can * read it as version=1 if it doesn't care about the changed area -- cgit v1.1 From 3301f6c6e9b52e370b07b3a08fd11735d0f0f292 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 29 Jan 2016 16:36:03 +0100 Subject: block: Add BB-BDS remove/insert notifiers bdrv_close() no longer signifies ejection of a medium, this is now done by removing the BDS from the BB. Therefore, we want to have a notifier for that in the BB instead of a close notifier in the BDS. The former is added now, the latter is removed later. Symmetrically, another notifier list is added that is invoked whenever a BDS is inserted. We will need that for virtio-blk and virtio-scsi, which can then remove their op blockers on BDS ejection and set them up on insertion. Signed-off-by: Max Reitz Reviewed-by: Kevin Wolf Reviewed-by: Fam Zheng Signed-off-by: Kevin Wolf --- block/block-backend.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'block') diff --git a/block/block-backend.c b/block/block-backend.c index a4208f1..1872191 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -49,6 +49,8 @@ struct BlockBackend { BlockdevOnError on_read_error, on_write_error; bool iostatus_enabled; BlockDeviceIoStatus iostatus; + + NotifierList remove_bs_notifiers, insert_bs_notifiers; }; typedef struct BlockBackendAIOCB { @@ -99,6 +101,8 @@ BlockBackend *blk_new(const char *name, Error **errp) blk = g_new0(BlockBackend, 1); blk->name = g_strdup(name); blk->refcnt = 1; + notifier_list_init(&blk->remove_bs_notifiers); + notifier_list_init(&blk->insert_bs_notifiers); QTAILQ_INSERT_TAIL(&blk_backends, blk, link); return blk; } @@ -167,6 +171,8 @@ static void blk_delete(BlockBackend *blk) bdrv_unref(blk->bs); blk->bs = NULL; } + assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers)); + assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers)); if (blk->root_state.throttle_state) { g_free(blk->root_state.throttle_group); throttle_group_unref(blk->root_state.throttle_state); @@ -345,6 +351,8 @@ void blk_hide_on_behalf_of_hmp_drive_del(BlockBackend *blk) */ void blk_remove_bs(BlockBackend *blk) { + notifier_list_notify(&blk->remove_bs_notifiers, blk); + blk_update_root_state(blk); blk->bs->blk = NULL; @@ -361,6 +369,8 @@ void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs) bdrv_ref(bs); blk->bs = bs; bs->blk = blk; + + notifier_list_notify(&blk->insert_bs_notifiers, blk); } /* @@ -1126,6 +1136,16 @@ void blk_remove_aio_context_notifier(BlockBackend *blk, } } +void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify) +{ + notifier_list_add(&blk->remove_bs_notifiers, notify); +} + +void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify) +{ + notifier_list_add(&blk->insert_bs_notifiers, notify); +} + void blk_add_close_notifier(BlockBackend *blk, Notifier *notify) { if (blk->bs) { -- cgit v1.1 From 033cb5659a1dce15643d2d5123615c26e24298ce Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 29 Jan 2016 16:36:07 +0100 Subject: block: Remove BDS close notifier It is unused now, so we can remove it. Signed-off-by: Max Reitz Reviewed-by: Fam Zheng Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/block-backend.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'block') diff --git a/block/block-backend.c b/block/block-backend.c index 1872191..621787c 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1146,13 +1146,6 @@ void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify) notifier_list_add(&blk->insert_bs_notifiers, notify); } -void blk_add_close_notifier(BlockBackend *blk, Notifier *notify) -{ - if (blk->bs) { - bdrv_add_close_notifier(blk->bs, notify); - } -} - void blk_io_plug(BlockBackend *blk) { if (blk->bs) { -- cgit v1.1 From 13855c6b9fa7f9d9e6d1f90377be0f678671073a Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 29 Jan 2016 16:36:08 +0100 Subject: block: Use blk_remove_bs() in blk_delete() Signed-off-by: Max Reitz Reviewed-by: Kevin Wolf Reviewed-by: Fam Zheng Signed-off-by: Kevin Wolf --- block/block-backend.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'block') diff --git a/block/block-backend.c b/block/block-backend.c index 621787c..7f5ad59 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -166,10 +166,7 @@ static void blk_delete(BlockBackend *blk) assert(!blk->refcnt); assert(!blk->dev); if (blk->bs) { - assert(blk->bs->blk == blk); - blk->bs->blk = NULL; - bdrv_unref(blk->bs); - blk->bs = NULL; + blk_remove_bs(blk); } assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers)); assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers)); @@ -351,6 +348,8 @@ void blk_hide_on_behalf_of_hmp_drive_del(BlockBackend *blk) */ void blk_remove_bs(BlockBackend *blk) { + assert(blk->bs->blk == blk); + notifier_list_notify(&blk->remove_bs_notifiers, blk); blk_update_root_state(blk); -- cgit v1.1 From d8da3cef3bc649492d190e029343293df1386027 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 29 Jan 2016 16:36:13 +0100 Subject: block: Add blk_remove_all_bs() When bdrv_close_all() is called, instead of force-closing all root BlockDriverStates, it is better to just drop the reference from all BlockBackends and let them be closed automatically. This prevents BDS from getting closed that are still referenced by other BDS, which may result in loss of cached data. This patch adds a function for doing that, but does not yet incorporate it in bdrv_close_all(). Signed-off-by: Max Reitz Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/block-backend.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'block') diff --git a/block/block-backend.c b/block/block-backend.c index 7f5ad59..ebdf78a 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -223,6 +223,21 @@ void blk_unref(BlockBackend *blk) } } +void blk_remove_all_bs(void) +{ + BlockBackend *blk; + + QTAILQ_FOREACH(blk, &blk_backends, link) { + AioContext *ctx = blk_get_aio_context(blk); + + aio_context_acquire(ctx); + if (blk->bs) { + blk_remove_bs(blk); + } + aio_context_release(ctx); + } +} + /* * Return the BlockBackend after @blk. * If @blk is null, return the first one. -- cgit v1.1 From 1963f8d52e04a8f8b213e34e6a76fb286fb23ec1 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 23 Dec 2015 11:48:23 +0100 Subject: block: acquire in bdrv_query_image_info NFS calls aio_poll inside bdrv_get_allocated_size. This requires acquiring the AioContext. Signed-off-by: Paolo Bonzini Message-id: 1450867706-19860-1-git-send-email-pbonzini@redhat.com Reviewed-by: Fam Zheng Signed-off-by: Max Reitz --- block/qapi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'block') diff --git a/block/qapi.c b/block/qapi.c index bbe0c9d..2e83105 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -211,11 +211,13 @@ void bdrv_query_image_info(BlockDriverState *bs, Error *err = NULL; ImageInfo *info; + aio_context_acquire(bdrv_get_aio_context(bs)); + size = bdrv_getlength(bs); if (size < 0) { error_setg_errno(errp, -size, "Can't get size of device '%s'", bdrv_get_device_name(bs)); - return; + goto out; } info = g_new0(ImageInfo, 1); @@ -283,10 +285,13 @@ void bdrv_query_image_info(BlockDriverState *bs, default: error_propagate(errp, err); qapi_free_ImageInfo(info); - return; + goto out; } *p_info = info; + +out: + aio_context_release(bdrv_get_aio_context(bs)); } /* @p_info will be set only on success. */ -- cgit v1.1 From 67a0fd2a9bca204d2b39f910a97c7137636a0715 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 26 Jan 2016 11:58:48 +0800 Subject: block: Add "file" output parameter to block status query functions The added parameter can be used to return the BDS pointer which the valid offset is referring to. Its value should be ignored unless BDRV_BLOCK_OFFSET_VALID in ret is set. Until block drivers fill in the right value, let's clear it explicitly right before calling .bdrv_get_block_status. The "bs->file" condition in bdrv_co_get_block_status is kept now to keep iotest case 102 passing, and will be fixed once all drivers return the right file pointer. Signed-off-by: Fam Zheng Message-id: 1453780743-16806-2-git-send-email-famz@redhat.com Reviewed-by: Max Reitz Signed-off-by: Max Reitz --- block/io.c | 40 ++++++++++++++++++++++++++++------------ block/iscsi.c | 6 ++++-- block/mirror.c | 3 ++- block/parallels.c | 2 +- block/qcow.c | 2 +- block/qcow2.c | 2 +- block/qed.c | 3 ++- block/raw-posix.c | 3 ++- block/raw_bsd.c | 3 ++- block/sheepdog.c | 2 +- block/vdi.c | 2 +- block/vmdk.c | 2 +- block/vpc.c | 2 +- block/vvfat.c | 2 +- 14 files changed, 48 insertions(+), 26 deletions(-) (limited to 'block') diff --git a/block/io.c b/block/io.c index 5bb353a..ea040be 100644 --- a/block/io.c +++ b/block/io.c @@ -664,6 +664,7 @@ int bdrv_write_zeroes(BlockDriverState *bs, int64_t sector_num, int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags) { int64_t target_sectors, ret, nb_sectors, sector_num = 0; + BlockDriverState *file; int n; target_sectors = bdrv_nb_sectors(bs); @@ -676,7 +677,7 @@ int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags) if (nb_sectors <= 0) { return 0; } - ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &n); + ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &n, &file); if (ret < 0) { error_report("error getting block status at sector %" PRId64 ": %s", sector_num, strerror(-ret)); @@ -1466,6 +1467,7 @@ int bdrv_flush_all(void) typedef struct BdrvCoGetBlockStatusData { BlockDriverState *bs; BlockDriverState *base; + BlockDriverState **file; int64_t sector_num; int nb_sectors; int *pnum; @@ -1487,10 +1489,14 @@ typedef struct BdrvCoGetBlockStatusData { * * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes * beyond the end of the disk image it will be clamped. + * + * If returned value is positive and BDRV_BLOCK_OFFSET_VALID bit is set, 'file' + * points to the BDS which the sector range is allocated in. */ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, int *pnum) + int nb_sectors, int *pnum, + BlockDriverState **file) { int64_t total_sectors; int64_t n; @@ -1520,7 +1526,9 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs, return ret; } - ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum); + *file = NULL; + ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum, + file); if (ret < 0) { *pnum = 0; return ret; @@ -1529,7 +1537,7 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs, if (ret & BDRV_BLOCK_RAW) { assert(ret & BDRV_BLOCK_OFFSET_VALID); return bdrv_get_block_status(bs->file->bs, ret >> BDRV_SECTOR_BITS, - *pnum, pnum); + *pnum, pnum, file); } if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) { @@ -1549,10 +1557,11 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs, if (bs->file && (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) && (ret & BDRV_BLOCK_OFFSET_VALID)) { + BlockDriverState *file2; int file_pnum; ret2 = bdrv_co_get_block_status(bs->file->bs, ret >> BDRV_SECTOR_BITS, - *pnum, &file_pnum); + *pnum, &file_pnum, &file2); if (ret2 >= 0) { /* Ignore errors. This is just providing extra information, it * is useful but not necessary. @@ -1577,14 +1586,15 @@ static int64_t coroutine_fn bdrv_co_get_block_status_above(BlockDriverState *bs, BlockDriverState *base, int64_t sector_num, int nb_sectors, - int *pnum) + int *pnum, + BlockDriverState **file) { BlockDriverState *p; int64_t ret = 0; assert(bs != base); for (p = bs; p != base; p = backing_bs(p)) { - ret = bdrv_co_get_block_status(p, sector_num, nb_sectors, pnum); + ret = bdrv_co_get_block_status(p, sector_num, nb_sectors, pnum, file); if (ret < 0 || ret & BDRV_BLOCK_ALLOCATED) { break; } @@ -1603,7 +1613,8 @@ static void coroutine_fn bdrv_get_block_status_above_co_entry(void *opaque) data->ret = bdrv_co_get_block_status_above(data->bs, data->base, data->sector_num, data->nb_sectors, - data->pnum); + data->pnum, + data->file); data->done = true; } @@ -1615,12 +1626,14 @@ static void coroutine_fn bdrv_get_block_status_above_co_entry(void *opaque) int64_t bdrv_get_block_status_above(BlockDriverState *bs, BlockDriverState *base, int64_t sector_num, - int nb_sectors, int *pnum) + int nb_sectors, int *pnum, + BlockDriverState **file) { Coroutine *co; BdrvCoGetBlockStatusData data = { .bs = bs, .base = base, + .file = file, .sector_num = sector_num, .nb_sectors = nb_sectors, .pnum = pnum, @@ -1644,16 +1657,19 @@ int64_t bdrv_get_block_status_above(BlockDriverState *bs, int64_t bdrv_get_block_status(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, int *pnum) + int nb_sectors, int *pnum, + BlockDriverState **file) { return bdrv_get_block_status_above(bs, backing_bs(bs), - sector_num, nb_sectors, pnum); + sector_num, nb_sectors, pnum, file); } int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum) { - int64_t ret = bdrv_get_block_status(bs, sector_num, nb_sectors, pnum); + BlockDriverState *file; + int64_t ret = bdrv_get_block_status(bs, sector_num, nb_sectors, pnum, + &file); if (ret < 0) { return ret; } diff --git a/block/iscsi.c b/block/iscsi.c index bffd707..e182557 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -532,7 +532,8 @@ static bool iscsi_allocationmap_is_allocated(IscsiLun *iscsilun, static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, int *pnum) + int nb_sectors, int *pnum, + BlockDriverState **file) { IscsiLun *iscsilun = bs->opaque; struct scsi_get_lba_status *lbas = NULL; @@ -650,7 +651,8 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs, !iscsi_allocationmap_is_allocated(iscsilun, sector_num, nb_sectors)) { int64_t ret; int pnum; - ret = iscsi_co_get_block_status(bs, sector_num, INT_MAX, &pnum); + BlockDriverState *file; + ret = iscsi_co_get_block_status(bs, sector_num, INT_MAX, &pnum, &file); if (ret < 0) { return ret; } diff --git a/block/mirror.c b/block/mirror.c index e9e151c..2c0edfa 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -168,6 +168,7 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s) MirrorOp *op; int pnum; int64_t ret; + BlockDriverState *file; max_iov = MIN(source->bl.max_iov, s->target->bl.max_iov); @@ -306,7 +307,7 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s) trace_mirror_one_iteration(s, sector_num, nb_sectors); ret = bdrv_get_block_status_above(source, NULL, sector_num, - nb_sectors, &pnum); + nb_sectors, &pnum, &file); if (ret < 0 || pnum < nb_sectors || (ret & BDRV_BLOCK_DATA && !(ret & BDRV_BLOCK_ZERO))) { bdrv_aio_readv(source, sector_num, &op->qiov, nb_sectors, diff --git a/block/parallels.c b/block/parallels.c index ee39081..e2de308 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -261,7 +261,7 @@ static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs) static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, int *pnum) + int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file) { BDRVParallelsState *s = bs->opaque; int64_t offset; diff --git a/block/qcow.c b/block/qcow.c index afed18f..4202797 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -489,7 +489,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, } static int64_t coroutine_fn qcow_co_get_block_status(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, int *pnum) + int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file) { BDRVQcowState *s = bs->opaque; int index_in_cluster, n; diff --git a/block/qcow2.c b/block/qcow2.c index fd8436c..d4ea6b4 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1330,7 +1330,7 @@ static void qcow2_join_options(QDict *options, QDict *old_options) } static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, int *pnum) + int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file) { BDRVQcow2State *s = bs->opaque; uint64_t cluster_offset; diff --git a/block/qed.c b/block/qed.c index 0c870cd..8f6f841 100644 --- a/block/qed.c +++ b/block/qed.c @@ -725,7 +725,8 @@ static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t l static int64_t coroutine_fn bdrv_qed_co_get_block_status(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, int *pnum) + int nb_sectors, int *pnum, + BlockDriverState **file) { BDRVQEDState *s = bs->opaque; size_t len = (size_t)nb_sectors * BDRV_SECTOR_SIZE; diff --git a/block/raw-posix.c b/block/raw-posix.c index 6df3067..3ef9b25 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1818,7 +1818,8 @@ static int find_allocation(BlockDriverState *bs, off_t start, */ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, int *pnum) + int nb_sectors, int *pnum, + BlockDriverState **file) { off_t start, data = 0, hole = 0; int64_t total_size; diff --git a/block/raw_bsd.c b/block/raw_bsd.c index bcaee11..9a8933b 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -115,7 +115,8 @@ fail: static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, int *pnum) + int nb_sectors, int *pnum, + BlockDriverState **file) { *pnum = nb_sectors; return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA | diff --git a/block/sheepdog.c b/block/sheepdog.c index ff89298..2ea05a6 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -2708,7 +2708,7 @@ retry: static coroutine_fn int64_t sd_co_get_block_status(BlockDriverState *bs, int64_t sector_num, int nb_sectors, - int *pnum) + int *pnum, BlockDriverState **file) { BDRVSheepdogState *s = bs->opaque; SheepdogInode *inode = &s->inode; diff --git a/block/vdi.c b/block/vdi.c index 61bcd54..294c438 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -527,7 +527,7 @@ static int vdi_reopen_prepare(BDRVReopenState *state, } static int64_t coroutine_fn vdi_co_get_block_status(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, int *pnum) + int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file) { /* TODO: Check for too large sector_num (in bdrv_is_allocated or here). */ BDRVVdiState *s = (BDRVVdiState *)bs->opaque; diff --git a/block/vmdk.c b/block/vmdk.c index 4a5850b..109fd5f 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1261,7 +1261,7 @@ static inline uint64_t vmdk_find_index_in_cluster(VmdkExtent *extent, } static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, int *pnum) + int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file) { BDRVVmdkState *s = bs->opaque; int64_t index_in_cluster, n, ret; diff --git a/block/vpc.c b/block/vpc.c index d852f96..a070307 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -579,7 +579,7 @@ static coroutine_fn int vpc_co_write(BlockDriverState *bs, int64_t sector_num, } static int64_t coroutine_fn vpc_co_get_block_status(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, int *pnum) + int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file) { BDRVVPCState *s = bs->opaque; VHDFooter *footer = (VHDFooter*) s->footer_buf; diff --git a/block/vvfat.c b/block/vvfat.c index 2ea5a4a..b8d29e1 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2884,7 +2884,7 @@ static coroutine_fn int vvfat_co_write(BlockDriverState *bs, int64_t sector_num, } static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, int* n) + int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file) { BDRVVVFATState* s = bs->opaque; *n = s->sector_count - sector_num; -- cgit v1.1 From 3064bf6fffe4705d983b8cecfbbe3de3e5a75312 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 26 Jan 2016 11:58:49 +0800 Subject: qcow: Assign bs->file->bs to file in qcow_co_get_block_status Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi Signed-off-by: Fam Zheng Message-id: 1453780743-16806-3-git-send-email-famz@redhat.com Signed-off-by: Max Reitz --- block/qcow.c | 1 + 1 file changed, 1 insertion(+) (limited to 'block') diff --git a/block/qcow.c b/block/qcow.c index 4202797..251910c 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -510,6 +510,7 @@ static int64_t coroutine_fn qcow_co_get_block_status(BlockDriverState *bs, return BDRV_BLOCK_DATA; } cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS); + *file = bs->file->bs; return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | cluster_offset; } -- cgit v1.1 From 178b4db7e5dc6c5bbaa24a72fdb232ec259c26eb Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 26 Jan 2016 11:58:50 +0800 Subject: qcow2: Assign bs->file->bs to file in qcow2_co_get_block_status Reviewed-by: Stefan Hajnoczi Signed-off-by: Fam Zheng Message-id: 1453780743-16806-4-git-send-email-famz@redhat.com Signed-off-by: Max Reitz --- block/qcow2.c | 1 + 1 file changed, 1 insertion(+) (limited to 'block') diff --git a/block/qcow2.c b/block/qcow2.c index d4ea6b4..8babecd 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1349,6 +1349,7 @@ static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs, !s->cipher) { index_in_cluster = sector_num & (s->cluster_sectors - 1); cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS); + *file = bs->file->bs; status |= BDRV_BLOCK_OFFSET_VALID | cluster_offset; } if (ret == QCOW2_CLUSTER_ZERO) { -- cgit v1.1 From 02650acbc622b51b3428630b2f60ca1966caa1e8 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 26 Jan 2016 11:58:51 +0800 Subject: raw: Assign bs to file in raw_co_get_block_status Signed-off-by: Fam Zheng Message-id: 1453780743-16806-5-git-send-email-famz@redhat.com Reviewed-by: Max Reitz Signed-off-by: Max Reitz --- block/raw-posix.c | 1 + block/raw_bsd.c | 1 + 2 files changed, 2 insertions(+) (limited to 'block') diff --git a/block/raw-posix.c b/block/raw-posix.c index 3ef9b25..8866121 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1861,6 +1861,7 @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs, *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE); ret = BDRV_BLOCK_ZERO; } + *file = bs; return ret | BDRV_BLOCK_OFFSET_VALID | start; } diff --git a/block/raw_bsd.c b/block/raw_bsd.c index 9a8933b..ea16a23 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -119,6 +119,7 @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs, BlockDriverState **file) { *pnum = nb_sectors; + *file = bs->file->bs; return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA | (sector_num << BDRV_SECTOR_BITS); } -- cgit v1.1 From 3399833f1412e72e6f9e6997775dfdf12d624eaf Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 26 Jan 2016 11:58:52 +0800 Subject: iscsi: Assign bs to file in iscsi_co_get_block_status Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi Signed-off-by: Fam Zheng Message-id: 1453780743-16806-6-git-send-email-famz@redhat.com Signed-off-by: Max Reitz --- block/iscsi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'block') diff --git a/block/iscsi.c b/block/iscsi.c index e182557..9fe76f4 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -625,6 +625,9 @@ out: if (iTask.task != NULL) { scsi_free_scsi_task(iTask.task); } + if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID) { + *file = bs; + } return ret; } -- cgit v1.1 From ddf4987d76ebc356da96f6901c1af970ef421da6 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 26 Jan 2016 11:58:53 +0800 Subject: parallels: Assign bs->file->bs to file in parallels_co_get_block_status Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi Signed-off-by: Fam Zheng Message-id: 1453780743-16806-7-git-send-email-famz@redhat.com Signed-off-by: Max Reitz --- block/parallels.c | 1 + 1 file changed, 1 insertion(+) (limited to 'block') diff --git a/block/parallels.c b/block/parallels.c index e2de308..645521d 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -274,6 +274,7 @@ static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs, return 0; } + *file = bs->file->bs; return (offset << BDRV_SECTOR_BITS) | BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID; } -- cgit v1.1 From 53f1dfd1ff5a603ea1bd67b925758d22f54e1f8a Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 26 Jan 2016 11:58:54 +0800 Subject: qed: Assign bs->file->bs to file in bdrv_qed_co_get_block_status Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi Signed-off-by: Fam Zheng Message-id: 1453780743-16806-8-git-send-email-famz@redhat.com Signed-off-by: Max Reitz --- block/qed.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'block') diff --git a/block/qed.c b/block/qed.c index 8f6f841..404be1e 100644 --- a/block/qed.c +++ b/block/qed.c @@ -693,6 +693,7 @@ typedef struct { uint64_t pos; int64_t status; int *pnum; + BlockDriverState **file; } QEDIsAllocatedCB; static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t len) @@ -704,6 +705,7 @@ static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t l case QED_CLUSTER_FOUND: offset |= qed_offset_into_cluster(s, cb->pos); cb->status = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset; + *cb->file = cb->bs->file->bs; break; case QED_CLUSTER_ZERO: cb->status = BDRV_BLOCK_ZERO; @@ -735,6 +737,7 @@ static int64_t coroutine_fn bdrv_qed_co_get_block_status(BlockDriverState *bs, .pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE, .status = BDRV_BLOCK_OFFSET_MASK, .pnum = pnum, + .file = file, }; QEDRequest request = { .l2_table = NULL }; -- cgit v1.1 From d234c929310a322357ed4323c7014605449f5802 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 26 Jan 2016 11:58:55 +0800 Subject: sheepdog: Assign bs to file in sd_co_get_block_status Reviewed-by: Stefan Hajnoczi Signed-off-by: Fam Zheng Message-id: 1453780743-16806-9-git-send-email-famz@redhat.com Signed-off-by: Max Reitz --- block/sheepdog.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'block') diff --git a/block/sheepdog.c b/block/sheepdog.c index 2ea05a6..a0098c1 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -2739,6 +2739,9 @@ sd_co_get_block_status(BlockDriverState *bs, int64_t sector_num, int nb_sectors, if (*pnum > nb_sectors) { *pnum = nb_sectors; } + if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID) { + *file = bs; + } return ret; } -- cgit v1.1 From 8bfb137152d2195c70e99ed3269a3f4825ffc614 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 26 Jan 2016 11:58:56 +0800 Subject: vdi: Assign bs->file->bs to file in vdi_co_get_block_status Reviewed-by: Stefan Hajnoczi Signed-off-by: Fam Zheng Message-id: 1453780743-16806-10-git-send-email-famz@redhat.com Signed-off-by: Max Reitz --- block/vdi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'block') diff --git a/block/vdi.c b/block/vdi.c index 294c438..b403243 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -551,6 +551,7 @@ static int64_t coroutine_fn vdi_co_get_block_status(BlockDriverState *bs, offset = s->header.offset_data + (uint64_t)bmap_entry * s->block_size + sector_in_block * SECTOR_SIZE; + *file = bs->file->bs; return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset; } -- cgit v1.1 From 7429e207883fb6f6bd46cefee4c79771e50f35f4 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 26 Jan 2016 11:58:57 +0800 Subject: vpc: Assign bs->file->bs to file in vpc_co_get_block_status Reviewed-by: Stefan Hajnoczi Signed-off-by: Fam Zheng Message-id: 1453780743-16806-11-git-send-email-famz@redhat.com Signed-off-by: Max Reitz --- block/vpc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'block') diff --git a/block/vpc.c b/block/vpc.c index a070307..f504536 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -589,6 +589,7 @@ static int64_t coroutine_fn vpc_co_get_block_status(BlockDriverState *bs, if (be32_to_cpu(footer->type) == VHD_FIXED) { *pnum = nb_sectors; + *file = bs->file->bs; return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA | (sector_num << BDRV_SECTOR_BITS); } @@ -610,6 +611,7 @@ static int64_t coroutine_fn vpc_co_get_block_status(BlockDriverState *bs, /* *pnum can't be greater than one block for allocated * sectors since there is always a bitmap in between. */ if (allocated) { + *file = bs->file->bs; return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | start; } if (nb_sectors == 0) { -- cgit v1.1 From d0a18f10251f515c86dcaec5bdf979a4e07fafc5 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 26 Jan 2016 11:58:58 +0800 Subject: vmdk: Fix calculation of block status's offset "offset" is the offset of cluster and sector_num doesn't necessarily refer to the start of it, it should add index_in_cluster. Signed-off-by: Fam Zheng Message-id: 1453780743-16806-12-git-send-email-famz@redhat.com Reviewed-by: Max Reitz Signed-off-by: Max Reitz --- block/vmdk.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'block') diff --git a/block/vmdk.c b/block/vmdk.c index 109fd5f..9d5a18a 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1278,6 +1278,7 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs, 0, 0); qemu_co_mutex_unlock(&s->lock); + index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num); switch (ret) { case VMDK_ERROR: ret = -EIO; @@ -1291,13 +1292,14 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs, case VMDK_OK: ret = BDRV_BLOCK_DATA; if (extent->file == bs->file && !extent->compressed) { - ret |= BDRV_BLOCK_OFFSET_VALID | offset; + ret |= BDRV_BLOCK_OFFSET_VALID; + ret |= (offset + (index_in_cluster << BDRV_SECTOR_BITS)) + & BDRV_BLOCK_OFFSET_MASK; } break; } - index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num); n = extent->cluster_sectors - index_in_cluster; if (n > nb_sectors) { n = nb_sectors; -- cgit v1.1 From e0f100f57ceee919a7df7af316961b175ffef4e6 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 26 Jan 2016 11:58:59 +0800 Subject: vmdk: Return extent's file in bdrv_get_block_status Signed-off-by: Fam Zheng Message-id: 1453780743-16806-13-git-send-email-famz@redhat.com Reviewed-by: Max Reitz Signed-off-by: Max Reitz --- block/vmdk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'block') diff --git a/block/vmdk.c b/block/vmdk.c index 9d5a18a..a8db5d9 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1291,12 +1291,12 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs, break; case VMDK_OK: ret = BDRV_BLOCK_DATA; - if (extent->file == bs->file && !extent->compressed) { + if (!extent->compressed) { ret |= BDRV_BLOCK_OFFSET_VALID; ret |= (offset + (index_in_cluster << BDRV_SECTOR_BITS)) & BDRV_BLOCK_OFFSET_MASK; } - + *file = extent->file->bs; break; } -- cgit v1.1 From ac987b30d0a97f14b82584921fc5ab3cd88c431b Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Tue, 26 Jan 2016 11:59:00 +0800 Subject: block: Use returned *file in bdrv_co_get_block_status Now that all drivers return the right "file" pointer, we can use it. Signed-off-by: Fam Zheng Reviewed-by: Max Reitz Message-id: 1453780743-16806-14-git-send-email-famz@redhat.com Signed-off-by: Max Reitz --- block/io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'block') diff --git a/block/io.c b/block/io.c index ea040be..343ff1f 100644 --- a/block/io.c +++ b/block/io.c @@ -1554,13 +1554,13 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs, } } - if (bs->file && + if (*file && *file != bs && (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) && (ret & BDRV_BLOCK_OFFSET_VALID)) { BlockDriverState *file2; int file_pnum; - ret2 = bdrv_co_get_block_status(bs->file->bs, ret >> BDRV_SECTOR_BITS, + ret2 = bdrv_co_get_block_status(*file, ret >> BDRV_SECTOR_BITS, *pnum, &file_pnum, &file2); if (ret2 >= 0) { /* Ignore errors. This is just providing extra information, it -- cgit v1.1