|
@@ -1155,10 +1155,6 @@ static void bdrv_backing_attach(BdrvChild *c)
|
|
bdrv_refresh_filename(backing_hd);
|
|
bdrv_refresh_filename(backing_hd);
|
|
|
|
|
|
parent->open_flags &= ~BDRV_O_NO_BACKING;
|
|
parent->open_flags &= ~BDRV_O_NO_BACKING;
|
|
- pstrcpy(parent->backing_file, sizeof(parent->backing_file),
|
|
|
|
- backing_hd->filename);
|
|
|
|
- pstrcpy(parent->backing_format, sizeof(parent->backing_format),
|
|
|
|
- backing_hd->drv ? backing_hd->drv->format_name : "");
|
|
|
|
|
|
|
|
bdrv_op_block_all(backing_hd, parent->backing_blocker);
|
|
bdrv_op_block_all(backing_hd, parent->backing_blocker);
|
|
/* Otherwise we won't be able to commit or stream */
|
|
/* Otherwise we won't be able to commit or stream */
|
|
@@ -5673,6 +5669,7 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
|
|
char *backing_file_full = NULL;
|
|
char *backing_file_full = NULL;
|
|
char *filename_tmp = NULL;
|
|
char *filename_tmp = NULL;
|
|
int is_protocol = 0;
|
|
int is_protocol = 0;
|
|
|
|
+ bool filenames_refreshed = false;
|
|
BlockDriverState *curr_bs = NULL;
|
|
BlockDriverState *curr_bs = NULL;
|
|
BlockDriverState *retval = NULL;
|
|
BlockDriverState *retval = NULL;
|
|
BlockDriverState *bs_below;
|
|
BlockDriverState *bs_below;
|
|
@@ -5698,9 +5695,31 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
|
|
{
|
|
{
|
|
bs_below = bdrv_backing_chain_next(curr_bs);
|
|
bs_below = bdrv_backing_chain_next(curr_bs);
|
|
|
|
|
|
- /* If either of the filename paths is actually a protocol, then
|
|
|
|
- * compare unmodified paths; otherwise make paths relative */
|
|
|
|
- if (is_protocol || path_has_protocol(curr_bs->backing_file)) {
|
|
|
|
|
|
+ if (bdrv_backing_overridden(curr_bs)) {
|
|
|
|
+ /*
|
|
|
|
+ * If the backing file was overridden, we can only compare
|
|
|
|
+ * directly against the backing node's filename.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ if (!filenames_refreshed) {
|
|
|
|
+ /*
|
|
|
|
+ * This will automatically refresh all of the
|
|
|
|
+ * filenames in the rest of the backing chain, so we
|
|
|
|
+ * only need to do this once.
|
|
|
|
+ */
|
|
|
|
+ bdrv_refresh_filename(bs_below);
|
|
|
|
+ filenames_refreshed = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (strcmp(backing_file, bs_below->filename) == 0) {
|
|
|
|
+ retval = bs_below;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ } else if (is_protocol || path_has_protocol(curr_bs->backing_file)) {
|
|
|
|
+ /*
|
|
|
|
+ * If either of the filename paths is actually a protocol, then
|
|
|
|
+ * compare unmodified paths; otherwise make paths relative.
|
|
|
|
+ */
|
|
char *backing_file_full_ret;
|
|
char *backing_file_full_ret;
|
|
|
|
|
|
if (strcmp(backing_file, curr_bs->backing_file) == 0) {
|
|
if (strcmp(backing_file, curr_bs->backing_file) == 0) {
|
|
@@ -6820,7 +6839,7 @@ static bool append_strong_runtime_options(QDict *d, BlockDriverState *bs)
|
|
/* Note: This function may return false positives; it may return true
|
|
/* Note: This function may return false positives; it may return true
|
|
* even if opening the backing file specified by bs's image header
|
|
* even if opening the backing file specified by bs's image header
|
|
* would result in exactly bs->backing. */
|
|
* would result in exactly bs->backing. */
|
|
-static bool bdrv_backing_overridden(BlockDriverState *bs)
|
|
|
|
|
|
+bool bdrv_backing_overridden(BlockDriverState *bs)
|
|
{
|
|
{
|
|
if (bs->backing) {
|
|
if (bs->backing) {
|
|
return strcmp(bs->auto_backing_file,
|
|
return strcmp(bs->auto_backing_file,
|