Patchwork [02/25,virtio-9p] Change all pdu handlers to coroutines.

login
register
mail settings
Submitter jvrao
Date May 12, 2011, 8:57 p.m.
Message ID <1305233867-4367-3-git-send-email-jvrao@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/95363/
State New
Headers show

Comments

jvrao - May 12, 2011, 8:57 p.m.
This patch changes the top level handlers to coroutines and sets the base.
It will be followed up with series of patches to convert all filesystem
calls to threaded coroutines pushing all blocking clals in VirtFS out
of vcpu threads.

Signed-off-by: Venkateswararao Jujjuri "<jvrao@linux.vnet.ibm.com>
---
 hw/9pfs/virtio-9p-coth.h |    7 ++
 hw/9pfs/virtio-9p.c      |  194 ++++++++++++++++++++++++++++++++++++----------
 hw/9pfs/virtio-9p.h      |    2 +-
 3 files changed, 161 insertions(+), 42 deletions(-)
Stefan Hajnoczi - May 13, 2011, 6:19 a.m.
On Thu, May 12, 2011 at 9:57 PM, Venkateswararao Jujjuri (JV)
<jvrao@linux.vnet.ibm.com> wrote:
> +typedef struct V9fsCoPdu {
> +    V9fsPDU *pdu;
> +    V9fsState *s;
> +    Coroutine *coroutine;
> +} V9fsCoPdu;

How about adding the V9fsState *s field to V9fsPDU?  Then you do not
need this new V9fsCoPdu struct and all the extracting fields/freeing
copdu.  You can use qemu_coroutine_self() if it is necessary to give
someone a reference to your coroutine.

Stefan

Patch

diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index fdc44f6..2ec1401 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -17,6 +17,7 @@ 
 
 #include "qemu-thread.h"
 #include "qemu-coroutine.h"
+#include "virtio-9p.h"
 #include <glib.h>
 
 typedef struct V9fsRequest {
@@ -34,6 +35,12 @@  typedef struct V9fsThPool {
     int wfd;
 } V9fsThPool;
 
+typedef struct V9fsCoPdu {
+    V9fsPDU *pdu;
+    V9fsState *s;
+    Coroutine *coroutine;
+} V9fsCoPdu;
+
 /* v9fs glib thread pool */
 extern V9fsThPool v9fs_pool;
 
diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index ec97b10..e308e9b 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -19,6 +19,7 @@ 
 #include "fsdev/qemu-fsdev.h"
 #include "virtio-9p-debug.h"
 #include "virtio-9p-xattr.h"
+#include "virtio-9p-coth.h"
 
 int debug_9p_pdu;
 
@@ -1192,8 +1193,11 @@  static void v9fs_fix_path(V9fsString *dst, V9fsString *src, int len)
     v9fs_string_free(&str);
 }
 
