diff options
Diffstat (limited to 'block.c')
-rw-r--r-- | block.c | 38 |
1 files changed, 37 insertions, 1 deletions
@@ -5540,6 +5540,21 @@ static bool append_open_options(QDict *d, BlockDriverState *bs) return found_any; } +/* Note: This function may return false positives; it may return true + * even if opening the backing file specified by bs's image header + * would result in exactly bs->backing. */ +static bool bdrv_backing_overridden(BlockDriverState *bs) +{ + if (bs->backing) { + return strcmp(bs->auto_backing_file, + bs->backing->bs->filename); + } else { + /* No backing BDS, so if the image header reports any backing + * file, it must have been suppressed */ + return bs->auto_backing_file[0] != '\0'; + } +} + /* Updates the following BDS fields: * - exact_filename: A filename which may be used for opening a block device * which (mostly) equals the given BDS (even without any @@ -5557,6 +5572,7 @@ void bdrv_refresh_filename(BlockDriverState *bs) BlockDriver *drv = bs->drv; BdrvChild *child; QDict *opts; + bool backing_overridden; if (!drv) { return; @@ -5582,6 +5598,16 @@ void bdrv_refresh_filename(BlockDriverState *bs) return; } + backing_overridden = bdrv_backing_overridden(bs); + + if (bs->open_flags & BDRV_O_NO_IO) { + /* Without I/O, the backing file does not change anything. + * Therefore, in such a case (primarily qemu-img), we can + * pretend the backing file has not been overridden even if + * it technically has been. */ + backing_overridden = false; + } + if (drv->bdrv_refresh_filename) { /* Obsolete information is of no use here, so drop the old file name * information before refreshing it */ @@ -5607,6 +5633,7 @@ void bdrv_refresh_filename(BlockDriverState *bs) opts = qdict_new(); has_open_options = append_open_options(opts, bs); + has_open_options |= backing_overridden; /* If no specific options have been given for this BDS, the filename of * the underlying file should suffice for this one as well */ @@ -5618,11 +5645,20 @@ void bdrv_refresh_filename(BlockDriverState *bs) * file BDS. The full options QDict of that file BDS should somehow * contain a representation of the filename, therefore the following * suffices without querying the (exact_)filename of this BDS. */ - if (bs->file->bs->full_open_options) { + if (bs->file->bs->full_open_options && + (!bs->backing || bs->backing->bs->full_open_options)) + { qdict_put_str(opts, "driver", drv->format_name); qdict_put(opts, "file", qobject_ref(bs->file->bs->full_open_options)); + if (bs->backing) { + qdict_put(opts, "backing", + qobject_ref(bs->backing->bs->full_open_options)); + } else if (backing_overridden) { + qdict_put_null(opts, "backing"); + } + bs->full_open_options = opts; } else { qobject_unref(opts); |