@@ -1474,6 +1474,17 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
goto fail;
}
+ if (drv->requires_growing_file && file && !file->growable &&
+ (flags & BDRV_O_RDWR))
+ {
+ error_report("Writes to the image '%s' in format '%s' may require the "
+ "file to grow which is not supported for this file; "
+ "please open it read-only or try to export it in a "
+ "different format over the protocol (e.g. use qemu-nbd "
+ "instead of nbd-server)",
+ filename ?: "", drv->format_name);
+ }
+
if (file && (bs->file != file)) {
bdrv_unref(file);
file = NULL;
@@ -416,6 +416,7 @@ static BlockDriver bdrv_cow = {
.bdrv_create = cow_create,
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.supports_backing = true,
+ .requires_growing_file = true,
.bdrv_read = cow_co_read,
.bdrv_write = cow_co_write,
@@ -942,6 +942,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,
@@ -2429,6 +2429,8 @@ static 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,
@@ -1675,6 +1675,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,
@@ -873,6 +873,8 @@ static BlockDriver bdrv_vdi = {
.create_opts = &vdi_create_opts,
.bdrv_check = vdi_check,
+
+ .requires_growing_file = true,
};
static void bdrv_vdi_init(void)
@@ -1927,6 +1927,8 @@ static BlockDriver bdrv_vhdx = {
.bdrv_check = vhdx_check,
.create_opts = &vhdx_create_opts,
+
+ .requires_growing_file = true,
};
static void bdrv_vhdx_init(void)
@@ -2180,6 +2180,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,
};
@@ -934,6 +934,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)
@@ -104,6 +104,10 @@ struct BlockDriver {
/* Set if a driver can support backing files */
bool supports_backing;
+ /* Set if a driver may need its underlying files to be able to grow for
+ * write accesses */
+ 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);
There are several block drivers which may require the underlying file to grow on write accesses because new clusters need to be allocated. If such a format should be used non-read-only over a protocol which does not allow file growth, emit an appropriate warning. This is relevant e.g. for qcow2 over NBD, if the user tried to export the raw image instead of using the qcow2 block driver on the host (e.g. when using nbd-server). Signed-off-by: Max Reitz <mreitz@redhat.com> --- block.c | 11 +++++++++++ block/cow.c | 1 + 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 ++++ 10 files changed, 27 insertions(+)