#include "fsdev/qemu-fsdev.h"
#include "virtio-9p-debug.h"
#include "virtio-9p-xattr.h"
+#include "virtio-9p-coth.h"
int debug_9p_pdu;
v9fs_string_free(&str);
}
-static void v9fs_version(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_version(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
V9fsString version;
size_t offset = 7;
complete_pdu(s, pdu, offset);
v9fs_string_free(&version);
+ return;
}
-static void v9fs_attach(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_attach(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid, afid, n_uname;
V9fsString uname, aname;
V9fsFidState *fidp;
qemu_free(vs);
}
-static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_stat(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsStatState *vs;
ssize_t err = 0;
qemu_free(vs);
}
-static void v9fs_getattr(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_getattr(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsStatStateDotl *vs;
ssize_t err = 0;
qemu_free(vs);
}
-static void v9fs_setattr(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_setattr(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsSetattrState *vs;
int err = 0;
v9fs_walk_complete(s, vs, err);
}
-static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_walk(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid, newfid;
V9fsWalkState *vs;
int err = 0;
qemu_free(vs);
}
-static void v9fs_open(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_open(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsOpenState *vs;
ssize_t err = 0;
v9fs_post_lcreate(s, vs, err);
}
-static void v9fs_lcreate(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_lcreate(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t dfid, flags, mode;
gid_t gid;
V9fsLcreateState *vs;
complete_pdu(s, pdu, err);
}
-static void v9fs_fsync(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_fsync(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
size_t offset = 7;
V9fsFidState *fidp;
v9fs_post_do_fsync(s, pdu, err);
}
-static void v9fs_clunk(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_clunk(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
size_t offset = 7;
int err;
qemu_free(vs);
}
-static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_read(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsReadState *vs;
ssize_t err = 0;
return;
}
-static void v9fs_readdir(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_readdir(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsReadDirState *vs;
ssize_t err = 0;
out:
complete_pdu(s, pdu, err);
qemu_free(vs);
- return;
}
static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs,
qemu_free(vs);
}
-static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_write(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsWriteState *vs;
ssize_t err;
v9fs_post_create(s, vs, err);
}
-static void v9fs_create(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_create(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsCreateState *vs;
int err = 0;
v9fs_post_symlink(s, vs, err);
}
-static void v9fs_symlink(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_symlink(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t dfid;
V9fsSymlinkState *vs;
int err = 0;
qemu_free(vs);
}
-static void v9fs_flush(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_flush(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
/* A nop call with no return */
complete_pdu(s, pdu, 7);
+ return;
}
-static void v9fs_link(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_link(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t dfid, oldfid;
V9fsFidState *dfidp, *oldfidp;
V9fsString name, fullname;
qemu_free(vs);
}
-static void v9fs_remove(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_remove(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsRemoveState *vs;
int err = 0;
qemu_free(vs);
}
-static void v9fs_rename(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_rename(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsRenameState *vs;
ssize_t err = 0;
qemu_free(vs);
}
-static void v9fs_wstat(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_wstat(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsWstatState *vs;
int err = 0;
qemu_free(vs);
}
-static void v9fs_statfs(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_statfs(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
V9fsStatfsState *vs;
ssize_t err = 0;
out:
complete_pdu(s, vs->pdu, err);
qemu_free(vs);
+ return;
}
static void v9fs_mknod_post_lstat(V9fsState *s, V9fsMkState *vs, int err)
qemu_free(vs);
}
-static void v9fs_mknod(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_mknod(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsMkState *vs;
int err = 0;
* So when a TLOCK request comes, always return success
*/
-static void v9fs_lock(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_lock(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid, err = 0;
V9fsLockState *vs;
* handling is done by client's VFS layer.
*/
-static void v9fs_getlock(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_getlock(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid, err = 0;
V9fsGetlockState *vs;
qemu_free(vs);
}
-static void v9fs_mkdir(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_mkdir(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsMkState *vs;
int err = 0;
qemu_free(vs);
}
-static void v9fs_xattrwalk(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_xattrwalk(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
ssize_t err = 0;
V9fsXattrState *vs;
int32_t fid, newfid;
qemu_free(vs);
}
-static void v9fs_xattrcreate(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_xattrcreate(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int flags;
int32_t fid;
ssize_t err = 0;
qemu_free(vs);
}
-static void v9fs_readlink(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_readlink(void *opaque)
{
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
int32_t fid;
V9fsReadLinkState *vs;
int err = 0;
qemu_free(vs);
}
-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,
[P9_TREMOVE] = v9fs_remove,
};
-static void v9fs_op_not_supp(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_op_not_supp(void *opaque)
{
- complete_pdu(s, pdu, -EOPNOTSUPP);
+ V9fsPDU *pdu = opaque;
+ complete_pdu(pdu->s, pdu, -EOPNOTSUPP);
}
static void submit_pdu(V9fsState *s, V9fsPDU *pdu)
{
- pdu_handler_t *handler;
+ Coroutine *co;
+ CoroutineEntry *handler;
if (debug_9p_pdu) {
pprint_pdu(pdu);
}
- if (pdu->id >= ARRAY_SIZE(pdu_handlers) ||
- (pdu_handlers[pdu->id] == NULL)) {
+ if (pdu->id >= ARRAY_SIZE(pdu_co_handlers) ||
+ (pdu_co_handlers[pdu->id] == NULL)) {
handler = v9fs_op_not_supp;
} else {
- handler = pdu_handlers[pdu->id];
+ handler = pdu_co_handlers[pdu->id];
}
- handler(s, pdu);
+ co = qemu_coroutine_create(handler);
+ qemu_coroutine_enter(co, pdu);
}
void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
while ((pdu = alloc_pdu(s)) &&
(len = virtqueue_pop(vq, &pdu->elem)) != 0) {
uint8_t *ptr;
-
+ pdu->s = s;
BUG_ON(pdu->elem.out_num == 0 || pdu->elem.in_num == 0);
BUG_ON(pdu->elem.out_sg[0].iov_len < 7);
memcpy(&pdu->size, ptr, 4);
pdu->id = ptr[4];
memcpy(&pdu->tag, ptr + 5, 2);
-
submit_pdu(s, pdu);
}
-
free_pdu(s, pdu);
}