diff --git a/block.c b/block.c
index 4c620b1..6da30f8 100644
--- a/block.c
+++ b/block.c
@@ -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) {
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 63611e0..83807f7 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -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))) {
diff --git a/block/blkverify.c b/block/blkverify.c
index 438dff8..6add81c 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -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);
diff --git a/block/iscsi.c b/block/iscsi.c
index 3e34b1f..dd94cda 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -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 "
diff --git a/block/nbd.c b/block/nbd.c
index 2176186..c433555 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -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) {
diff --git a/block/qcow2.c b/block/qcow2.c
index 32bdf75..b4e2aa3 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -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");
diff --git a/block/quorum.c b/block/quorum.c
index 437b122..7a6bcb7 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -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;
 
diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index e3d2d04..72fd951 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -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,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index dccb092..01dee2a 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -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;
 