-static void v9fs_version(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_version(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     V9fsString version;
     size_t offset = 7;
 
@@ -1211,10 +1215,15 @@  static void v9fs_version(V9fsState *s, V9fsPDU *pdu)
     complete_pdu(s, pdu, offset);
 
     v9fs_string_free(&version);
+    qemu_free(copdu);
+    return;
 }
 
-static void v9fs_attach(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_attach(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid, afid, n_uname;
     V9fsString uname, aname;
     V9fsFidState *fidp;
@@ -1247,6 +1256,7 @@  out:
     complete_pdu(s, pdu, err);
     v9fs_string_free(&uname);
     v9fs_string_free(&aname);
+    qemu_free(copdu);
 }
 
 static void v9fs_stat_post_lstat(V9fsState *s, V9fsStatState *vs, int err)
@@ -1269,8 +1279,11 @@  out:
     qemu_free(vs);
 }
 
-static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_stat(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsStatState *vs;
     ssize_t err = 0;
@@ -1297,6 +1310,7 @@  out:
     complete_pdu(s, vs->pdu, err);
     v9fs_stat_free(&vs->v9stat);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 static void v9fs_getattr_post_lstat(V9fsState *s, V9fsStatStateDotl *vs,
@@ -1316,8 +1330,11 @@  out:
     qemu_free(vs);
 }
 
-static void v9fs_getattr(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_getattr(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsStatStateDotl *vs;
     ssize_t err = 0;
@@ -1348,6 +1365,7 @@  static void v9fs_getattr(V9fsState *s, V9fsPDU *pdu)
 out:
     complete_pdu(s, vs->pdu, err);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 /* From Linux kernel code */
@@ -1465,8 +1483,11 @@  out:
     qemu_free(vs);
 }
 
-static void v9fs_setattr(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_setattr(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsSetattrState *vs;
     int err = 0;
@@ -1493,6 +1514,7 @@  static void v9fs_setattr(V9fsState *s, V9fsPDU *pdu)
 out:
     complete_pdu(s, vs->pdu, err);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
@@ -1579,8 +1601,11 @@  out:
     v9fs_walk_complete(s, vs, err);
 }
 
-static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_walk(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid, newfid;
     V9fsWalkState *vs;
     int err = 0;
@@ -1658,6 +1683,7 @@  static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
     err = vs->offset;
 out:
     v9fs_walk_complete(s, vs, err);
+    qemu_free(copdu);
 }
 
 static int32_t get_iounit(V9fsState *s, V9fsString *name)
@@ -1751,8 +1777,11 @@  out:
     qemu_free(vs);
 }
 
-static void v9fs_open(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_open(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsOpenState *vs;
     ssize_t err = 0;
@@ -1783,6 +1812,7 @@  static void v9fs_open(V9fsState *s, V9fsPDU *pdu)
 out:
     complete_pdu(s, pdu, err);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 static void v9fs_post_lcreate(V9fsState *s, V9fsLcreateState *vs, int err)
@@ -1836,8 +1866,11 @@  out:
     v9fs_post_lcreate(s, vs, err);
 }
 
-static void v9fs_lcreate(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_lcreate(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t dfid, flags, mode;
     gid_t gid;
     V9fsLcreateState *vs;
@@ -1873,6 +1906,7 @@  out:
     complete_pdu(s, vs->pdu, err);
     v9fs_string_free(&vs->name);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 static void v9fs_post_do_fsync(V9fsState *s, V9fsPDU *pdu, int err)
@@ -1883,8 +1917,11 @@  static void v9fs_post_do_fsync(V9fsState *s, V9fsPDU *pdu, int err)
     complete_pdu(s, pdu, err);
 }
 
-static void v9fs_fsync(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_fsync(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     size_t offset = 7;
     V9fsFidState *fidp;
@@ -1900,10 +1937,14 @@  static void v9fs_fsync(V9fsState *s, V9fsPDU *pdu)
     }
     err = v9fs_do_fsync(s, fidp->fs.fd, datasync);
     v9fs_post_do_fsync(s, pdu, err);
+    qemu_free(copdu);
 }
 
-static void v9fs_clunk(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_clunk(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     size_t offset = 7;
     int err;
@@ -1919,6 +1960,7 @@  static void v9fs_clunk(V9fsState *s, V9fsPDU *pdu)
     err = offset;
 out:
     complete_pdu(s, pdu, err);
+    qemu_free(copdu);
 }
 
 static void v9fs_read_post_readdir(V9fsState *, V9fsReadState *, ssize_t);
@@ -2068,8 +2110,11 @@  static void v9fs_xattr_read(V9fsState *s, V9fsReadState *vs)
     qemu_free(vs);
 }
 
-static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_read(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsReadState *vs;
     ssize_t err = 0;
@@ -2120,6 +2165,7 @@  static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
 out:
     complete_pdu(s, pdu, err);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 typedef struct V9fsReadDirState {
@@ -2207,8 +2253,11 @@  static void v9fs_readdir_post_setdir(V9fsState *s, V9fsReadDirState *vs)
     return;
 }
 
-static void v9fs_readdir(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_readdir(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsReadDirState *vs;
     ssize_t err = 0;
@@ -2240,7 +2289,7 @@  static void v9fs_readdir(V9fsState *s, V9fsPDU *pdu)
 out:
     complete_pdu(s, pdu, err);
     qemu_free(vs);
-    return;
+    qemu_free(copdu);
 }
 
 static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs,
@@ -2319,8 +2368,11 @@  out:
     qemu_free(vs);
 }
 
-static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_write(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsWriteState *vs;
     ssize_t err;
@@ -2370,6 +2422,7 @@  static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
 out:
     complete_pdu(s, vs->pdu, err);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 static void v9fs_create_post_getiounit(V9fsState *s, V9fsCreateState *vs)
@@ -2553,8 +2606,11 @@  out:
     v9fs_post_create(s, vs, err);
 }
 
-static void v9fs_create(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_create(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsCreateState *vs;
     int err = 0;
@@ -2586,6 +2642,7 @@  out:
     v9fs_string_free(&vs->name);
     v9fs_string_free(&vs->extension);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 static void v9fs_post_symlink(V9fsState *s, V9fsSymlinkState *vs, int err)
@@ -2615,8 +2672,11 @@  out:
     v9fs_post_symlink(s, vs, err);
 }
 
-static void v9fs_symlink(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_symlink(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t dfid;
     V9fsSymlinkState *vs;
     int err = 0;
@@ -2649,16 +2709,25 @@  out:
     v9fs_string_free(&vs->name);
     v9fs_string_free(&vs->symname);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
-static void v9fs_flush(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_flush(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     /* A nop call with no return */
     complete_pdu(s, pdu, 7);
+    qemu_free(copdu);
+    return;
 }
 
-static void v9fs_link(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_link(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t dfid, oldfid;
     V9fsFidState *dfidp, *oldfidp;
     V9fsString name, fullname;
@@ -2692,6 +2761,7 @@  static void v9fs_link(V9fsState *s, V9fsPDU *pdu)
 out:
     v9fs_string_free(&name);
     complete_pdu(s, pdu, err);
+    qemu_free(copdu);
 }
 
 static void v9fs_remove_post_remove(V9fsState *s, V9fsRemoveState *vs,
@@ -2710,8 +2780,11 @@  static void v9fs_remove_post_remove(V9fsState *s, V9fsRemoveState *vs,
     qemu_free(vs);
 }
 
-static void v9fs_remove(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_remove(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsRemoveState *vs;
     int err = 0;
@@ -2735,6 +2808,7 @@  static void v9fs_remove(V9fsState *s, V9fsPDU *pdu)
 out:
     complete_pdu(s, pdu, err);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 static void v9fs_wstat_post_truncate(V9fsState *s, V9fsWstatState *vs, int err)
@@ -2877,8 +2951,11 @@  out:
     qemu_free(vs);
 }
 
-static void v9fs_rename(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_rename(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsRenameState *vs;
     ssize_t err = 0;
@@ -2903,6 +2980,7 @@  static void v9fs_rename(V9fsState *s, V9fsPDU *pdu)
 out:
     complete_pdu(s, vs->pdu, err);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 static void v9fs_wstat_post_utime(V9fsState *s, V9fsWstatState *vs, int err)
@@ -3002,8 +3080,11 @@  out:
     qemu_free(vs);
 }
 
-static void v9fs_wstat(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_wstat(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsWstatState *vs;
     int err = 0;
@@ -3040,6 +3121,7 @@  out:
     v9fs_stat_free(&vs->v9stat);
     complete_pdu(s, vs->pdu, err);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 static void v9fs_statfs_post_statfs(V9fsState *s, V9fsStatfsState *vs, int err)
@@ -3087,8 +3169,11 @@  out:
     qemu_free(vs);
 }
 
-static void v9fs_statfs(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_statfs(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     V9fsStatfsState *vs;
     ssize_t err = 0;
 
@@ -3113,6 +3198,8 @@  static void v9fs_statfs(V9fsState *s, V9fsPDU *pdu)
 out:
     complete_pdu(s, vs->pdu, err);
     qemu_free(vs);
+    qemu_free(copdu);
+    return;
 }
 
 static void v9fs_mknod_post_lstat(V9fsState *s, V9fsMkState *vs, int err)
@@ -3149,8 +3236,11 @@  out:
     qemu_free(vs);
 }
 
-static void v9fs_mknod(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_mknod(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsMkState *vs;
     int err = 0;
@@ -3184,6 +3274,7 @@  out:
     v9fs_string_free(&vs->fullname);
     v9fs_string_free(&vs->name);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 /*
@@ -3195,8 +3286,11 @@  out:
  * So when a TLOCK request comes, always return success
  */
 
-static void v9fs_lock(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_lock(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid, err = 0;
     V9fsLockState *vs;
 
@@ -3233,6 +3327,7 @@  out:
     complete_pdu(s, vs->pdu, err);
     qemu_free(vs->flock);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 /*
@@ -3240,8 +3335,11 @@  out:
  * handling is done by client's VFS layer.
  */
 
-static void v9fs_getlock(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_getlock(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid, err = 0;
     V9fsGetlockState *vs;
 
@@ -3273,6 +3371,7 @@  out:
     complete_pdu(s, vs->pdu, err);
     qemu_free(vs->glock);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 static void v9fs_mkdir_post_lstat(V9fsState *s, V9fsMkState *vs, int err)
@@ -3309,8 +3408,11 @@  out:
     qemu_free(vs);
 }
 
-static void v9fs_mkdir(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_mkdir(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsMkState *vs;
     int err = 0;
@@ -3342,6 +3444,7 @@  out:
     v9fs_string_free(&vs->fullname);
     v9fs_string_free(&vs->name);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 static void v9fs_post_xattr_getvalue(V9fsState *s, V9fsXattrState *vs, int err)
@@ -3433,8 +3536,11 @@  out:
     qemu_free(vs);
 }
 
-static void v9fs_xattrwalk(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_xattrwalk(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     ssize_t err = 0;
     V9fsXattrState *vs;
     int32_t fid, newfid;
@@ -3485,10 +3591,14 @@  out:
     complete_pdu(s, vs->pdu, err);
     v9fs_string_free(&vs->name);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
-static void v9fs_xattrcreate(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_xattrcreate(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int flags;
     int32_t fid;
     ssize_t err = 0;
@@ -3524,6 +3634,7 @@  out:
     complete_pdu(s, vs->pdu, err);
     v9fs_string_free(&vs->name);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
 static void v9fs_readlink_post_readlink(V9fsState *s, V9fsReadLinkState *vs,
@@ -3541,8 +3652,11 @@  out:
     qemu_free(vs);
 }
 
-static void v9fs_readlink(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_readlink(void *opaque)
 {
+    V9fsCoPdu *copdu = opaque;
+    V9fsState *s = copdu->s;
+    V9fsPDU *pdu = copdu->pdu;
     int32_t fid;
     V9fsReadLinkState *vs;
     int err = 0;
@@ -3567,11 +3681,10 @@  static void v9fs_readlink(V9fsState *s, V9fsPDU *pdu)
 out:
     complete_pdu(s, vs->pdu, err);
     qemu_free(vs);
+    qemu_free(copdu);
 }
 
-typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU *pdu);
-
-static pdu_handler_t *pdu_handlers[] = {
+static CoroutineEntry *pdu_co_handlers[] = {
     [P9_TREADDIR] = v9fs_readdir,
     [P9_TSTATFS] = v9fs_statfs,
     [P9_TGETATTR] = v9fs_getattr,
@@ -3608,18 +3721,17 @@  static pdu_handler_t *pdu_handlers[] = {
 
 static void submit_pdu(V9fsState *s, V9fsPDU *pdu)
 {
-    pdu_handler_t *handler;
-
+    V9fsCoPdu *copdu;
     if (debug_9p_pdu) {
         pprint_pdu(pdu);
     }
-
-    BUG_ON(pdu->id >= ARRAY_SIZE(pdu_handlers));
-
-    handler = pdu_handlers[pdu->id];
-    BUG_ON(handler == NULL);
-
-    handler(s, pdu);
+    BUG_ON(pdu->id >= ARRAY_SIZE(pdu_co_handlers));
+    BUG_ON(pdu_co_handlers[pdu->id] == NULL);
+    copdu = qemu_malloc(sizeof(V9fsCoPdu));
+    copdu->s = s;
+    copdu->pdu = pdu;
+    copdu->coroutine = qemu_coroutine_create(pdu_co_handlers[pdu->id]);
+    qemu_coroutine_enter(copdu->coroutine, copdu);
 }
 
 void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 699d3ab..5021da8 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -5,7 +5,7 @@ 
 #include <dirent.h>
 #include <sys/time.h>
 #include <utime.h>
-
+#include "hw/virtio.h"
 #include "fsdev/file-op-9p.h"
 
 /* The feature bitmap for virtio 9P */