From: Sripathi Kodi <sripat...@in.ibm.com> Signed-off-by: Sripathi Kodi <sripat...@in.ibm.com> --- hw/virtio-9p.c | 92 +++++++++++++++++++++----------------------------------- hw/virtio-9p.h | 4 ++ 2 files changed, 39 insertions(+), 57 deletions(-)
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c index 82f0ed2..47bcbd1 100644 --- a/hw/virtio-9p.c +++ b/hw/virtio-9p.c @@ -2244,40 +2244,6 @@ out: return; } -static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs, - ssize_t err) -{ - if (err < 0) { - /* IO error return the error */ - err = -errno; - goto out; - } - vs->total += vs->len; - vs->sg = adjust_sg(vs->sg, vs->len, &vs->cnt); - if (vs->total < vs->count && vs->len > 0) { - do { - if (0) { - print_sg(vs->sg, vs->cnt); - } - vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt, - vs->off); - if (vs->len > 0) { - vs->off += vs->len; - } - } while (vs->len == -1 && errno == EINTR); - if (vs->len == -1) { - err = -errno; - } - v9fs_write_post_pwritev(s, vs, err); - return; - } - vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total); - err = vs->offset; -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - static void v9fs_xattr_write(V9fsState *s, V9fsWriteState *vs) { int i, to_copy; @@ -2320,32 +2286,26 @@ out: qemu_free(vs); } -static void v9fs_write(V9fsState *s, V9fsPDU *pdu) +static void v9fs_write_do_complete(void *opaque) { - int32_t fid; - V9fsWriteState *vs; - ssize_t err; - - vs = qemu_malloc(sizeof(*vs)); + V9fsWriteState *vs = (V9fsWriteState *)opaque; - vs->pdu = pdu; - vs->offset = 7; - vs->sg = vs->iov; - vs->total = 0; - vs->len = 0; - - pdu_unmarshal(vs->pdu, vs->offset, "dqdv", &fid, &vs->off, &vs->count, - vs->sg, &vs->cnt); + complete_pdu(vs->s, vs->pdu, vs->err); + qemu_free(vs); +} - vs->fidp = lookup_fid(s, fid); +static void v9fs_write_worker(ThreadletWork *work) +{ + V9fsWriteState *vs = container_of(work, V9fsWriteState, work); + vs->fidp = lookup_fid(vs->s, vs->fid); if (vs->fidp == NULL) { - err = -EINVAL; + vs->err = -EINVAL; goto out; } if (vs->fidp->fid_type == P9_FID_FILE) { if (vs->fidp->fs.fd == -1) { - err = -EINVAL; + vs->err = -EINVAL; goto out; } } else if (vs->fidp->fid_type == P9_FID_XATTR) { @@ -2355,7 +2315,7 @@ static void v9fs_write(V9fsState *s, V9fsPDU *pdu) v9fs_xattr_write(s, vs); return; } else { - err = -EINVAL; + vs->err = -EINVAL; goto out; } vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt); @@ -2364,13 +2324,31 @@ static void v9fs_write(V9fsState *s, V9fsPDU *pdu) if (vs->len > 0) { vs->off += vs->len; } - err = vs->len; - v9fs_write_post_pwritev(s, vs, err); + vs->err = vs->len; } - return; out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); + v9fs_async_helper_done(v9fs_write_do_complete, vs); +} + +static void v9fs_write(V9fsState *s, V9fsPDU *pdu) +{ + V9fsWriteState *vs; + + vs = qemu_malloc(sizeof(*vs)); + + vs->pdu = pdu; + vs->offset = 7; + vs->sg = vs->iov; + vs->total = 0; + vs->len = 0; + vs->s = s; + + pdu_unmarshal(vs->pdu, vs->offset, "dqdv", &vs->fid, &vs->off, &vs->count, + vs->sg, &vs->cnt); + + vs->work.func = v9fs_write_worker; + submit_threadlet(&vs->work); + return; } static void v9fs_create_post_getiounit(V9fsState *s, V9fsCreateState *vs) diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h index 5c6bf74..78d35b5 100644 --- a/hw/virtio-9p.h +++ b/hw/virtio-9p.h @@ -351,6 +351,10 @@ typedef struct V9fsWriteState { struct iovec iov[128]; /* FIXME: bad, bad, bad */ struct iovec *sg; int cnt; + V9fsState *s; + int32_t fid; + int32_t err; + ThreadletWork work; } V9fsWriteState; typedef struct V9fsRemoveState {