diff --git a/block/vhdx.h b/block/vhdx.h
index 85594a5380..c6dd4d6040 100644
--- a/block/vhdx.h
+++ b/block/vhdx.h
@@ -401,8 +401,9 @@ typedef struct BDRVVHDXState {
 
 void vhdx_guid_generate(MSGUID *guid);
 
-int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s, bool rw,
-                        MSGUID *log_guid);
+int GRAPH_RDLOCK
+vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s, bool rw,
+                    MSGUID *log_guid);
 
 uint32_t vhdx_update_checksum(uint8_t *buf, size_t size, int crc_offset);
 uint32_t vhdx_checksum_calc(uint32_t crc, uint8_t *buf, size_t size,
@@ -448,6 +449,8 @@ void vhdx_metadata_header_le_import(VHDXMetadataTableHeader *hdr);
 void vhdx_metadata_header_le_export(VHDXMetadataTableHeader *hdr);
 void vhdx_metadata_entry_le_import(VHDXMetadataTableEntry *e);
 void vhdx_metadata_entry_le_export(VHDXMetadataTableEntry *e);
-int vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s);
+
+int GRAPH_RDLOCK
+vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s);
 
 #endif
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
index d8ed651b70..4385a2d4f6 100644
--- a/block/vhdx-log.c
+++ b/block/vhdx-log.c
@@ -55,8 +55,9 @@ static const MSGUID zero_guid = { 0 };
 
 /* Allow peeking at the hdr entry at the beginning of the current
  * read index, without advancing the read index */
