Skip to content

Commit 8f89734

Browse files
committed
qcow2: Take locks for accessing bs->file
This updates the qcow2 code to add GRAPH_RDLOCK annotations for all places that read bs->file. Signed-off-by: Kevin Wolf <[email protected]> Message-ID: <[email protected]> Reviewed-by: Eric Blake <[email protected]> Signed-off-by: Kevin Wolf <[email protected]>
1 parent 79a5586 commit 8f89734

File tree

4 files changed

+59
-41
lines changed

4 files changed

+59
-41
lines changed

block/qcow2-bitmap.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static inline bool can_write(BlockDriverState *bs)
105105
return !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE);
106106
}
107107

108-
static int update_header_sync(BlockDriverState *bs)
108+
static int GRAPH_RDLOCK update_header_sync(BlockDriverState *bs)
109109
{
110110
int ret;
111111

@@ -221,8 +221,9 @@ clear_bitmap_table(BlockDriverState *bs, uint64_t *bitmap_table,
221221
}
222222
}
223223

224-
static int bitmap_table_load(BlockDriverState *bs, Qcow2BitmapTable *tb,
225-
uint64_t **bitmap_table)
224+
static int GRAPH_RDLOCK
225+
bitmap_table_load(BlockDriverState *bs, Qcow2BitmapTable *tb,
226+
uint64_t **bitmap_table)
226227
{
227228
int ret;
228229
BDRVQcow2State *s = bs->opaque;
@@ -551,8 +552,9 @@ static uint32_t bitmap_list_count(Qcow2BitmapList *bm_list)
551552
* Get bitmap list from qcow2 image. Actually reads bitmap directory,
552553
* checks it and convert to bitmap list.
553554
*/
554-
static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, uint64_t offset,
555-
uint64_t size, Error **errp)
555+
static Qcow2BitmapList * GRAPH_RDLOCK
556+
bitmap_list_load(BlockDriverState *bs, uint64_t offset, uint64_t size,
557+
Error **errp)
556558
{
557559
int ret;
558560
BDRVQcow2State *s = bs->opaque;
@@ -961,7 +963,7 @@ static void set_readonly_helper(gpointer bitmap, gpointer value)
961963
* If header_updated is not NULL then it is set appropriately regardless of
962964
* the return value.
963965
*/
964-
bool coroutine_fn GRAPH_RDLOCK
966+
bool coroutine_fn
965967
qcow2_load_dirty_bitmaps(BlockDriverState *bs,
966968
bool *header_updated, Error **errp)
967969
{

block/qcow2-cluster.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -391,11 +391,10 @@ static int GRAPH_RDLOCK l2_allocate(BlockDriverState *bs, int l1_index)
391391
* If the L2 entry is invalid return -errno and set @type to
392392
* QCOW2_SUBCLUSTER_INVALID.
393393
*/
394-
static int qcow2_get_subcluster_range_type(BlockDriverState *bs,
395-
uint64_t l2_entry,
396-
uint64_t l2_bitmap,
397-
unsigned sc_from,
398-
QCow2SubclusterType *type)
394+
static int GRAPH_RDLOCK
395+
qcow2_get_subcluster_range_type(BlockDriverState *bs, uint64_t l2_entry,
396+
uint64_t l2_bitmap, unsigned sc_from,
397+
QCow2SubclusterType *type)
399398
{
400399
BDRVQcow2State *s = bs->opaque;
401400
uint32_t val;
@@ -442,9 +441,10 @@ static int qcow2_get_subcluster_range_type(BlockDriverState *bs,
442441
* On failure return -errno and update @l2_index to point to the
443442
* invalid entry.
444443
*/
445-
static int count_contiguous_subclusters(BlockDriverState *bs, int nb_clusters,
446-
unsigned sc_index, uint64_t *l2_slice,
447-
unsigned *l2_index)
444+
static int GRAPH_RDLOCK
445+
count_contiguous_subclusters(BlockDriverState *bs, int nb_clusters,
446+
unsigned sc_index, uint64_t *l2_slice,
447+
unsigned *l2_index)
448448
{
449449
BDRVQcow2State *s = bs->opaque;
450450
int i, count = 0;
@@ -1329,7 +1329,8 @@ calculate_l2_meta(BlockDriverState *bs, uint64_t host_cluster_offset,
13291329
* requires a new allocation (that is, if the cluster is unallocated
13301330
* or has refcount > 1 and therefore cannot be written in-place).
13311331
*/
1332-
static bool cluster_needs_new_alloc(BlockDriverState *bs, uint64_t l2_entry)
1332+
static bool GRAPH_RDLOCK
1333+
cluster_needs_new_alloc(BlockDriverState *bs, uint64_t l2_entry)
13331334
{
13341335
switch (qcow2_get_cluster_type(bs, l2_entry)) {
13351336
case QCOW2_CLUSTER_NORMAL:
@@ -1360,9 +1361,9 @@ static bool cluster_needs_new_alloc(BlockDriverState *bs, uint64_t l2_entry)
13601361
* allocated and can be overwritten in-place (this includes clusters
13611362
* of type QCOW2_CLUSTER_ZERO_ALLOC).
13621363
*/
1363-
static int count_single_write_clusters(BlockDriverState *bs, int nb_clusters,
1364-
uint64_t *l2_slice, int l2_index,
1365-
bool new_alloc)
1364+
static int GRAPH_RDLOCK
1365+
count_single_write_clusters(BlockDriverState *bs, int nb_clusters,
1366+
uint64_t *l2_slice, int l2_index, bool new_alloc)
13661367
{
13671368
BDRVQcow2State *s = bs->opaque;
13681369
uint64_t l2_entry = get_l2_entry(s, l2_slice, l2_index);

block/qcow2.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,10 @@ static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename)
9595
}
9696

9797

98-
static int qcow2_crypto_hdr_read_func(QCryptoBlock *block, size_t offset,
99-
uint8_t *buf, size_t buflen,
100-
void *opaque, Error **errp)
98+
static int GRAPH_RDLOCK
99+
qcow2_crypto_hdr_read_func(QCryptoBlock *block, size_t offset,
100+
uint8_t *buf, size_t buflen,
101+
void *opaque, Error **errp)
101102
{
102103
BlockDriverState *bs = opaque;
103104
BDRVQcow2State *s = bs->opaque;
@@ -156,7 +157,7 @@ qcow2_crypto_hdr_init_func(QCryptoBlock *block, size_t headerlen, void *opaque,
156157

157158

158159
/* The graph lock must be held when called in coroutine context */
159-
static int coroutine_mixed_fn
160+
static int coroutine_mixed_fn GRAPH_RDLOCK
160161
qcow2_crypto_hdr_write_func(QCryptoBlock *block, size_t offset,
161162
const uint8_t *buf, size_t buflen,
162163
void *opaque, Error **errp)
@@ -2029,6 +2030,8 @@ static void qcow2_reopen_commit(BDRVReopenState *state)
20292030
{
20302031
BDRVQcow2State *s = state->bs->opaque;
20312032

2033+
GRAPH_RDLOCK_GUARD_MAINLOOP();
2034+
20322035
qcow2_update_options_commit(state->bs, state->opaque);
20332036
if (!s->data_file) {
20342037
/*
@@ -2064,6 +2067,8 @@ static void qcow2_reopen_abort(BDRVReopenState *state)
20642067
{
20652068
BDRVQcow2State *s = state->bs->opaque;
20662069

2070+
GRAPH_RDLOCK_GUARD_MAINLOOP();
2071+
20672072
if (!s->data_file) {
20682073
/*
20692074
* If we don't have an external data file, s->data_file was cleared by

block/qcow2.h

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ static inline void set_l2_bitmap(BDRVQcow2State *s, uint64_t *l2_slice,
641641
l2_slice[idx + 1] = cpu_to_be64(bitmap);
642642
}
643643

644-
static inline bool has_data_file(BlockDriverState *bs)
644+
static inline bool GRAPH_RDLOCK has_data_file(BlockDriverState *bs)
645645
{
646646
BDRVQcow2State *s = bs->opaque;
647647
return (s->data_file != bs->file);
@@ -709,8 +709,8 @@ static inline int64_t qcow2_vm_state_offset(BDRVQcow2State *s)
709709
return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
710710
}
711711

712-
static inline QCow2ClusterType qcow2_get_cluster_type(BlockDriverState *bs,
713-
uint64_t l2_entry)
712+
static inline QCow2ClusterType GRAPH_RDLOCK
713+
qcow2_get_cluster_type(BlockDriverState *bs, uint64_t l2_entry)
714714
{
715715
BDRVQcow2State *s = bs->opaque;
716716

@@ -743,7 +743,7 @@ static inline QCow2ClusterType qcow2_get_cluster_type(BlockDriverState *bs,
743743
* (this checks the whole entry and bitmap, not only the bits related
744744
* to subcluster @sc_index).
745745
*/
746-
static inline
746+
static inline GRAPH_RDLOCK
747747
QCow2SubclusterType qcow2_get_subcluster_type(BlockDriverState *bs,
748748
uint64_t l2_entry,
749749
uint64_t l2_bitmap,
@@ -834,9 +834,9 @@ int64_t qcow2_refcount_metadata_size(int64_t clusters, size_t cluster_size,
834834
int refcount_order, bool generous_increase,
835835
uint64_t *refblock_count);
836836

837-
int qcow2_mark_dirty(BlockDriverState *bs);
838-
int qcow2_mark_corrupt(BlockDriverState *bs);
839-
int qcow2_update_header(BlockDriverState *bs);
837+
int GRAPH_RDLOCK qcow2_mark_dirty(BlockDriverState *bs);
838+
int GRAPH_RDLOCK qcow2_mark_corrupt(BlockDriverState *bs);
839+
int GRAPH_RDLOCK qcow2_update_header(BlockDriverState *bs);
840840

841841
void GRAPH_RDLOCK
842842
qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
@@ -890,10 +890,11 @@ int GRAPH_RDLOCK qcow2_write_caches(BlockDriverState *bs);
890890
int coroutine_fn qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
891891
BdrvCheckMode fix);
892892

893-
void qcow2_process_discards(BlockDriverState *bs, int ret);
893+
void GRAPH_RDLOCK qcow2_process_discards(BlockDriverState *bs, int ret);
894894

895-
int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
896-
int64_t size);
895+
int GRAPH_RDLOCK
896+
qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
897+
int64_t size);
897898
int GRAPH_RDLOCK
898899
qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
899900
int64_t size, bool data_file);
@@ -939,8 +940,9 @@ qcow2_alloc_host_offset(BlockDriverState *bs, uint64_t offset,
939940
int coroutine_fn GRAPH_RDLOCK
940941
qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, uint64_t offset,
941942
int compressed_size, uint64_t *host_offset);
942-
void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
943-
uint64_t *coffset, int *csize);
943+
void GRAPH_RDLOCK
944+
qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
945+
uint64_t *coffset, int *csize);
944946

945947
int coroutine_fn GRAPH_RDLOCK
946948
qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
@@ -993,8 +995,9 @@ qcow2_check_fix_snapshot_table(BlockDriverState *bs, BdrvCheckResult *result,
993995
BdrvCheckMode fix);
994996

995997
/* qcow2-cache.c functions */
996-
Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables,
997-
unsigned table_size);
998+
Qcow2Cache * GRAPH_RDLOCK
999+
qcow2_cache_create(BlockDriverState *bs, int num_tables, unsigned table_size);
1000+
9981001
int qcow2_cache_destroy(Qcow2Cache *c);
9991002

10001003
void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table);
@@ -1020,17 +1023,24 @@ void *qcow2_cache_is_table_offset(Qcow2Cache *c, uint64_t offset);
10201023
void qcow2_cache_discard(Qcow2Cache *c, void *table);
10211024

10221025
/* qcow2-bitmap.c functions */
1023-
int coroutine_fn
1026+
int coroutine_fn GRAPH_RDLOCK
10241027
qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
10251028
void **refcount_table,
10261029
int64_t *refcount_table_size);
1030+
10271031
bool coroutine_fn GRAPH_RDLOCK
1028-
qcow2_load_dirty_bitmaps(BlockDriverState *bs, bool *header_updated, Error **errp);
1029-
bool qcow2_get_bitmap_info_list(BlockDriverState *bs,
1030-
Qcow2BitmapInfoList **info_list, Error **errp);
1032+
qcow2_load_dirty_bitmaps(BlockDriverState *bs, bool *header_updated,
1033+
Error **errp);
1034+
1035+
bool GRAPH_RDLOCK
1036+
qcow2_get_bitmap_info_list(BlockDriverState *bs,
1037+
Qcow2BitmapInfoList **info_list, Error **errp);
1038+
10311039
int GRAPH_RDLOCK qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
10321040
int GRAPH_RDLOCK qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
1033-
int coroutine_fn qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp);
1041+
1042+
int coroutine_fn GRAPH_RDLOCK
1043+
qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp);
10341044

10351045
bool GRAPH_RDLOCK
10361046
qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, bool release_stored,

0 commit comments

Comments
 (0)