block.c (313274bbd4677f44631921ef4366f4ffc81cc5d5) | block.c (d669ed6ab028497d634e1f236c74a98725f9e45f) |
---|---|
1/* 2 * QEMU System Emulator block driver 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights --- 4896 unchanged lines hidden (view full) --- 4905 * if active == top, that is considered an error 4906 * 4907 */ 4908int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base, 4909 const char *backing_file_str) 4910{ 4911 BlockDriverState *explicit_top = top; 4912 bool update_inherits_from; | 1/* 2 * QEMU System Emulator block driver 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights --- 4896 unchanged lines hidden (view full) --- 4905 * if active == top, that is considered an error 4906 * 4907 */ 4908int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base, 4909 const char *backing_file_str) 4910{ 4911 BlockDriverState *explicit_top = top; 4912 bool update_inherits_from; |
4913 BdrvChild *c, *next; | 4913 BdrvChild *c; |
4914 Error *local_err = NULL; 4915 int ret = -EIO; | 4914 Error *local_err = NULL; 4915 int ret = -EIO; |
4916 g_autoptr(GSList) updated_children = NULL; 4917 GSList *p; |
|
4916 4917 bdrv_ref(top); 4918 bdrv_subtree_drained_begin(top); 4919 4920 if (!top->drv || !base->drv) { 4921 goto exit; 4922 } 4923 4924 /* Make sure that base is in the backing chain of top */ 4925 if (!bdrv_chain_contains(top, base)) { 4926 goto exit; 4927 } 4928 | 4918 4919 bdrv_ref(top); 4920 bdrv_subtree_drained_begin(top); 4921 4922 if (!top->drv || !base->drv) { 4923 goto exit; 4924 } 4925 4926 /* Make sure that base is in the backing chain of top */ 4927 if (!bdrv_chain_contains(top, base)) { 4928 goto exit; 4929 } 4930 |
4929 /* This function changes all links that point to top and makes 4930 * them point to base. Check that none of them is frozen. */ 4931 QLIST_FOREACH(c, &top->parents, next_parent) { 4932 if (c->frozen) { 4933 goto exit; 4934 } 4935 } 4936 | |
4937 /* If 'base' recursively inherits from 'top' then we should set 4938 * base->inherits_from to top->inherits_from after 'top' and all 4939 * other intermediate nodes have been dropped. 4940 * If 'top' is an implicit node (e.g. "commit_top") we should skip 4941 * it because no one inherits from it. We use explicit_top for that. */ 4942 explicit_top = bdrv_skip_implicit_filters(explicit_top); 4943 update_inherits_from = bdrv_inherits_from_recursive(base, explicit_top); 4944 4945 /* success - we can delete the intermediate states, and link top->base */ 4946 /* TODO Check graph modification op blockers (BLK_PERM_GRAPH_MOD) once 4947 * we've figured out how they should work. */ 4948 if (!backing_file_str) { 4949 bdrv_refresh_filename(base); 4950 backing_file_str = base->filename; 4951 } 4952 | 4931 /* If 'base' recursively inherits from 'top' then we should set 4932 * base->inherits_from to top->inherits_from after 'top' and all 4933 * other intermediate nodes have been dropped. 4934 * If 'top' is an implicit node (e.g. "commit_top") we should skip 4935 * it because no one inherits from it. We use explicit_top for that. */ 4936 explicit_top = bdrv_skip_implicit_filters(explicit_top); 4937 update_inherits_from = bdrv_inherits_from_recursive(base, explicit_top); 4938 4939 /* success - we can delete the intermediate states, and link top->base */ 4940 /* TODO Check graph modification op blockers (BLK_PERM_GRAPH_MOD) once 4941 * we've figured out how they should work. */ 4942 if (!backing_file_str) { 4943 bdrv_refresh_filename(base); 4944 backing_file_str = base->filename; 4945 } 4946 |
4953 QLIST_FOREACH_SAFE(c, &top->parents, next_parent, next) { 4954 /* Check whether we are allowed to switch c from top to base */ 4955 GSList *ignore_children = g_slist_prepend(NULL, c); 4956 ret = bdrv_check_update_perm(base, NULL, c->perm, c->shared_perm, 4957 ignore_children, NULL, &local_err); 4958 g_slist_free(ignore_children); 4959 if (ret < 0) { 4960 error_report_err(local_err); 4961 goto exit; 4962 } | 4947 QLIST_FOREACH(c, &top->parents, next_parent) { 4948 updated_children = g_slist_prepend(updated_children, c); 4949 } |
4963 | 4950 |
4964 /* If so, update the backing file path in the image file */ | 4951 bdrv_replace_node_common(top, base, false, &local_err); 4952 if (local_err) { 4953 error_report_err(local_err); 4954 goto exit; 4955 } 4956 4957 for (p = updated_children; p; p = p->next) { 4958 c = p->data; 4959 |
4965 if (c->klass->update_filename) { 4966 ret = c->klass->update_filename(c, base, backing_file_str, 4967 &local_err); 4968 if (ret < 0) { | 4960 if (c->klass->update_filename) { 4961 ret = c->klass->update_filename(c, base, backing_file_str, 4962 &local_err); 4963 if (ret < 0) { |
4969 bdrv_abort_perm_update(base); | 4964 /* 4965 * TODO: Actually, we want to rollback all previous iterations 4966 * of this loop, and (which is almost impossible) previous 4967 * bdrv_replace_node()... 4968 * 4969 * Note, that c->klass->update_filename may lead to permission 4970 * update, so it's a bad idea to call it inside permission 4971 * update transaction of bdrv_replace_node. 4972 */ |
4970 error_report_err(local_err); 4971 goto exit; 4972 } 4973 } | 4973 error_report_err(local_err); 4974 goto exit; 4975 } 4976 } |
4974 4975 /* 4976 * Do the actual switch in the in-memory graph. 4977 * Completes bdrv_check_update_perm() transaction internally. 4978 * c->frozen is false, we have checked that above. 4979 */ 4980 bdrv_ref(base); 4981 bdrv_replace_child(c, base); 4982 bdrv_unref(top); | |
4983 } 4984 4985 if (update_inherits_from) { 4986 base->inherits_from = explicit_top->inherits_from; 4987 } 4988 4989 ret = 0; 4990exit: --- 2260 unchanged lines hidden --- | 4977 } 4978 4979 if (update_inherits_from) { 4980 base->inherits_from = explicit_top->inherits_from; 4981 } 4982 4983 ret = 0; 4984exit: --- 2260 unchanged lines hidden --- |