-static int vhdx_log_peek_hdr(BlockDriverState *bs, VHDXLogEntries *log,
-                             VHDXLogEntryHeader *hdr)
+static int GRAPH_RDLOCK
+vhdx_log_peek_hdr(BlockDriverState *bs, VHDXLogEntries *log,
+                  VHDXLogEntryHeader *hdr)
 {
     int ret = 0;
     uint64_t offset;
@@ -107,7 +108,7 @@ static int vhdx_log_inc_idx(uint32_t idx, uint64_t length)
 
 
 /* Reset the log to empty */
-static void vhdx_log_reset(BlockDriverState *bs, BDRVVHDXState *s)
+static void GRAPH_RDLOCK vhdx_log_reset(BlockDriverState *bs, BDRVVHDXState *s)
 {
     MSGUID guid = { 0 };
     s->log.read = s->log.write = 0;
@@ -127,9 +128,10 @@ static void vhdx_log_reset(BlockDriverState *bs, BDRVVHDXState *s)
  * not modified.
  *
  * 0 is returned on success, -errno otherwise.  */
-static int vhdx_log_read_sectors(BlockDriverState *bs, VHDXLogEntries *log,
-                                 uint32_t *sectors_read, void *buffer,
-                                 uint32_t num_sectors, bool peek)
+static int GRAPH_RDLOCK
+vhdx_log_read_sectors(BlockDriverState *bs, VHDXLogEntries *log,
+                      uint32_t *sectors_read, void *buffer,
+                      uint32_t num_sectors, bool peek)
 {
     int ret = 0;
     uint64_t offset;
@@ -333,9 +335,9 @@ static int vhdx_compute_desc_sectors(uint32_t desc_cnt)
  * will allocate all the space for buffer, which must be NULL when
  * passed into this function. Each descriptor will also be validated,
  * and error returned if any are invalid. */
-static int vhdx_log_read_desc(BlockDriverState *bs, BDRVVHDXState *s,
-                              VHDXLogEntries *log, VHDXLogDescEntries **buffer,
-                              bool convert_endian)
+static int GRAPH_RDLOCK
+vhdx_log_read_desc(BlockDriverState *bs, BDRVVHDXState *s, VHDXLogEntries *log,
+                   VHDXLogDescEntries **buffer, bool convert_endian)
 {
     int ret = 0;
     uint32_t desc_sectors;
@@ -412,8 +414,9 @@ exit:
  * For a zero descriptor, it may describe multiple sectors to fill with zeroes.
  * In this case, it should be noted that zeroes are written to disk, and the
  * image file is not extended as a sparse file.  */
-static int vhdx_log_flush_desc(BlockDriverState *bs, VHDXLogDescriptor *desc,
-                               VHDXLogDataSector *data)
+static int GRAPH_RDLOCK
+vhdx_log_flush_desc(BlockDriverState *bs, VHDXLogDescriptor *desc,
+                    VHDXLogDataSector *data)
 {
     int ret = 0;
     uint64_t seq, file_offset;
@@ -484,8 +487,8 @@ exit:
  * file, and then set the log to 'empty' status once complete.
  *
  * The log entries should be validate prior to flushing */
-static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
-                          VHDXLogSequence *logs)
+static int GRAPH_RDLOCK
+vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s, VHDXLogSequence *logs)
 {
     int ret = 0;
     int i;
@@ -584,9 +587,10 @@ exit:
     return ret;
 }
 
-static int vhdx_validate_log_entry(BlockDriverState *bs, BDRVVHDXState *s,
-                                   VHDXLogEntries *log, uint64_t seq,
-                                   bool *valid, VHDXLogEntryHeader *entry)
+static int GRAPH_RDLOCK
+vhdx_validate_log_entry(BlockDriverState *bs, BDRVVHDXState *s,
+                        VHDXLogEntries *log, uint64_t seq,
+                        bool *valid, VHDXLogEntryHeader *entry)
 {
     int ret = 0;
     VHDXLogEntryHeader hdr;
@@ -663,8 +667,8 @@ free_and_exit:
 /* Search through the log circular buffer, and find the valid, active
  * log sequence, if any exists
  * */
-static int vhdx_log_search(BlockDriverState *bs, BDRVVHDXState *s,
-                           VHDXLogSequence *logs)
+static int GRAPH_RDLOCK
+vhdx_log_search(BlockDriverState *bs, BDRVVHDXState *s, VHDXLogSequence *logs)
 {
     int ret = 0;
     uint32_t tail;
diff --git a/block/vhdx.c b/block/vhdx.c
index 50aefa5fb5..fa3875fa63 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -353,8 +353,9 @@ exit:
  *
  *  - non-current header is updated with largest sequence number
  */
-static int vhdx_update_header(BlockDriverState *bs, BDRVVHDXState *s,
-                              bool generate_data_write_guid, MSGUID *log_guid)
+static int GRAPH_RDLOCK
+vhdx_update_header(BlockDriverState *bs, BDRVVHDXState *s,
+                   bool generate_data_write_guid, MSGUID *log_guid)
 {
     int ret = 0;
     int hdr_idx = 0;
@@ -416,8 +417,8 @@ int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s,
 }
 
 /* opens the specified header block from the VHDX file header section */
-static void vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s,
-                              Error **errp)
+static void GRAPH_RDLOCK
+vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s, Error **errp)
 {
     int ret;
     VHDXHeader *header1;
@@ -517,7 +518,8 @@ exit:
 }
 
 
-static int vhdx_open_region_tables(BlockDriverState *bs, BDRVVHDXState *s)
+static int GRAPH_RDLOCK
+vhdx_open_region_tables(BlockDriverState *bs, BDRVVHDXState *s)
 {
     int ret = 0;
     uint8_t *buffer;
@@ -634,7 +636,8 @@ fail:
  * Also, if the File Parameters indicate this is a differencing file,
  * we must also look for the Parent Locator metadata item.
  */
-static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
+static int GRAPH_RDLOCK
+vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
 {
     int ret = 0;
     uint8_t *buffer;
@@ -885,7 +888,8 @@ static void vhdx_calc_bat_entries(BDRVVHDXState *s)
 
 }
 
-static int vhdx_check_bat_entries(BlockDriverState *bs, int *errcnt)
+static int coroutine_mixed_fn GRAPH_RDLOCK
+vhdx_check_bat_entries(BlockDriverState *bs, int *errcnt)
 {
     BDRVVHDXState *s = bs->opaque;
     int64_t image_file_size = bdrv_getlength(bs->file->bs);
