Patchwork [5/5] Convert block layer callers' annotations

login
register
mail settings
Submitter Charlie Shepherd
Date Aug. 5, 2013, 6:44 p.m.
Message ID <1375728247-1306-6-git-send-email-charlie@ctshepherd.com>
Download mbox | patch
Permalink /patch/264750/
State New
Headers show

Comments

Charlie Shepherd - Aug. 5, 2013, 6:44 p.m.
This patch updates the callers of block layer functions converted to explicit
coroutine_fn annotation in the previous patch.

---
 block/bochs.c            |  4 ++--
 block/cloop.c            |  4 ++--
 block/cow.c              |  8 +++----
 block/dmg.c              |  8 +++----
 block/qcow.c             |  6 +++---
 block/qcow2.c            | 18 ++++++++--------
 block/qcow2.h            |  2 +-
 block/vdi.c              |  4 ++--
 block/vmdk.c             | 34 +++++++++++++++---------------
 block/vpc.c              |  4 ++--
 block/vvfat.c            | 20 +++++++++---------
 blockjob.c               |  2 +-
 include/block/blockjob.h |  2 +-
 nbd.c                    |  4 ++--
 qemu-img.c               | 54 ++++++++++++++++++++++++++++++++++++++----------
 qemu-io-cmds.c           | 12 +++++------
 16 files changed, 109 insertions(+), 77 deletions(-)
Gabriel Kerneis - Aug. 5, 2013, 8:15 p.m.
On Mon, Aug 05, 2013 at 08:44:07PM +0200, Charlie Shepherd wrote:
> This patch updates the callers of block layer functions converted to explicit
> coroutine_fn annotation in the previous patch.

It looks like this patch is made of three parts:
- updating the annotations, following the rule "caller of coroutine_fn must be
  coroutine_fn",
- introducing a run_handler function in qemu-img.c,
- replacing bdrv_* by bdrv_*_sync in qemu-io-cmds.c.

The first one is purely mechanical and boring. The second one is moderately
inventive (note that I did not review the code in detail). The third one is
simple but definitely deserves some explanation. Again, I think this could be
split in three different patches, with an expanded commit message.

Best,
Charlie Shepherd - Aug. 8, 2013, 1:19 a.m.
On 05/08/2013 21:15, Gabriel Kerneis wrote:
> On Mon, Aug 05, 2013 at 08:44:07PM +0200, Charlie Shepherd wrote:
>> This patch updates the callers of block layer functions converted to explicit
>> coroutine_fn annotation in the previous patch.
> It looks like this patch is made of three parts:
> - updating the annotations, following the rule "caller of coroutine_fn must be
>    coroutine_fn",
> - introducing a run_handler function in qemu-img.c,
> - replacing bdrv_* by bdrv_*_sync in qemu-io-cmds.c.
>
> The first one is purely mechanical and boring. The second one is moderately
> inventive (note that I did not review the code in detail). The third one is
> simple but definitely deserves some explanation. Again, I think this could be
> split in three different patches, with an expanded commit message.

Ok thanks this seems like a logical way to split them up.


Charlie

Patch

diff --git a/block/bochs.c b/block/bochs.c
index c827bd4..a64cfa3 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -165,7 +165,7 @@  fail:
     return ret;
 }
 
-static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
+static int64_t coroutine_fn seek_to_sector(BlockDriverState *bs, int64_t sector_num)
 {
     BDRVBochsState *s = bs->opaque;
     int64_t offset = sector_num * 512;
@@ -196,7 +196,7 @@  static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
     return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
 }
 
