From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47264) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YYfjM-0002nr-Sc for qemu-devel@nongnu.org; Thu, 19 Mar 2015 15:03:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YYfjG-00060w-Mo for qemu-devel@nongnu.org; Thu, 19 Mar 2015 15:03:44 -0400 From: Max Reitz Date: Thu, 19 Mar 2015 15:03:21 -0400 Message-Id: <1426791801-9042-4-git-send-email-mreitz@redhat.com> In-Reply-To: <1426791801-9042-1-git-send-email-mreitz@redhat.com> References: <1426791801-9042-1-git-send-email-mreitz@redhat.com> Subject: [Qemu-devel] [PATCH v2 3/3] block: Introduce BlockDriver.requires_growing_file List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: Kevin Wolf , qemu-devel@nongnu.org, Stefan Hajnoczi , Max Reitz This flag is set if write accesses to BDSs managed by the respective driver may lead to writes beyond the end of the underlying file BDS, expecting it to increase its size accordingly. This behavior, however, is only supported by protocol BDSs having the BDS.growing flag set. If they do not, emit a warning. An example of such a misconfiguration is exporting a qcow2 file using the reference NBD server implementation, which cannot interpret the qcow2 format and will thus expose it directly over the network. When accessing that export with qemu, qemu's qcow2 driver may try to allocate clusters over the NBD connection, writing to addresses beyond the size of the NBD export, which will then fail (without the user knowing why, without this warning). Signed-off-by: Max Reitz --- block.c | 16 ++++++++++++++++ block/qcow.c | 1 + block/qcow2.c | 2 ++ block/qed.c | 1 + block/vdi.c | 2 ++ block/vhdx.c | 2 ++ block/vmdk.c | 1 + block/vpc.c | 2 ++ include/block/block_int.h | 4 ++++ 9 files changed, 31 insertions(+) diff --git a/block.c b/block.c index 6da30f8..2db27b5 100644 --- a/block.c +++ b/block.c @@ -1585,6 +1585,22 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, goto fail; } + /* requires_growing_file may only be true for format block drivers */ + assert(!bs->drv->requires_growing_file || bs->file); + if (bs->drv->requires_growing_file && !bs->file->growing && + (flags & BDRV_O_RDWR)) + { + error_report("WARNING: Writes to the image '%s' in format '%s'\n" + " may require the file to grow which is not " + "supported for protocol '%s'.\n" + " Please open it read-only or try to export " + "it in a different format\n" + " over the protocol (e.g. use qemu-nbd " + "instead of nbd-server).", + filename ?: "", drv->format_name, + bs->file->drv->format_name); + } + if (file && (bs->file != file)) { bdrv_unref(file); file = NULL; diff --git a/block/qcow.c b/block/qcow.c index 0558969..5719285 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -962,6 +962,7 @@ static BlockDriver bdrv_qcow = { .bdrv_create = qcow_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .supports_backing = true, + .requires_growing_file = true, .bdrv_co_readv = qcow_co_readv, .bdrv_co_writev = qcow_co_writev, diff --git a/block/qcow2.c b/block/qcow2.c index b4e2aa3..ad1028b 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2944,6 +2944,8 @@ BlockDriver bdrv_qcow2 = { .supports_backing = true, .bdrv_change_backing_file = qcow2_change_backing_file, + .requires_growing_file = true, + .bdrv_refresh_limits = qcow2_refresh_limits, .bdrv_invalidate_cache = qcow2_invalidate_cache, diff --git a/block/qed.c b/block/qed.c index 892b13c..1cd1233 100644 --- a/block/qed.c +++ b/block/qed.c @@ -1662,6 +1662,7 @@ static BlockDriver bdrv_qed = { .instance_size = sizeof(BDRVQEDState), .create_opts = &qed_create_opts, .supports_backing = true, + .requires_growing_file = true, .bdrv_probe = bdrv_qed_probe, .bdrv_rebind = bdrv_qed_rebind, diff --git a/block/vdi.c b/block/vdi.c index 53bd02f..13ffd91 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -903,6 +903,8 @@ static BlockDriver bdrv_vdi = { .create_opts = &vdi_create_opts, .bdrv_check = vdi_check, + + .requires_growing_file = true, }; static void bdrv_vdi_init(void) diff --git a/block/vhdx.c b/block/vhdx.c index bb3ed45..bc1aaca 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -1970,6 +1970,8 @@ static BlockDriver bdrv_vhdx = { .bdrv_has_zero_init = bdrv_has_zero_init_1, .create_opts = &vhdx_create_opts, + + .requires_growing_file = true, }; static void bdrv_vhdx_init(void) diff --git a/block/vmdk.c b/block/vmdk.c index 8410a15..31ae764 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -2293,6 +2293,7 @@ static BlockDriver bdrv_vmdk = { .bdrv_attach_aio_context = vmdk_attach_aio_context, .supports_backing = true, + .requires_growing_file = true, .create_opts = &vmdk_create_opts, }; diff --git a/block/vpc.c b/block/vpc.c index 43e768e..4c26273 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -924,6 +924,8 @@ static BlockDriver bdrv_vpc = { .create_opts = &vpc_create_opts, .bdrv_has_zero_init = vpc_has_zero_init, + + .requires_growing_file = true, }; static void bdrv_vpc_init(void) diff --git a/include/block/block_int.h b/include/block/block_int.h index 01dee2a..be44c80 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -109,6 +109,10 @@ struct BlockDriver { /* Set if a driver can support backing files */ bool supports_backing; + /* Set if the underlying BDS.file needs to support writes beyond its size to + * be grown implicitly in order for this driver's BDSs to be writable */ + bool requires_growing_file; + /* For handling image reopen for split or non-split files */ int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state, BlockReopenQueue *queue, Error **errp); -- 2.1.0