qcow2: Mark qcow2_signal_corruption() and callers GRAPH_RDLOCK
This adds GRAPH_RDLOCK annotations to declare that callers of qcow2_signal_corruption() need to hold a reader lock for the graph because it calls bdrv_get_node_name(), which accesses the parents list of a node. For some places, we know that they will hold the lock, but we don't have the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock() with a FIXME comment. These places will be removed once everything is properly annotated. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Message-ID: <20230929145157.45443-15-kwolf@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
bd131d6705
commit
0bb79c97fd
3
block.c
3
block.c
@ -7250,7 +7250,8 @@ bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp)
|
|||||||
{
|
{
|
||||||
BdrvOpBlocker *blocker;
|
BdrvOpBlocker *blocker;
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
|
||||||
|
assume_graph_lock(); /* FIXME */
|
||||||
|
|
||||||
assert((int) op >= 0 && op < BLOCK_OP_TYPE_MAX);
|
assert((int) op >= 0 && op < BLOCK_OP_TYPE_MAX);
|
||||||
if (!QLIST_EMPTY(&bs->op_blockers[op])) {
|
if (!QLIST_EMPTY(&bs->op_blockers[op])) {
|
||||||
|
@ -2905,6 +2905,8 @@ const BdrvChild *blk_root(BlockBackend *blk)
|
|||||||
int blk_make_empty(BlockBackend *blk, Error **errp)
|
int blk_make_empty(BlockBackend *blk, Error **errp)
|
||||||
{
|
{
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||||
|
|
||||||
if (!blk_is_available(blk)) {
|
if (!blk_is_available(blk)) {
|
||||||
error_setg(errp, "No medium inserted");
|
error_setg(errp, "No medium inserted");
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
|
@ -206,8 +206,9 @@ static int check_constraints_on_bitmap(BlockDriverState *bs,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_bitmap_table(BlockDriverState *bs, uint64_t *bitmap_table,
|
static void GRAPH_RDLOCK
|
||||||
uint32_t bitmap_table_size)
|
clear_bitmap_table(BlockDriverState *bs, uint64_t *bitmap_table,
|
||||||
|
uint32_t bitmap_table_size)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int i;
|
int i;
|
||||||
@ -261,7 +262,8 @@ fail:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int free_bitmap_clusters(BlockDriverState *bs, Qcow2BitmapTable *tb)
|
static int GRAPH_RDLOCK
|
||||||
|
free_bitmap_clusters(BlockDriverState *bs, Qcow2BitmapTable *tb)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
uint64_t *bitmap_table;
|
uint64_t *bitmap_table;
|
||||||
@ -732,8 +734,9 @@ out:
|
|||||||
* Store bitmap list to qcow2 image as a bitmap directory.
|
* Store bitmap list to qcow2 image as a bitmap directory.
|
||||||
* Everything is checked.
|
* Everything is checked.
|
||||||
*/
|
*/
|
||||||
static int bitmap_list_store(BlockDriverState *bs, Qcow2BitmapList *bm_list,
|
static int GRAPH_RDLOCK
|
||||||
uint64_t *offset, uint64_t *size, bool in_place)
|
bitmap_list_store(BlockDriverState *bs, Qcow2BitmapList *bm_list,
|
||||||
|
uint64_t *offset, uint64_t *size, bool in_place)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
uint8_t *dir;
|
uint8_t *dir;
|
||||||
@ -831,8 +834,9 @@ fail:
|
|||||||
* Bitmap List end
|
* Bitmap List end
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int update_ext_header_and_dir_in_place(BlockDriverState *bs,
|
static int GRAPH_RDLOCK
|
||||||
Qcow2BitmapList *bm_list)
|
update_ext_header_and_dir_in_place(BlockDriverState *bs,
|
||||||
|
Qcow2BitmapList *bm_list)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int ret;
|
int ret;
|
||||||
@ -879,8 +883,8 @@ static int update_ext_header_and_dir_in_place(BlockDriverState *bs,
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static int update_ext_header_and_dir(BlockDriverState *bs,
|
static int GRAPH_RDLOCK
|
||||||
Qcow2BitmapList *bm_list)
|
update_ext_header_and_dir(BlockDriverState *bs, Qcow2BitmapList *bm_list)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int ret;
|
int ret;
|
||||||
@ -1273,9 +1277,9 @@ out:
|
|||||||
/* store_bitmap_data()
|
/* store_bitmap_data()
|
||||||
* Store bitmap to image, filling bitmap table accordingly.
|
* Store bitmap to image, filling bitmap table accordingly.
|
||||||
*/
|
*/
|
||||||
static uint64_t *store_bitmap_data(BlockDriverState *bs,
|
static uint64_t * GRAPH_RDLOCK
|
||||||
BdrvDirtyBitmap *bitmap,
|
store_bitmap_data(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
|
||||||
uint32_t *bitmap_table_size, Error **errp)
|
uint32_t *bitmap_table_size, Error **errp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
@ -1372,7 +1376,8 @@ fail:
|
|||||||
* Store bm->dirty_bitmap to qcow2.
|
* Store bm->dirty_bitmap to qcow2.
|
||||||
* Set bm->table_offset and bm->table_size accordingly.
|
* Set bm->table_offset and bm->table_size accordingly.
|
||||||
*/
|
*/
|
||||||
static int store_bitmap(BlockDriverState *bs, Qcow2Bitmap *bm, Error **errp)
|
static int GRAPH_RDLOCK
|
||||||
|
store_bitmap(BlockDriverState *bs, Qcow2Bitmap *bm, Error **errp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
uint64_t *tb;
|
uint64_t *tb;
|
||||||
|
@ -163,7 +163,8 @@ int qcow2_cache_destroy(Qcow2Cache *c)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow2_cache_flush_dependency(BlockDriverState *bs, Qcow2Cache *c)
|
static int GRAPH_RDLOCK
|
||||||
|
qcow2_cache_flush_dependency(BlockDriverState *bs, Qcow2Cache *c)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -178,7 +179,8 @@ static int qcow2_cache_flush_dependency(BlockDriverState *bs, Qcow2Cache *c)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
|
static int GRAPH_RDLOCK
|
||||||
|
qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -318,8 +320,9 @@ int qcow2_cache_empty(BlockDriverState *bs, Qcow2Cache *c)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow2_cache_do_get(BlockDriverState *bs, Qcow2Cache *c,
|
static int GRAPH_RDLOCK
|
||||||
uint64_t offset, void **table, bool read_from_disk)
|
qcow2_cache_do_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
|
||||||
|
void **table, bool read_from_disk)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int i;
|
int i;
|
||||||
|
@ -207,8 +207,9 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
|
|||||||
* the cache is used; otherwise the L2 slice is loaded from the image
|
* the cache is used; otherwise the L2 slice is loaded from the image
|
||||||
* file.
|
* file.
|
||||||
*/
|
*/
|
||||||
static int l2_load(BlockDriverState *bs, uint64_t offset,
|
static int GRAPH_RDLOCK
|
||||||
uint64_t l2_offset, uint64_t **l2_slice)
|
l2_load(BlockDriverState *bs, uint64_t offset,
|
||||||
|
uint64_t l2_offset, uint64_t **l2_slice)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int start_of_slice = l2_entry_size(s) *
|
int start_of_slice = l2_entry_size(s) *
|
||||||
@ -269,7 +270,7 @@ int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int l2_allocate(BlockDriverState *bs, int l1_index)
|
static int GRAPH_RDLOCK l2_allocate(BlockDriverState *bs, int l1_index)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
uint64_t old_l2_offset;
|
uint64_t old_l2_offset;
|
||||||
@ -751,9 +752,9 @@ fail:
|
|||||||
*
|
*
|
||||||
* Returns 0 on success, -errno in failure case
|
* Returns 0 on success, -errno in failure case
|
||||||
*/
|
*/
|
||||||
static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
|
static int GRAPH_RDLOCK
|
||||||
uint64_t **new_l2_slice,
|
get_cluster_table(BlockDriverState *bs, uint64_t offset,
|
||||||
int *new_l2_index)
|
uint64_t **new_l2_slice, int *new_l2_index)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
unsigned int l2_index;
|
unsigned int l2_index;
|
||||||
@ -1155,11 +1156,10 @@ void coroutine_fn qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m)
|
|||||||
*
|
*
|
||||||
* Returns 0 on success, -errno on failure.
|
* Returns 0 on success, -errno on failure.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn calculate_l2_meta(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t host_cluster_offset,
|
calculate_l2_meta(BlockDriverState *bs, uint64_t host_cluster_offset,
|
||||||
uint64_t guest_offset, unsigned bytes,
|
uint64_t guest_offset, unsigned bytes, uint64_t *l2_slice,
|
||||||
uint64_t *l2_slice, QCowL2Meta **m,
|
QCowL2Meta **m, bool keep_old)
|
||||||
bool keep_old)
|
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int sc_index, l2_index = offset_to_l2_slice_index(s, guest_offset);
|
int sc_index, l2_index = offset_to_l2_slice_index(s, guest_offset);
|
||||||
@ -1490,9 +1490,9 @@ static int coroutine_fn handle_dependencies(BlockDriverState *bs,
|
|||||||
*
|
*
|
||||||
* -errno: in error cases
|
* -errno: in error cases
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn handle_copied(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t guest_offset, uint64_t *host_offset, uint64_t *bytes,
|
handle_copied(BlockDriverState *bs, uint64_t guest_offset,
|
||||||
QCowL2Meta **m)
|
uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int l2_index;
|
int l2_index;
|
||||||
@ -1600,10 +1600,9 @@ out:
|
|||||||
* function has been waiting for another request and the allocation must be
|
* function has been waiting for another request and the allocation must be
|
||||||
* restarted, but the whole request should not be failed.
|
* restarted, but the whole request should not be failed.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn do_alloc_cluster_offset(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t guest_offset,
|
do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset,
|
||||||
uint64_t *host_offset,
|
uint64_t *host_offset, uint64_t *nb_clusters)
|
||||||
uint64_t *nb_clusters)
|
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
|
||||||
@ -1658,9 +1657,9 @@ static int coroutine_fn do_alloc_cluster_offset(BlockDriverState *bs,
|
|||||||
*
|
*
|
||||||
* -errno: in error cases
|
* -errno: in error cases
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn handle_alloc(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t guest_offset, uint64_t *host_offset, uint64_t *bytes,
|
handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
|
||||||
QCowL2Meta **m)
|
uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int l2_index;
|
int l2_index;
|
||||||
@ -1898,9 +1897,9 @@ again:
|
|||||||
* all clusters in the same L2 slice) and returns the number of discarded
|
* all clusters in the same L2 slice) and returns the number of discarded
|
||||||
* clusters.
|
* clusters.
|
||||||
*/
|
*/
|
||||||
static int discard_in_l2_slice(BlockDriverState *bs, uint64_t offset,
|
static int GRAPH_RDLOCK
|
||||||
uint64_t nb_clusters,
|
discard_in_l2_slice(BlockDriverState *bs, uint64_t offset, uint64_t nb_clusters,
|
||||||
enum qcow2_discard_type type, bool full_discard)
|
enum qcow2_discard_type type, bool full_discard)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
uint64_t *l2_slice;
|
uint64_t *l2_slice;
|
||||||
@ -2037,7 +2036,7 @@ fail:
|
|||||||
* all clusters in the same L2 slice) and returns the number of zeroed
|
* all clusters in the same L2 slice) and returns the number of zeroed
|
||||||
* clusters.
|
* clusters.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
zero_in_l2_slice(BlockDriverState *bs, uint64_t offset,
|
zero_in_l2_slice(BlockDriverState *bs, uint64_t offset,
|
||||||
uint64_t nb_clusters, int flags)
|
uint64_t nb_clusters, int flags)
|
||||||
{
|
{
|
||||||
@ -2093,7 +2092,7 @@ zero_in_l2_slice(BlockDriverState *bs, uint64_t offset,
|
|||||||
return nb_clusters;
|
return nb_clusters;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
zero_l2_subclusters(BlockDriverState *bs, uint64_t offset,
|
zero_l2_subclusters(BlockDriverState *bs, uint64_t offset,
|
||||||
unsigned nb_subclusters)
|
unsigned nb_subclusters)
|
||||||
{
|
{
|
||||||
@ -2231,11 +2230,12 @@ fail:
|
|||||||
* status_cb(). l1_entries contains the total number of L1 entries and
|
* status_cb(). l1_entries contains the total number of L1 entries and
|
||||||
* *visited_l1_entries counts all visited L1 entries.
|
* *visited_l1_entries counts all visited L1 entries.
|
||||||
*/
|
*/
|
||||||
static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
|
static int GRAPH_RDLOCK
|
||||||
int l1_size, int64_t *visited_l1_entries,
|
expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
|
||||||
int64_t l1_entries,
|
int l1_size, int64_t *visited_l1_entries,
|
||||||
BlockDriverAmendStatusCB *status_cb,
|
int64_t l1_entries,
|
||||||
void *cb_opaque)
|
BlockDriverAmendStatusCB *status_cb,
|
||||||
|
void *cb_opaque)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
bool is_active_l1 = (l1_table == s->l1_table);
|
bool is_active_l1 = (l1_table == s->l1_table);
|
||||||
|
@ -229,9 +229,9 @@ static void set_refcount_ro6(void *refcount_array, uint64_t index,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int load_refcount_block(BlockDriverState *bs,
|
static int GRAPH_RDLOCK
|
||||||
int64_t refcount_block_offset,
|
load_refcount_block(BlockDriverState *bs, int64_t refcount_block_offset,
|
||||||
void **refcount_block)
|
void **refcount_block)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
|
||||||
@ -302,8 +302,9 @@ static int in_same_refcount_block(BDRVQcow2State *s, uint64_t offset_a,
|
|||||||
*
|
*
|
||||||
* Returns 0 on success or -errno in error case
|
* Returns 0 on success or -errno in error case
|
||||||
*/
|
*/
|
||||||
static int alloc_refcount_block(BlockDriverState *bs,
|
static int GRAPH_RDLOCK
|
||||||
int64_t cluster_index, void **refcount_block)
|
alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index,
|
||||||
|
void **refcount_block)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
unsigned int refcount_table_index;
|
unsigned int refcount_table_index;
|
||||||
@ -806,12 +807,9 @@ found:
|
|||||||
/* XXX: cache several refcount block clusters ? */
|
/* XXX: cache several refcount block clusters ? */
|
||||||
/* @addend is the absolute value of the addend; if @decrease is set, @addend
|
/* @addend is the absolute value of the addend; if @decrease is set, @addend
|
||||||
* will be subtracted from the current refcount, otherwise it will be added */
|
* will be subtracted from the current refcount, otherwise it will be added */
|
||||||
static int update_refcount(BlockDriverState *bs,
|
static int GRAPH_RDLOCK
|
||||||
int64_t offset,
|
update_refcount(BlockDriverState *bs, int64_t offset, int64_t length,
|
||||||
int64_t length,
|
uint64_t addend, bool decrease, enum qcow2_discard_type type)
|
||||||
uint64_t addend,
|
|
||||||
bool decrease,
|
|
||||||
enum qcow2_discard_type type)
|
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int64_t start, last, cluster_offset;
|
int64_t start, last, cluster_offset;
|
||||||
@ -967,8 +965,8 @@ int qcow2_update_cluster_refcount(BlockDriverState *bs,
|
|||||||
|
|
||||||
|
|
||||||
/* return < 0 if error */
|
/* return < 0 if error */
|
||||||
static int64_t alloc_clusters_noref(BlockDriverState *bs, uint64_t size,
|
static int64_t GRAPH_RDLOCK
|
||||||
uint64_t max)
|
alloc_clusters_noref(BlockDriverState *bs, uint64_t size, uint64_t max)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
uint64_t i, nb_clusters, refcount;
|
uint64_t i, nb_clusters, refcount;
|
||||||
@ -2302,7 +2300,7 @@ calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
|
|||||||
* Compares the actual reference count for each cluster in the image against the
|
* Compares the actual reference count for each cluster in the image against the
|
||||||
* refcount as reported by the refcount structures on-disk.
|
* refcount as reported by the refcount structures on-disk.
|
||||||
*/
|
*/
|
||||||
static void coroutine_fn
|
static void coroutine_fn GRAPH_RDLOCK
|
||||||
compare_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
|
compare_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
|
||||||
BdrvCheckMode fix, bool *rebuild,
|
BdrvCheckMode fix, bool *rebuild,
|
||||||
int64_t *highest_cluster,
|
int64_t *highest_cluster,
|
||||||
@ -3103,20 +3101,22 @@ int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
|
|||||||
*
|
*
|
||||||
* @allocated should be set to true if a new cluster has been allocated.
|
* @allocated should be set to true if a new cluster has been allocated.
|
||||||
*/
|
*/
|
||||||
typedef int (RefblockFinishOp)(BlockDriverState *bs, uint64_t **reftable,
|
typedef int /* GRAPH_RDLOCK_PTR */
|
||||||
uint64_t reftable_index, uint64_t *reftable_size,
|
(RefblockFinishOp)(BlockDriverState *bs, uint64_t **reftable,
|
||||||
void *refblock, bool refblock_empty,
|
uint64_t reftable_index, uint64_t *reftable_size,
|
||||||
bool *allocated, Error **errp);
|
void *refblock, bool refblock_empty,
|
||||||
|
bool *allocated, Error **errp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This "operation" for walk_over_reftable() allocates the refblock on disk (if
|
* This "operation" for walk_over_reftable() allocates the refblock on disk (if
|
||||||
* it is not empty) and inserts its offset into the new reftable. The size of
|
* it is not empty) and inserts its offset into the new reftable. The size of
|
||||||
* this new reftable is increased as required.
|
* this new reftable is increased as required.
|
||||||
*/
|
*/
|
||||||
static int alloc_refblock(BlockDriverState *bs, uint64_t **reftable,
|
static int GRAPH_RDLOCK
|
||||||
uint64_t reftable_index, uint64_t *reftable_size,
|
alloc_refblock(BlockDriverState *bs, uint64_t **reftable,
|
||||||
void *refblock, bool refblock_empty, bool *allocated,
|
uint64_t reftable_index, uint64_t *reftable_size,
|
||||||
Error **errp)
|
void *refblock, bool refblock_empty, bool *allocated,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
@ -3166,10 +3166,11 @@ static int alloc_refblock(BlockDriverState *bs, uint64_t **reftable,
|
|||||||
* offset specified by the new reftable's entry. It does not modify the new
|
* offset specified by the new reftable's entry. It does not modify the new
|
||||||
* reftable or change any refcounts.
|
* reftable or change any refcounts.
|
||||||
*/
|
*/
|
||||||
static int flush_refblock(BlockDriverState *bs, uint64_t **reftable,
|
static int GRAPH_RDLOCK
|
||||||
uint64_t reftable_index, uint64_t *reftable_size,
|
flush_refblock(BlockDriverState *bs, uint64_t **reftable,
|
||||||
void *refblock, bool refblock_empty, bool *allocated,
|
uint64_t reftable_index, uint64_t *reftable_size,
|
||||||
Error **errp)
|
void *refblock, bool refblock_empty, bool *allocated,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
@ -3210,16 +3211,17 @@ static int flush_refblock(BlockDriverState *bs, uint64_t **reftable,
|
|||||||
*
|
*
|
||||||
* @allocated is set to true if a new cluster has been allocated.
|
* @allocated is set to true if a new cluster has been allocated.
|
||||||
*/
|
*/
|
||||||
static int walk_over_reftable(BlockDriverState *bs, uint64_t **new_reftable,
|
static int GRAPH_RDLOCK
|
||||||
uint64_t *new_reftable_index,
|
walk_over_reftable(BlockDriverState *bs, uint64_t **new_reftable,
|
||||||
uint64_t *new_reftable_size,
|
uint64_t *new_reftable_index,
|
||||||
void *new_refblock, int new_refblock_size,
|
uint64_t *new_reftable_size,
|
||||||
int new_refcount_bits,
|
void *new_refblock, int new_refblock_size,
|
||||||
RefblockFinishOp *operation, bool *allocated,
|
int new_refcount_bits,
|
||||||
Qcow2SetRefcountFunc *new_set_refcount,
|
RefblockFinishOp *operation, bool *allocated,
|
||||||
BlockDriverAmendStatusCB *status_cb,
|
Qcow2SetRefcountFunc *new_set_refcount,
|
||||||
void *cb_opaque, int index, int total,
|
BlockDriverAmendStatusCB *status_cb,
|
||||||
Error **errp)
|
void *cb_opaque, int index, int total,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
uint64_t reftable_index;
|
uint64_t reftable_index;
|
||||||
@ -3545,8 +3547,8 @@ done:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t coroutine_fn get_refblock_offset(BlockDriverState *bs,
|
static int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
uint64_t offset)
|
get_refblock_offset(BlockDriverState *bs, uint64_t offset)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
uint32_t index = offset_to_reftable_index(s, offset);
|
uint32_t index = offset_to_reftable_index(s, offset);
|
||||||
@ -3565,7 +3567,7 @@ static int64_t coroutine_fn get_refblock_offset(BlockDriverState *bs,
|
|||||||
return covering_refblock_offset;
|
return covering_refblock_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_discard_refcount_block(BlockDriverState *bs, uint64_t discard_block_offs)
|
qcow2_discard_refcount_block(BlockDriverState *bs, uint64_t discard_block_offs)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
@ -536,7 +536,7 @@ int qcow2_mark_dirty(BlockDriverState *bs)
|
|||||||
* function when there are no pending requests, it does not guard against
|
* function when there are no pending requests, it does not guard against
|
||||||
* concurrent requests dirtying the image.
|
* concurrent requests dirtying the image.
|
||||||
*/
|
*/
|
||||||
static int qcow2_mark_clean(BlockDriverState *bs)
|
static int GRAPH_RDLOCK qcow2_mark_clean(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
|
||||||
@ -570,7 +570,8 @@ int qcow2_mark_corrupt(BlockDriverState *bs)
|
|||||||
* Marks the image as consistent, i.e., unsets the corrupt bit, and flushes
|
* Marks the image as consistent, i.e., unsets the corrupt bit, and flushes
|
||||||
* before if necessary.
|
* before if necessary.
|
||||||
*/
|
*/
|
||||||
static int coroutine_fn qcow2_mark_consistent(BlockDriverState *bs)
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
|
qcow2_mark_consistent(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
|
||||||
@ -980,10 +981,9 @@ typedef struct Qcow2ReopenState {
|
|||||||
QCryptoBlockOpenOptions *crypto_opts; /* Disk encryption runtime options */
|
QCryptoBlockOpenOptions *crypto_opts; /* Disk encryption runtime options */
|
||||||
} Qcow2ReopenState;
|
} Qcow2ReopenState;
|
||||||
|
|
||||||
static int qcow2_update_options_prepare(BlockDriverState *bs,
|
static int GRAPH_RDLOCK
|
||||||
Qcow2ReopenState *r,
|
qcow2_update_options_prepare(BlockDriverState *bs, Qcow2ReopenState *r,
|
||||||
QDict *options, int flags,
|
QDict *options, int flags, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
QemuOpts *opts = NULL;
|
QemuOpts *opts = NULL;
|
||||||
@ -1260,7 +1260,7 @@ static void qcow2_update_options_abort(BlockDriverState *bs,
|
|||||||
qapi_free_QCryptoBlockOpenOptions(r->crypto_opts);
|
qapi_free_QCryptoBlockOpenOptions(r->crypto_opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_update_options(BlockDriverState *bs, QDict *options, int flags,
|
qcow2_update_options(BlockDriverState *bs, QDict *options, int flags,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
@ -1969,13 +1969,17 @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
|
|||||||
bs->bl.pdiscard_alignment = s->cluster_size;
|
bs->bl.pdiscard_alignment = s->cluster_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow2_reopen_prepare(BDRVReopenState *state,
|
static int GRAPH_UNLOCKED
|
||||||
BlockReopenQueue *queue, Error **errp)
|
qcow2_reopen_prepare(BDRVReopenState *state,BlockReopenQueue *queue,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = state->bs->opaque;
|
BDRVQcow2State *s = state->bs->opaque;
|
||||||
Qcow2ReopenState *r;
|
Qcow2ReopenState *r;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
GLOBAL_STATE_CODE();
|
||||||
|
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||||
|
|
||||||
r = g_new0(Qcow2ReopenState, 1);
|
r = g_new0(Qcow2ReopenState, 1);
|
||||||
state->opaque = r;
|
state->opaque = r;
|
||||||
|
|
||||||
@ -2038,6 +2042,8 @@ static void qcow2_reopen_commit(BDRVReopenState *state)
|
|||||||
|
|
||||||
static void qcow2_reopen_commit_post(BDRVReopenState *state)
|
static void qcow2_reopen_commit_post(BDRVReopenState *state)
|
||||||
{
|
{
|
||||||
|
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||||
|
|
||||||
if (state->flags & BDRV_O_RDWR) {
|
if (state->flags & BDRV_O_RDWR) {
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
@ -4079,8 +4085,8 @@ qcow2_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,
|
static int coroutine_fn GRAPH_RDLOCK
|
||||||
int64_t offset, int64_t bytes)
|
qcow2_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
@ -4825,7 +4831,7 @@ fail:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int make_completely_empty(BlockDriverState *bs)
|
static int GRAPH_RDLOCK make_completely_empty(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
@ -4976,7 +4982,7 @@ fail:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow2_make_empty(BlockDriverState *bs)
|
static int GRAPH_RDLOCK qcow2_make_empty(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
uint64_t offset, end_offset;
|
uint64_t offset, end_offset;
|
||||||
@ -5020,7 +5026,7 @@ static int qcow2_make_empty(BlockDriverState *bs)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs)
|
static coroutine_fn GRAPH_RDLOCK int qcow2_co_flush_to_os(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int ret;
|
int ret;
|
||||||
@ -5369,7 +5375,7 @@ qcow2_co_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
|
|||||||
return bs->drv->bdrv_co_preadv_part(bs, offset, qiov->size, qiov, 0, 0);
|
return bs->drv->bdrv_co_preadv_part(bs, offset, qiov->size, qiov, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow2_has_compressed_clusters(BlockDriverState *bs)
|
static int GRAPH_RDLOCK qcow2_has_compressed_clusters(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
int64_t offset = 0;
|
int64_t offset = 0;
|
||||||
int64_t bytes = bdrv_getlength(bs);
|
int64_t bytes = bdrv_getlength(bs);
|
||||||
@ -5405,9 +5411,10 @@ static int qcow2_has_compressed_clusters(BlockDriverState *bs)
|
|||||||
* Downgrades an image's version. To achieve this, any incompatible features
|
* Downgrades an image's version. To achieve this, any incompatible features
|
||||||
* have to be removed.
|
* have to be removed.
|
||||||
*/
|
*/
|
||||||
static int qcow2_downgrade(BlockDriverState *bs, int target_version,
|
static int GRAPH_RDLOCK
|
||||||
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
|
qcow2_downgrade(BlockDriverState *bs, int target_version,
|
||||||
Error **errp)
|
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int current_version = s->qcow_version;
|
int current_version = s->qcow_version;
|
||||||
@ -5515,9 +5522,10 @@ static int qcow2_downgrade(BlockDriverState *bs, int target_version,
|
|||||||
* features of older versions, some things may have to be presented
|
* features of older versions, some things may have to be presented
|
||||||
* differently.
|
* differently.
|
||||||
*/
|
*/
|
||||||
static int qcow2_upgrade(BlockDriverState *bs, int target_version,
|
static int GRAPH_RDLOCK
|
||||||
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
|
qcow2_upgrade(BlockDriverState *bs, int target_version,
|
||||||
Error **errp)
|
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
bool need_snapshot_update;
|
bool need_snapshot_update;
|
||||||
@ -5643,11 +5651,10 @@ static void qcow2_amend_helper_cb(BlockDriverState *bs,
|
|||||||
info->original_cb_opaque);
|
info->original_cb_opaque);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
|
static int GRAPH_RDLOCK
|
||||||
BlockDriverAmendStatusCB *status_cb,
|
qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
|
||||||
void *cb_opaque,
|
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
|
||||||
bool force,
|
bool force, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int old_version = s->qcow_version, new_version = old_version;
|
int old_version = s->qcow_version, new_version = old_version;
|
||||||
@ -5947,8 +5954,6 @@ void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
|
|||||||
char *message;
|
char *message;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
assume_graph_lock(); /* FIXME */
|
|
||||||
|
|
||||||
fatal = fatal && bdrv_is_writable(bs);
|
fatal = fatal && bdrv_is_writable(bs);
|
||||||
|
|
||||||
if (s->signaled_corruption &&
|
if (s->signaled_corruption &&
|
||||||
|
178
block/qcow2.h
178
block/qcow2.h
@ -838,9 +838,10 @@ int qcow2_mark_dirty(BlockDriverState *bs);
|
|||||||
int qcow2_mark_corrupt(BlockDriverState *bs);
|
int qcow2_mark_corrupt(BlockDriverState *bs);
|
||||||
int qcow2_update_header(BlockDriverState *bs);
|
int qcow2_update_header(BlockDriverState *bs);
|
||||||
|
|
||||||
void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
|
void GRAPH_RDLOCK
|
||||||
int64_t size, const char *message_format, ...)
|
qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
|
||||||
G_GNUC_PRINTF(5, 6);
|
int64_t size, const char *message_format, ...)
|
||||||
|
G_GNUC_PRINTF(5, 6);
|
||||||
|
|
||||||
int qcow2_validate_table(BlockDriverState *bs, uint64_t offset,
|
int qcow2_validate_table(BlockDriverState *bs, uint64_t offset,
|
||||||
uint64_t entries, size_t entry_len,
|
uint64_t entries, size_t entry_len,
|
||||||
@ -851,33 +852,41 @@ int qcow2_validate_table(BlockDriverState *bs, uint64_t offset,
|
|||||||
int coroutine_fn GRAPH_RDLOCK qcow2_refcount_init(BlockDriverState *bs);
|
int coroutine_fn GRAPH_RDLOCK qcow2_refcount_init(BlockDriverState *bs);
|
||||||
void qcow2_refcount_close(BlockDriverState *bs);
|
void qcow2_refcount_close(BlockDriverState *bs);
|
||||||
|
|
||||||
int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index,
|
int GRAPH_RDLOCK qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index,
|
||||||
uint64_t *refcount);
|
uint64_t *refcount);
|
||||||
|
|
||||||
int qcow2_update_cluster_refcount(BlockDriverState *bs, int64_t cluster_index,
|
int GRAPH_RDLOCK
|
||||||
uint64_t addend, bool decrease,
|
qcow2_update_cluster_refcount(BlockDriverState *bs, int64_t cluster_index,
|
||||||
enum qcow2_discard_type type);
|
uint64_t addend, bool decrease,
|
||||||
|
enum qcow2_discard_type type);
|
||||||
|
|
||||||
int64_t qcow2_refcount_area(BlockDriverState *bs, uint64_t offset,
|
int64_t GRAPH_RDLOCK
|
||||||
uint64_t additional_clusters, bool exact_size,
|
qcow2_refcount_area(BlockDriverState *bs, uint64_t offset,
|
||||||
int new_refblock_index,
|
uint64_t additional_clusters, bool exact_size,
|
||||||
uint64_t new_refblock_offset);
|
int new_refblock_index,
|
||||||
|
uint64_t new_refblock_offset);
|
||||||
|
|
||||||
|
int64_t GRAPH_RDLOCK
|
||||||
|
qcow2_alloc_clusters(BlockDriverState *bs, uint64_t size);
|
||||||
|
|
||||||
|
int64_t GRAPH_RDLOCK coroutine_fn
|
||||||
|
qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
|
||||||
|
int64_t nb_clusters);
|
||||||
|
|
||||||
int64_t qcow2_alloc_clusters(BlockDriverState *bs, uint64_t size);
|
|
||||||
int64_t coroutine_fn qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
|
|
||||||
int64_t nb_clusters);
|
|
||||||
int64_t coroutine_fn GRAPH_RDLOCK qcow2_alloc_bytes(BlockDriverState *bs, int size);
|
int64_t coroutine_fn GRAPH_RDLOCK qcow2_alloc_bytes(BlockDriverState *bs, int size);
|
||||||
void qcow2_free_clusters(BlockDriverState *bs,
|
void GRAPH_RDLOCK qcow2_free_clusters(BlockDriverState *bs,
|
||||||
int64_t offset, int64_t size,
|
int64_t offset, int64_t size,
|
||||||
enum qcow2_discard_type type);
|
enum qcow2_discard_type type);
|
||||||
void qcow2_free_any_cluster(BlockDriverState *bs, uint64_t l2_entry,
|
void GRAPH_RDLOCK
|
||||||
enum qcow2_discard_type type);
|
qcow2_free_any_cluster(BlockDriverState *bs, uint64_t l2_entry,
|
||||||
|
enum qcow2_discard_type type);
|
||||||
|
|
||||||
int qcow2_update_snapshot_refcount(BlockDriverState *bs,
|
int GRAPH_RDLOCK
|
||||||
int64_t l1_table_offset, int l1_size, int addend);
|
qcow2_update_snapshot_refcount(BlockDriverState *bs, int64_t l1_table_offset,
|
||||||
|
int l1_size, int addend);
|
||||||
|
|
||||||
int qcow2_flush_caches(BlockDriverState *bs);
|
int GRAPH_RDLOCK qcow2_flush_caches(BlockDriverState *bs);
|
||||||
int qcow2_write_caches(BlockDriverState *bs);
|
int GRAPH_RDLOCK qcow2_write_caches(BlockDriverState *bs);
|
||||||
int coroutine_fn qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
|
int coroutine_fn qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
|
||||||
BdrvCheckMode fix);
|
BdrvCheckMode fix);
|
||||||
|
|
||||||
@ -885,39 +894,48 @@ void qcow2_process_discards(BlockDriverState *bs, int ret);
|
|||||||
|
|
||||||
int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
|
int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
|
||||||
int64_t size);
|
int64_t size);
|
||||||
int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
|
int GRAPH_RDLOCK
|
||||||
int64_t size, bool data_file);
|
qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
|
||||||
|
int64_t size, bool data_file);
|
||||||
|
|
||||||
int coroutine_fn qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
|
int coroutine_fn qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
|
||||||
void **refcount_table,
|
void **refcount_table,
|
||||||
int64_t *refcount_table_size,
|
int64_t *refcount_table_size,
|
||||||
int64_t offset, int64_t size);
|
int64_t offset, int64_t size);
|
||||||
|
|
||||||
int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
|
int GRAPH_RDLOCK
|
||||||
BlockDriverAmendStatusCB *status_cb,
|
qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
|
||||||
void *cb_opaque, Error **errp);
|
BlockDriverAmendStatusCB *status_cb,
|
||||||
|
void *cb_opaque, Error **errp);
|
||||||
int coroutine_fn GRAPH_RDLOCK qcow2_shrink_reftable(BlockDriverState *bs);
|
int coroutine_fn GRAPH_RDLOCK qcow2_shrink_reftable(BlockDriverState *bs);
|
||||||
int64_t coroutine_fn qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
|
|
||||||
|
int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
|
qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
|
||||||
|
|
||||||
int coroutine_fn GRAPH_RDLOCK
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_detect_metadata_preallocation(BlockDriverState *bs);
|
qcow2_detect_metadata_preallocation(BlockDriverState *bs);
|
||||||
|
|
||||||
/* qcow2-cluster.c functions */
|
/* qcow2-cluster.c functions */
|
||||||
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
|
int GRAPH_RDLOCK
|
||||||
bool exact_size);
|
qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size, bool exact_size);
|
||||||
|
|
||||||
int coroutine_fn GRAPH_RDLOCK
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
|
qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
|
||||||
|
|
||||||
int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
|
int GRAPH_RDLOCK qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
|
||||||
int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
|
int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
|
||||||
uint8_t *buf, int nb_sectors, bool enc, Error **errp);
|
uint8_t *buf, int nb_sectors, bool enc, Error **errp);
|
||||||
|
|
||||||
int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,
|
int GRAPH_RDLOCK
|
||||||
unsigned int *bytes, uint64_t *host_offset,
|
qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,
|
||||||
QCow2SubclusterType *subcluster_type);
|
unsigned int *bytes, uint64_t *host_offset,
|
||||||
int coroutine_fn qcow2_alloc_host_offset(BlockDriverState *bs, uint64_t offset,
|
QCow2SubclusterType *subcluster_type);
|
||||||
unsigned int *bytes,
|
|
||||||
uint64_t *host_offset, QCowL2Meta **m);
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
|
qcow2_alloc_host_offset(BlockDriverState *bs, uint64_t offset,
|
||||||
|
unsigned int *bytes, uint64_t *host_offset,
|
||||||
|
QCowL2Meta **m);
|
||||||
|
|
||||||
int coroutine_fn GRAPH_RDLOCK
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, uint64_t offset,
|
qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, uint64_t offset,
|
||||||
int compressed_size, uint64_t *host_offset);
|
int compressed_size, uint64_t *host_offset);
|
||||||
@ -927,26 +945,33 @@ void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
|
|||||||
int coroutine_fn GRAPH_RDLOCK
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
|
qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
|
||||||
|
|
||||||
void coroutine_fn qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
|
void coroutine_fn GRAPH_RDLOCK
|
||||||
int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset,
|
qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
|
||||||
uint64_t bytes, enum qcow2_discard_type type,
|
|
||||||
bool full_discard);
|
int GRAPH_RDLOCK
|
||||||
|
qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
||||||
|
enum qcow2_discard_type type, bool full_discard);
|
||||||
|
|
||||||
int coroutine_fn GRAPH_RDLOCK
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
int qcow2_expand_zero_clusters(BlockDriverState *bs,
|
int GRAPH_RDLOCK
|
||||||
BlockDriverAmendStatusCB *status_cb,
|
qcow2_expand_zero_clusters(BlockDriverState *bs,
|
||||||
void *cb_opaque);
|
BlockDriverAmendStatusCB *status_cb,
|
||||||
|
void *cb_opaque);
|
||||||
|
|
||||||
/* qcow2-snapshot.c functions */
|
/* qcow2-snapshot.c functions */
|
||||||
int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info);
|
int GRAPH_RDLOCK
|
||||||
int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id);
|
qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info);
|
||||||
int qcow2_snapshot_delete(BlockDriverState *bs,
|
|
||||||
const char *snapshot_id,
|
int GRAPH_RDLOCK
|
||||||
const char *name,
|
qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id);
|
||||||
Error **errp);
|
|
||||||
|
int GRAPH_RDLOCK
|
||||||
|
qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id,
|
||||||
|
const char *name, Error **errp);
|
||||||
|
|
||||||
int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab);
|
int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab);
|
||||||
int qcow2_snapshot_load_tmp(BlockDriverState *bs,
|
int qcow2_snapshot_load_tmp(BlockDriverState *bs,
|
||||||
const char *snapshot_id,
|
const char *snapshot_id,
|
||||||
@ -956,15 +981,15 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs,
|
|||||||
void qcow2_free_snapshots(BlockDriverState *bs);
|
void qcow2_free_snapshots(BlockDriverState *bs);
|
||||||
int coroutine_fn GRAPH_RDLOCK
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_read_snapshots(BlockDriverState *bs, Error **errp);
|
qcow2_read_snapshots(BlockDriverState *bs, Error **errp);
|
||||||
int qcow2_write_snapshots(BlockDriverState *bs);
|
int GRAPH_RDLOCK qcow2_write_snapshots(BlockDriverState *bs);
|
||||||
|
|
||||||
int coroutine_fn GRAPH_RDLOCK
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_check_read_snapshot_table(BlockDriverState *bs, BdrvCheckResult *result,
|
qcow2_check_read_snapshot_table(BlockDriverState *bs, BdrvCheckResult *result,
|
||||||
BdrvCheckMode fix);
|
BdrvCheckMode fix);
|
||||||
|
|
||||||
int coroutine_fn qcow2_check_fix_snapshot_table(BlockDriverState *bs,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
BdrvCheckResult *result,
|
qcow2_check_fix_snapshot_table(BlockDriverState *bs, BdrvCheckResult *result,
|
||||||
BdrvCheckMode fix);
|
BdrvCheckMode fix);
|
||||||
|
|
||||||
/* qcow2-cache.c functions */
|
/* qcow2-cache.c functions */
|
||||||
Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables,
|
Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables,
|
||||||
@ -972,19 +997,23 @@ Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables,
|
|||||||
int qcow2_cache_destroy(Qcow2Cache *c);
|
int qcow2_cache_destroy(Qcow2Cache *c);
|
||||||
|
|
||||||
void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table);
|
void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table);
|
||||||
int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c);
|
int GRAPH_RDLOCK qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c);
|
||||||
int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c);
|
int GRAPH_RDLOCK qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c);
|
||||||
int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c,
|
int GRAPH_RDLOCK qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c,
|
||||||
Qcow2Cache *dependency);
|
Qcow2Cache *dependency);
|
||||||
void qcow2_cache_depends_on_flush(Qcow2Cache *c);
|
void qcow2_cache_depends_on_flush(Qcow2Cache *c);
|
||||||
|
|
||||||
void qcow2_cache_clean_unused(Qcow2Cache *c);
|
void qcow2_cache_clean_unused(Qcow2Cache *c);
|
||||||
int qcow2_cache_empty(BlockDriverState *bs, Qcow2Cache *c);
|
int GRAPH_RDLOCK qcow2_cache_empty(BlockDriverState *bs, Qcow2Cache *c);
|
||||||
|
|
||||||
|
int GRAPH_RDLOCK
|
||||||
|
qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
|
||||||
|
void **table);
|
||||||
|
|
||||||
|
int GRAPH_RDLOCK
|
||||||
|
qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
|
||||||
|
void **table);
|
||||||
|
|
||||||
int qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
|
|
||||||
void **table);
|
|
||||||
int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
|
|
||||||
void **table);
|
|
||||||
void qcow2_cache_put(Qcow2Cache *c, void **table);
|
void qcow2_cache_put(Qcow2Cache *c, void **table);
|
||||||
void *qcow2_cache_is_table_offset(Qcow2Cache *c, uint64_t offset);
|
void *qcow2_cache_is_table_offset(Qcow2Cache *c, uint64_t offset);
|
||||||
void qcow2_cache_discard(Qcow2Cache *c, void *table);
|
void qcow2_cache_discard(Qcow2Cache *c, void *table);
|
||||||
@ -998,17 +1027,22 @@ bool coroutine_fn GRAPH_RDLOCK
|
|||||||
qcow2_load_dirty_bitmaps(BlockDriverState *bs, bool *header_updated, Error **errp);
|
qcow2_load_dirty_bitmaps(BlockDriverState *bs, bool *header_updated, Error **errp);
|
||||||
bool qcow2_get_bitmap_info_list(BlockDriverState *bs,
|
bool qcow2_get_bitmap_info_list(BlockDriverState *bs,
|
||||||
Qcow2BitmapInfoList **info_list, Error **errp);
|
Qcow2BitmapInfoList **info_list, Error **errp);
|
||||||
int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
|
int GRAPH_RDLOCK qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
|
||||||
|
int GRAPH_RDLOCK qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
|
||||||
int coroutine_fn qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp);
|
int coroutine_fn qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp);
|
||||||
bool qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs,
|
|
||||||
bool release_stored, Error **errp);
|
bool GRAPH_RDLOCK
|
||||||
int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
|
qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, bool release_stored,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
bool coroutine_fn GRAPH_RDLOCK
|
bool coroutine_fn GRAPH_RDLOCK
|
||||||
qcow2_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
|
qcow2_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
|
||||||
uint32_t granularity, Error **errp);
|
uint32_t granularity, Error **errp);
|
||||||
int coroutine_fn qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs,
|
|
||||||
const char *name,
|
int coroutine_fn GRAPH_RDLOCK
|
||||||
Error **errp);
|
qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs);
|
bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs);
|
||||||
uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs,
|
uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs,
|
||||||
uint32_t cluster_size);
|
uint32_t cluster_size);
|
||||||
|
@ -307,13 +307,16 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void secondary_do_checkpoint(BlockDriverState *bs, Error **errp)
|
static void GRAPH_UNLOCKED
|
||||||
|
secondary_do_checkpoint(BlockDriverState *bs, Error **errp)
|
||||||
{
|
{
|
||||||
BDRVReplicationState *s = bs->opaque;
|
BDRVReplicationState *s = bs->opaque;
|
||||||
BdrvChild *active_disk = bs->file;
|
BdrvChild *active_disk = bs->file;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
||||||
|
|
||||||
if (!s->backup_job) {
|
if (!s->backup_job) {
|
||||||
error_setg(errp, "Backup job was cancelled unexpectedly");
|
error_setg(errp, "Backup job was cancelled unexpectedly");
|
||||||
return;
|
return;
|
||||||
@ -531,13 +534,16 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
|
|||||||
/* Must be true, or the bdrv_getlength() calls would have failed */
|
/* Must be true, or the bdrv_getlength() calls would have failed */
|
||||||
assert(active_disk->bs->drv && hidden_disk->bs->drv);
|
assert(active_disk->bs->drv && hidden_disk->bs->drv);
|
||||||
|
|
||||||
|
bdrv_graph_rdlock_main_loop();
|
||||||
if (!active_disk->bs->drv->bdrv_make_empty ||
|
if (!active_disk->bs->drv->bdrv_make_empty ||
|
||||||
!hidden_disk->bs->drv->bdrv_make_empty) {
|
!hidden_disk->bs->drv->bdrv_make_empty) {
|
||||||
error_setg(errp,
|
error_setg(errp,
|
||||||
"Active disk or hidden disk doesn't support make_empty");
|
"Active disk or hidden disk doesn't support make_empty");
|
||||||
aio_context_release(aio_context);
|
aio_context_release(aio_context);
|
||||||
|
bdrv_graph_rdunlock_main_loop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
bdrv_graph_rdunlock_main_loop();
|
||||||
|
|
||||||
/* reopen the backing file in r/w mode */
|
/* reopen the backing file in r/w mode */
|
||||||
reopen_backing_file(bs, true, &local_err);
|
reopen_backing_file(bs, true, &local_err);
|
||||||
|
@ -138,7 +138,7 @@ void GRAPH_RDLOCK
|
|||||||
bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp);
|
bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp);
|
||||||
|
|
||||||
int bdrv_commit(BlockDriverState *bs);
|
int bdrv_commit(BlockDriverState *bs);
|
||||||
int bdrv_make_empty(BdrvChild *c, Error **errp);
|
int GRAPH_RDLOCK bdrv_make_empty(BdrvChild *c, Error **errp);
|
||||||
int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file,
|
int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file,
|
||||||
const char *backing_fmt, bool warn);
|
const char *backing_fmt, bool warn);
|
||||||
void bdrv_register(BlockDriver *bdrv);
|
void bdrv_register(BlockDriver *bdrv);
|
||||||
|
@ -264,7 +264,7 @@ struct BlockDriver {
|
|||||||
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
|
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
|
||||||
bool force, Error **errp);
|
bool force, Error **errp);
|
||||||
|
|
||||||
int (*bdrv_make_empty)(BlockDriverState *bs);
|
int GRAPH_RDLOCK_PTR (*bdrv_make_empty)(BlockDriverState *bs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Refreshes the bs->exact_filename field. If that is impossible,
|
* Refreshes the bs->exact_filename field. If that is impossible,
|
||||||
|
Loading…
Reference in New Issue
Block a user