-static int bochs_read(BlockDriverState *bs, int64_t sector_num,
+static int coroutine_fn bochs_read(BlockDriverState *bs, int64_t sector_num,
                     uint8_t *buf, int nb_sectors)
 {
     int ret;
diff --git a/block/cloop.c b/block/cloop.c
index ef5555f..b9dee5f 100644
--- a/block/cloop.c
+++ b/block/cloop.c
@@ -114,7 +114,7 @@  fail:
     return ret;
 }
 
-static inline int cloop_read_block(BlockDriverState *bs, int block_num)
+static inline int coroutine_fn cloop_read_block(BlockDriverState *bs, int block_num)
 {
     BDRVCloopState *s = bs->opaque;
 
@@ -146,7 +146,7 @@  static inline int cloop_read_block(BlockDriverState *bs, int block_num)
     return 0;
 }
 
-static int cloop_read(BlockDriverState *bs, int64_t sector_num,
+static int coroutine_fn cloop_read(BlockDriverState *bs, int64_t sector_num,
                     uint8_t *buf, int nb_sectors)
 {
     BDRVCloopState *s = bs->opaque;
diff --git a/block/cow.c b/block/cow.c
index c68c5ae..e63b154 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -106,7 +106,7 @@  static int coroutine_fn cow_co_open(BlockDriverState *bs, QDict *options, int fl
  * XXX(hch): right now these functions are extremely inefficient.
  * We should just read the whole bitmap we'll need in one go instead.
  */
-static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum)
+static inline int coroutine_fn cow_set_bit(BlockDriverState *bs, int64_t bitnum)
 {
     uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
     uint8_t bitmap;
@@ -126,7 +126,7 @@  static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum)
     return 0;
 }
 
-static inline int is_bit_set(BlockDriverState *bs, int64_t bitnum)
+static inline int coroutine_fn is_bit_set(BlockDriverState *bs, int64_t bitnum)
 {
     uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
     uint8_t bitmap;
@@ -166,7 +166,7 @@  static int coroutine_fn cow_co_is_allocated(BlockDriverState *bs,
     return changed;
 }
 
-static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num,
+static int coroutine_fn cow_update_bitmap(BlockDriverState *bs, int64_t sector_num,
         int nb_sectors)
 {
     int error = 0;
@@ -225,7 +225,7 @@  static coroutine_fn int cow_co_read(BlockDriverState *bs, int64_t sector_num,
     return ret;
 }
 
-static int cow_write(BlockDriverState *bs, int64_t sector_num,
+static int coroutine_fn cow_write(BlockDriverState *bs, int64_t sector_num,
                      const uint8_t *buf, int nb_sectors)
 {
     BDRVCowState *s = bs->opaque;
diff --git a/block/dmg.c b/block/dmg.c
index 346aa7d..3933f45 100644
--- a/block/dmg.c
+++ b/block/dmg.c
@@ -64,7 +64,7 @@  static int dmg_probe(const uint8_t *buf, int buf_size, const char *filename)
     return 0;
 }
 
-static int read_uint64(BlockDriverState *bs, int64_t offset, uint64_t *result)
+static int coroutine_fn read_uint64(BlockDriverState *bs, int64_t offset, uint64_t *result)
 {
     uint64_t buffer;
     int ret;
@@ -78,7 +78,7 @@  static int read_uint64(BlockDriverState *bs, int64_t offset, uint64_t *result)
     return 0;
 }
 
-static int read_uint32(BlockDriverState *bs, int64_t offset, uint32_t *result)
+static int coroutine_fn read_uint32(BlockDriverState *bs, int64_t offset, uint32_t *result)
 {
     uint32_t buffer;
     int ret;
@@ -276,7 +276,7 @@  static inline uint32_t search_chunk(BDRVDMGState* s,int sector_num)
     return s->n_chunks; /* error */
 }
 
-static inline int dmg_read_chunk(BlockDriverState *bs, int sector_num)
+static inline int coroutine_fn dmg_read_chunk(BlockDriverState *bs, int sector_num)
 {
     BDRVDMGState *s = bs->opaque;
 
@@ -332,7 +332,7 @@  static inline int dmg_read_chunk(BlockDriverState *bs, int sector_num)
     return 0;
 }
 
-static int dmg_read(BlockDriverState *bs, int64_t sector_num,
+static int coroutine_fn dmg_read(BlockDriverState *bs, int64_t sector_num,
                     uint8_t *buf, int nb_sectors)
 {
     BDRVDMGState *s = bs->opaque;
diff --git a/block/qcow.c b/block/qcow.c
index 04f59f2..09e631c 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -78,7 +78,7 @@  typedef struct BDRVQcowState {
     Error *migration_blocker;
 } BDRVQcowState;
 
-static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
+static int coroutine_fn decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
 
 static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
 {
@@ -268,7 +268,7 @@  static void encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
  *
  * return 0 if not allocated.
  */
-static uint64_t get_cluster_offset(BlockDriverState *bs,
+static uint64_t coroutine_fn get_cluster_offset(BlockDriverState *bs,
                                    uint64_t offset, int allocate,
                                    int compressed_size,
                                    int n_start, int n_end)
@@ -440,7 +440,7 @@  static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
     return 0;
 }
 
-static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
+static int coroutine_fn decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
 {
     BDRVQcowState *s = bs->opaque;
     int ret, csize;
diff --git a/block/qcow2.c b/block/qcow2.c
index 2ed0bb6..9b359a4 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -82,7 +82,7 @@  static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename)
  * unknown magic is skipped (future extension this version knows nothing about)
  * return 0 upon success, non-0 otherwise
  */
-static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
+static int coroutine_fn qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
                                  uint64_t end_offset, void **p_feature_table)
 {
     BDRVQcowState *s = bs->opaque;
@@ -227,7 +227,7 @@  static void report_unsupported_feature(BlockDriverState *bs,
  * updated successfully.  Therefore it is not required to check the return
  * value of this function.
  */
-int qcow2_mark_dirty(BlockDriverState *bs)
+int coroutine_fn qcow2_mark_dirty(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
     uint64_t val;
@@ -260,7 +260,7 @@  int qcow2_mark_dirty(BlockDriverState *bs)
  * function when there are no pending requests, it does not guard against
  * concurrent requests dirtying the image.
  */
-static int qcow2_mark_clean(BlockDriverState *bs)
+static int coroutine_fn qcow2_mark_clean(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
 
@@ -276,7 +276,7 @@  static int qcow2_mark_clean(BlockDriverState *bs)
     return 0;
 }
 
-static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
+static int coroutine_fn qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
                        BdrvCheckMode fix)
 {
     int ret = qcow2_check_refcounts(bs, result, fix);
@@ -1001,7 +1001,7 @@  static void qcow2_close(BlockDriverState *bs)
     qcow2_free_snapshots(bs);
 }
 
-static void qcow2_invalidate_cache(BlockDriverState *bs)
+static void coroutine_fn qcow2_invalidate_cache(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
     int flags = s->flags;
@@ -1592,7 +1592,7 @@  static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
 
 /* XXX: put compressed sectors first, then all the cluster aligned
    tables to avoid losing bytes in alignment */
-static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
+static int coroutine_fn qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
                                   const uint8_t *buf, int nb_sectors)
 {
     BDRVQcowState *s = bs->opaque;
@@ -1738,7 +1738,7 @@  static void dump_refcounts(BlockDriverState *bs)
 }
 #endif
 
-static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
+static int coroutine_fn qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
                               int64_t pos)
 {
     BDRVQcowState *s = bs->opaque;
@@ -1747,13 +1747,13 @@  static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
 
     BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE);
     bs->growable = 1;
-    ret = bdrv_pwritev(bs, qcow2_vm_state_offset(s) + pos, qiov);
+    ret = bdrv_pwritev_sync(bs, qcow2_vm_state_offset(s) + pos, qiov);
     bs->growable = growable;
 
     return ret;
 }
 
-static int qcow2_load_vmstate(BlockDriverState *bs, uint8_t *buf,
+static int coroutine_fn qcow2_load_vmstate(BlockDriverState *bs, uint8_t *buf,
                               int64_t pos, int size)
 {
     BDRVQcowState *s = bs->opaque;
diff --git a/block/qcow2.h b/block/qcow2.h
index 0b482ff..e195db0 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -360,7 +360,7 @@  static inline uint64_t l2meta_cow_end(QCowL2Meta *m)
 int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
                   int64_t sector_num, int nb_sectors);
 
-int qcow2_mark_dirty(BlockDriverState *bs);
+int coroutine_fn qcow2_mark_dirty(BlockDriverState *bs);
 int qcow2_update_header(BlockDriverState *bs);
 
 /* qcow2-refcount.c functions */
diff --git a/block/vdi.c b/block/vdi.c
index 577a638..6f1a52c 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -487,7 +487,7 @@  static int coroutine_fn vdi_co_is_allocated(BlockDriverState *bs,
     return VDI_IS_ALLOCATED(bmap_entry);
 }
 
-static int vdi_co_read(BlockDriverState *bs,
+static int coroutine_fn vdi_co_read(BlockDriverState *bs,
         int64_t sector_num, uint8_t *buf, int nb_sectors)
 {
     BDRVVdiState *s = bs->opaque;
@@ -532,7 +532,7 @@  static int vdi_co_read(BlockDriverState *bs,
     return ret;
 }
 
-static int vdi_co_write(BlockDriverState *bs,
+static int coroutine_fn vdi_co_write(BlockDriverState *bs,
         int64_t sector_num, const uint8_t *buf, int nb_sectors)
 {
     BDRVVdiState *s = bs->opaque;
diff --git a/block/vmdk.c b/block/vmdk.c
index ae1dee4..178c21a 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -232,7 +232,7 @@  static void vmdk_free_last_extent(BlockDriverState *bs)
     s->extents = g_realloc(s->extents, s->num_extents * sizeof(VmdkExtent));
 }
 
-static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
+static uint32_t coroutine_fn vmdk_read_cid(BlockDriverState *bs, int parent)
 {
     char desc[DESC_SIZE];
     uint32_t cid = 0xffffffff;
@@ -264,7 +264,7 @@  static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
     return cid;
 }
 
-static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
+static int coroutine_fn vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
 {
     char desc[DESC_SIZE], tmp_desc[DESC_SIZE];
     char *p_name, *tmp_str;
@@ -298,7 +298,7 @@  static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
     return 0;
 }
 
-static int vmdk_is_cid_valid(BlockDriverState *bs)
+static int coroutine_fn vmdk_is_cid_valid(BlockDriverState *bs)
 {
 #ifdef CHECK_CID
     BDRVVmdkState *s = bs->opaque;
@@ -351,7 +351,7 @@  exit:
     return ret;
 }
 
-static int vmdk_parent_open(BlockDriverState *bs)
+static int coroutine_fn vmdk_parent_open(BlockDriverState *bs)
 {
     char *p_name;
     char desc[DESC_SIZE + 1];
@@ -419,7 +419,7 @@  static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
     return extent;
 }
 
-static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
+static int coroutine_fn vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
 {
     int ret;
     int l1_size, i;
@@ -462,7 +462,7 @@  static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
     return ret;
 }
 
-static int vmdk_open_vmdk3(BlockDriverState *bs,
+static int coroutine_fn vmdk_open_vmdk3(BlockDriverState *bs,
                            BlockDriverState *file,
                            int flags)
 {
@@ -492,7 +492,7 @@  static int vmdk_open_vmdk3(BlockDriverState *bs,
 static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
                                int64_t desc_offset);
 
-static int vmdk_open_vmdk4(BlockDriverState *bs,
+static int coroutine_fn vmdk_open_vmdk4(BlockDriverState *bs,
                            BlockDriverState *file,
                            int flags)
 {
@@ -628,7 +628,7 @@  static int vmdk_parse_description(const char *desc, const char *opt_name,
 }
 
 /* Open an extent file and append to bs array */
-static int vmdk_open_sparse(BlockDriverState *bs,
+static int coroutine_fn vmdk_open_sparse(BlockDriverState *bs,
                             BlockDriverState *file,
                             int flags)
 {
@@ -652,7 +652,7 @@  static int vmdk_open_sparse(BlockDriverState *bs,
     }
 }
 
-static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
+static int coroutine_fn vmdk_parse_extents(const char *desc, BlockDriverState *bs,
         const char *desc_file_path)
 {
     int ret;
@@ -727,7 +727,7 @@  next_line:
     return 0;
 }
 
-static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
+static int coroutine_fn vmdk_open_desc_file(BlockDriverState *bs, int flags,
                                int64_t desc_offset)
 {
     int ret;
@@ -801,7 +801,7 @@  fail:
     return ret;
 }
 
-static int get_whole_cluster(BlockDriverState *bs,
+static int coroutine_fn get_whole_cluster(BlockDriverState *bs,
                 VmdkExtent *extent,
                 uint64_t cluster_offset,
                 uint64_t offset,
@@ -868,7 +868,7 @@  static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
     return VMDK_OK;
 }
 
-static int get_cluster_offset(BlockDriverState *bs,
+static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
                                     VmdkExtent *extent,
                                     VmdkMetaData *m_data,
                                     uint64_t offset,
@@ -1026,7 +1026,7 @@  static int coroutine_fn vmdk_co_is_allocated(BlockDriverState *bs,
     return ret;
 }
 
-static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
+static int coroutine_fn vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
                             int64_t offset_in_cluster, const uint8_t *buf,
                             int nb_sectors, int64_t sector_num)
 {
@@ -1067,7 +1067,7 @@  static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
     return ret;
 }
 
-static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
+static int coroutine_fn vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
                             int64_t offset_in_cluster, uint8_t *buf,
                             int nb_sectors)
 {
@@ -1133,7 +1133,7 @@  static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
     return ret;
 }
 
-static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
+static int coroutine_fn vmdk_read(BlockDriverState *bs, int64_t sector_num,
                     uint8_t *buf, int nb_sectors)
 {
     BDRVVmdkState *s = bs->opaque;
@@ -1205,7 +1205,7 @@  static coroutine_fn int vmdk_co_read(BlockDriverState *bs, int64_t sector_num,
  *
  * Returns: error code with 0 for success.
  */
-static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
+static int coroutine_fn vmdk_write(BlockDriverState *bs, int64_t sector_num,
                       const uint8_t *buf, int nb_sectors,
                       bool zeroed, bool zero_dry_run)
 {
@@ -1692,7 +1692,7 @@  static coroutine_fn int vmdk_co_flush(BlockDriverState *bs)
     int ret = 0;
 
     for (i = 0; i < s->num_extents; i++) {
-        err = bdrv_co_flush(s->extents[i].file);
+        err = bdrv_flush(s->extents[i].file);
         if (err < 0) {
             ret = err;
         }
diff --git a/block/vpc.c b/block/vpc.c
index 6eb293a..0c94003 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -438,7 +438,7 @@  fail:
     return -1;
 }
 
-static int vpc_read(BlockDriverState *bs, int64_t sector_num,
+static int coroutine_fn vpc_read(BlockDriverState *bs, int64_t sector_num,
                     uint8_t *buf, int nb_sectors)
 {
     BDRVVPCState *s = bs->opaque;
@@ -487,7 +487,7 @@  static coroutine_fn int vpc_co_read(BlockDriverState *bs, int64_t sector_num,
     return ret;
 }
 
-static int vpc_write(BlockDriverState *bs, int64_t sector_num,
+static int coroutine_fn vpc_write(BlockDriverState *bs, int64_t sector_num,
     const uint8_t *buf, int nb_sectors)
 {
     BDRVVPCState *s = bs->opaque;
diff --git a/block/vvfat.c b/block/vvfat.c
index 4771a5d..91f8bec 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1368,7 +1368,7 @@  static void print_mapping(const mapping_t* mapping)
 }
 #endif
 
-static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
+static int coroutine_fn vvfat_read(BlockDriverState *bs, int64_t sector_num,
                     uint8_t *buf, int nb_sectors)
 {
     BDRVVVFATState *s = bs->opaque;
@@ -1677,7 +1677,7 @@  typedef enum {
  * Further, the files/directories handled by this function are
  * assumed to be *not* deleted (and *only* those).
  */
-static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
+static uint32_t coroutine_fn get_cluster_count_for_direntry(BDRVVVFATState* s,
 	direntry_t* direntry, const char* path)
 {
     /*
@@ -1824,7 +1824,7 @@  static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
  * It returns 0 upon inconsistency or error, and the number of clusters
  * used by the directory, its subdirectories and their files.
  */
-static int check_directory_consistency(BDRVVVFATState *s,
+static int coroutine_fn check_directory_consistency(BDRVVVFATState *s,
 	int cluster_num, const char* path)
 {
     int ret = 0;
@@ -1948,7 +1948,7 @@  DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i))
 }
 
 /* returns 1 on success */
-static int is_consistent(BDRVVVFATState* s)
+static int coroutine_fn is_consistent(BDRVVVFATState* s)
 {
     int i, check;
     int used_clusters_count = 0;
@@ -2224,7 +2224,7 @@  static int commit_mappings(BDRVVVFATState* s,
     return 0;
 }
 
-static int commit_direntries(BDRVVVFATState* s,
+static int coroutine_fn commit_direntries(BDRVVVFATState* s,
 	int dir_index, int parent_mapping_index)
 {
     direntry_t* direntry = array_get(&(s->directory), dir_index);
@@ -2304,7 +2304,7 @@  DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapp
 
 /* commit one file (adjust contents, adjust mapping),
    return first_mapping_index */
-static int commit_one_file(BDRVVVFATState* s,
+static int coroutine_fn commit_one_file(BDRVVVFATState* s,
 	int dir_index, uint32_t offset)
 {
     direntry_t* direntry = array_get(&(s->directory), dir_index);
@@ -2559,7 +2559,7 @@  static int handle_renames_and_mkdirs(BDRVVVFATState* s)
 /*
  * TODO: make sure that the short name is not matching *another* file
  */
-static int handle_commits(BDRVVVFATState* s)
+static int coroutine_fn handle_commits(BDRVVVFATState* s)
 {
     int i, fail = 0;
 
@@ -2705,7 +2705,7 @@  static int handle_deletes(BDRVVVFATState* s)
  * - recurse direntries from root (using bs->bdrv_read)
  * - delete files corresponding to mappings marked as deleted
  */
-static int do_commit(BDRVVVFATState* s)
+static int coroutine_fn do_commit(BDRVVVFATState* s)
 {
     int ret = 0;
 
@@ -2757,7 +2757,7 @@  DLOG(checkpoint());
     return 0;
 }
 
-static int try_commit(BDRVVVFATState* s)
+static int coroutine_fn try_commit(BDRVVVFATState* s)
 {
     vvfat_close_current_file(s);
 DLOG(checkpoint());
@@ -2766,7 +2766,7 @@  DLOG(checkpoint());
     return do_commit(s);
 }
 
-static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
+static int coroutine_fn vvfat_write(BlockDriverState *bs, int64_t sector_num,
                     const uint8_t *buf, int nb_sectors)
 {
     BDRVVVFATState *s = bs->opaque;
diff --git a/blockjob.c b/blockjob.c
index ca80df1..92bb98d 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -187,7 +187,7 @@  int block_job_cancel_sync(BlockJob *job)
     return (data.cancelled && data.ret == 0) ? -ECANCELED : data.ret;
 }
 
-void block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns)
+void coroutine_fn block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns)
 {
     assert(job->busy);
 
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index c290d07..ac06b85 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -141,7 +141,7 @@  void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs,
  * Put the job to sleep (assuming that it wasn't canceled) for @ns
  * nanoseconds.  Canceling the job will interrupt the wait immediately.
  */
-void block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns);
+void coroutine_fn block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns);
 
 /**
  * block_job_completed:
diff --git a/nbd.c b/nbd.c
index 2606403..dd835a3 100644
--- a/nbd.c
+++ b/nbd.c
@@ -971,7 +971,7 @@  static int nbd_can_read(void *opaque);
 static void nbd_read(void *opaque);
 static void nbd_restart_write(void *opaque);
 
-static ssize_t nbd_co_send_reply(NBDRequest *req, struct nbd_reply *reply,
+static ssize_t coroutine_fn nbd_co_send_reply(NBDRequest *req, struct nbd_reply *reply,
                                  int len)
 {
     NBDClient *client = req->client;
@@ -1055,7 +1055,7 @@  out:
     return rc;
 }
 
-static void nbd_trip(void *opaque)
+static void coroutine_fn nbd_trip(void *opaque)
 {
     NBDClient *client = opaque;
     NBDExport *exp = client->exp;
diff --git a/qemu-img.c b/qemu-img.c
index f8c97d3..eba5d2a 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -324,7 +324,7 @@  static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
     return 0;
 }
 
-static int img_create(int argc, char **argv)
+static int coroutine_fn img_create(int argc, char **argv)
 {
     int c;
     uint64_t img_size = -1;
@@ -519,7 +519,7 @@  static int collect_image_check(BlockDriverState *bs,
  * 2 - Check completed, image is corrupted
  * 3 - Check completed, image has leaked clusters, but is good otherwise
  */
-static int img_check(int argc, char **argv)
+static int coroutine_fn img_check(int argc, char **argv)
 {
     int c, ret;
     OutputFormat output_format = OFORMAT_HUMAN;
@@ -654,7 +654,7 @@  fail:
     return ret;
 }
 
-static int img_commit(int argc, char **argv)
+static int coroutine_fn img_commit(int argc, char **argv)
 {
     int c, ret, flags;
     const char *filename, *fmt, *cache;
@@ -851,7 +851,7 @@  static int64_t sectors_to_process(int64_t total, int64_t from)
  * @param buffer: Allocated buffer for storing read data
  * @param quiet: Flag for quiet mode
  */
-static int check_empty_sectors(BlockDriverState *bs, int64_t sect_num,
+static int coroutine_fn check_empty_sectors(BlockDriverState *bs, int64_t sect_num,
                                int sect_count, const char *filename,
                                uint8_t *buffer, bool quiet)
 {
@@ -879,7 +879,7 @@  static int check_empty_sectors(BlockDriverState *bs, int64_t sect_num,
  * 1 - Images differ
  * >1 - Error occurred
  */
-static int img_compare(int argc, char **argv)
+static int coroutine_fn img_compare(int argc, char **argv)
 {
     const char *fmt1 = NULL, *fmt2 = NULL, *filename1, *filename2;
     BlockDriverState *bs1, *bs2;
@@ -1111,7 +1111,7 @@  out3:
     return ret;
 }
 
-static int img_convert(int argc, char **argv)
+static int coroutine_fn img_convert(int argc, char **argv)
 {
     int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;
     int progress = 0, flags;
@@ -1701,7 +1701,7 @@  err:
     return NULL;
 }
 
-static int img_info(int argc, char **argv)
+static int coroutine_fn img_info(int argc, char **argv)
 {
     int c;
     OutputFormat output_format = OFORMAT_HUMAN;
@@ -1782,7 +1782,7 @@  static int img_info(int argc, char **argv)
 #define SNAPSHOT_APPLY  3
 #define SNAPSHOT_DELETE 4
 
-static int img_snapshot(int argc, char **argv)
+static int coroutine_fn img_snapshot(int argc, char **argv)
 {
     BlockDriverState *bs;
     QEMUSnapshotInfo sn;
@@ -1899,7 +1899,7 @@  static int img_snapshot(int argc, char **argv)
     return 0;
 }
 
-static int img_rebase(int argc, char **argv)
+static int coroutine_fn img_rebase(int argc, char **argv)
 {
     BlockDriverState *bs, *bs_old_backing = NULL, *bs_new_backing = NULL;
     BlockDriver *old_backing_drv, *new_backing_drv;
@@ -2181,7 +2181,7 @@  out:
     return 0;
 }
 
-static int img_resize(int argc, char **argv)
+static int coroutine_fn img_resize(int argc, char **argv)
 {
     int c, ret, relative;
     const char *filename, *fmt, *size;
@@ -2314,6 +2314,38 @@  static const img_cmd_t img_cmds[] = {
     { NULL, NULL, },
 };
 
+struct HandlerCo {
+    int coroutine_fn (*handler)(int, char **);
+    int argc;
+    char **argv;
+    int ret;
+};
+
+
+static void coroutine_fn handler_entry(void *opaque)
+{
+    struct HandlerCo *hco = opaque;
+    hco->ret = hco->handler(hco->argc, hco->argv);
+    hco->handler = NULL;
+}
+
+static int run_handler(int coroutine_fn (*handler)(int, char **), int argc, char **argv)
+{
+    struct HandlerCo hco = {
+        .handler = handler,
+        .argc = argc,
+        .argv = argv,
+    };
+
+    Coroutine *co = qemu_coroutine_create(handler_entry);
+    qemu_coroutine_enter(co, &hco);
+    while (hco.handler) {
+        qemu_aio_wait();
+    }
+
+    return hco.ret;
+}
+
 int main(int argc, char **argv)
 {
     const img_cmd_t *cmd;
@@ -2331,7 +2363,7 @@  int main(int argc, char **argv)
     /* find the command */
     for(cmd = img_cmds; cmd->name != NULL; cmd++) {
         if (!strcmp(cmdname, cmd->name)) {
-            return cmd->handler(argc, argv);
+            return run_handler(cmd->handler, argc, argv);
         }
     }
 
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index ffbcf31..d15c800 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -385,7 +385,7 @@  static int do_read(BlockDriverState *bs, char *buf, int64_t offset, int count,
 {
     int ret;
 
-    ret = bdrv_read(bs, offset >> 9, (uint8_t *)buf, count >> 9);
+    ret = bdrv_read_sync(bs, offset >> 9, (uint8_t *)buf, count >> 9);
     if (ret < 0) {
         return ret;
     }
@@ -398,7 +398,7 @@  static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
 {
     int ret;
 
-    ret = bdrv_write(bs, offset >> 9, (uint8_t *)buf, count >> 9);
+    ret = bdrv_write_sync(bs, offset >> 9, (uint8_t *)buf, count >> 9);
     if (ret < 0) {
         return ret;
     }
@@ -409,7 +409,7 @@  static int do_write(BlockDriverState *bs, char *buf, int64_t offset, int count,
 static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
                     int *total)
 {
-    *total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
+    *total = bdrv_pread_sync(bs, offset, (uint8_t *)buf, count);
     if (*total < 0) {
         return *total;
     }
@@ -419,7 +419,7 @@  static int do_pread(BlockDriverState *bs, char *buf, int64_t offset, int count,
 static int do_pwrite(BlockDriverState *bs, char *buf, int64_t offset, int count,
                      int *total)
 {
-    *total = bdrv_pwrite(bs, offset, (uint8_t *)buf, count);
+    *total = bdrv_pwrite_sync(bs, offset, (uint8_t *)buf, count);
     if (*total < 0) {
         return *total;
     }
@@ -1608,7 +1608,7 @@  static const cmdinfo_t aio_flush_cmd = {
 
 static int flush_f(BlockDriverState *bs, int argc, char **argv)
 {
-    bdrv_flush(bs);
+    bdrv_flush_sync(bs);
     return 0;
 }
 
@@ -1777,7 +1777,7 @@  static int discard_f(BlockDriverState *bs, int argc, char **argv)
     }
 
     gettimeofday(&t1, NULL);
-    ret = bdrv_discard(bs, offset >> BDRV_SECTOR_BITS,
+    ret = bdrv_discard_sync(bs, offset >> BDRV_SECTOR_BITS,
                        count >> BDRV_SECTOR_BITS);
     gettimeofday(&t2, NULL);