@@ -1575,6 +1575,10 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
* (the inverse results in an error message from bdrv_open_common()) */
assert(!(flags & BDRV_O_PROTOCOL) || !file);
+ /* Default, can be overridden by drv->bdrv_file_open() (conversely,
+ * drv->bdrv_open() can override bs->growing being false by default) */
+ bs->growing = flags & BDRV_O_PROTOCOL;
+
/* Open the image */
ret = bdrv_open_common(bs, file, options, flags, drv, &local_err);
if (ret < 0) {
@@ -437,6 +437,8 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
goto out;
}
+ bs->growing = bs->file->growing;
+
/* Set request alignment */
align = qemu_opt_get_size(opts, "align", bs->request_alignment);
if (align > 0 && align < INT_MAX && !(align & (align - 1))) {
@@ -141,6 +141,8 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
+ bs->growing = bs->file->growing && s->test_file->growing;
+
ret = 0;
fail:
qemu_opts_del(opts);
@@ -1285,6 +1285,8 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
const char *filename;
int i, ret = 0;
+ bs->growing = false;
+
if ((BDRV_SECTOR_SIZE % 512) != 0) {
error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
"BDRV_SECTOR_SIZE(%lld) is not a multiple "
@@ -262,6 +262,8 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
int result, sock;
Error *local_err = NULL;
+ bs->growing = false;
+
/* Pop the config into our state object. Exit if invalid. */
nbd_config(s, options, &export, &local_err);
if (local_err) {
@@ -552,6 +552,11 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
int overlap_check_template = 0;
uint64_t l2_cache_size, refcount_cache_size;
+ /* Note: bs->growing is not set, even though qcow2 supports writes beyond
+ * the virtual disk size; these writes do not increase the disk size,
+ * however, which would be necessary for that flag to be set (also, that
+ * behavior is used internally by qcow2 only anyway). */
+
ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not read qcow2 header");
@@ -974,6 +974,11 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
opened[i] = true;
}
+ bs->growing = true;
+ for (i = 0; i < s->num_children; i++) {
+ bs->growing &= s->bs[i]->growing;
+ }
+
g_free(opened);
goto exit;
@@ -208,6 +208,7 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
bs->sg = bs->file->sg;
+ bs->growing = bs->file->growing;
if (bs->probed && !bdrv_is_read_only(bs)) {
fprintf(stderr,
@@ -345,6 +345,9 @@ struct BlockDriverState {
note this is a reference count */
bool probed;
+ /* Set if writes beyond the BDS's size make it grow */
+ bool growing;
+
BlockDriver *drv; /* NULL means no media */
void *opaque;
This flag is set if the BDS's size can be increased by writing beyond its end. Signed-off-by: Max Reitz <mreitz@redhat.com> --- block.c | 4 ++++ block/blkdebug.c | 2 ++ block/blkverify.c | 2 ++ block/iscsi.c | 2 ++ block/nbd.c | 2 ++ block/qcow2.c | 5 +++++ block/quorum.c | 5 +++++ block/raw_bsd.c | 1 + include/block/block_int.h | 3 +++ 9 files changed, 26 insertions(+)