From: Sripathi Kodi <sripat...@in.ibm.com> Signed-off-by: Sripathi Kodi <sripat...@in.ibm.com> --- hw/virtio-9p.c | 115 +++++++++++++++++++++++--------------------------------- hw/virtio-9p.h | 4 ++ 2 files changed, 51 insertions(+), 68 deletions(-)
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c index 1f2fd9f..cad21fd 100644 --- a/hw/virtio-9p.c +++ b/hw/virtio-9p.c @@ -1797,6 +1797,13 @@ out: v9fs_walk_complete(s, vs, err); } +static void v9fs_open_do_complete(void *opaque) +{ + V9fsOpenState *vs = (V9fsOpenState *)opaque; + complete_pdu(vs->s, vs->pdu, vs->err); + qemu_free(vs); +} + static int32_t get_iounit(V9fsState *s, V9fsString *name) { struct statfs stbuf; @@ -1817,61 +1824,37 @@ static int32_t get_iounit(V9fsState *s, V9fsString *name) return iounit; } -static void v9fs_open_post_opendir(V9fsState *s, V9fsOpenState *vs, int err) -{ - if (vs->fidp->fs.dir == NULL) { - err = -errno; - goto out; - } - vs->fidp->fid_type = P9_FID_DIR; - vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, 0); - err = vs->offset; -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); - -} - -static void v9fs_open_post_getiounit(V9fsState *s, V9fsOpenState *vs) -{ - int err; - vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, vs->iounit); - err = vs->offset; - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_open_post_open(V9fsState *s, V9fsOpenState *vs, int err) +static void v9fs_open_worker(ThreadletWork *work) { - if (vs->fidp->fs.fd == -1) { - err = -errno; + int flags; + V9fsOpenState *vs = container_of(work, V9fsOpenState, work); + vs->fidp = lookup_fid(vs->s, vs->fid); + if (vs->fidp == NULL) { + vs->err = -ENOENT; goto out; } - vs->fidp->fid_type = P9_FID_FILE; - vs->iounit = get_iounit(s, &vs->fidp->path); - v9fs_open_post_getiounit(s, vs); - return; -out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); -} - -static void v9fs_open_post_lstat(V9fsState *s, V9fsOpenState *vs, int err) -{ - int flags; - - if (err) { - err = -errno; + BUG_ON(vs->fidp->fid_type != P9_FID_NONE); + qemu_rwmutex_rdlock(&global_rename_lock); + vs->err = v9fs_do_lstat(vs->s, &vs->fidp->path, &vs->stbuf); + if (vs->err) { + vs->err = -errno; goto out; } stat_to_qid(&vs->stbuf, &vs->qid); if (S_ISDIR(vs->stbuf.st_mode)) { - vs->fidp->fs.dir = v9fs_do_opendir(s, &vs->fidp->path); - v9fs_open_post_opendir(s, vs, err); + vs->fidp->fs.dir = v9fs_do_opendir(vs->s, &vs->fidp->path); + + if (vs->fidp->fs.dir == NULL) { + vs->err = -errno; + goto out; + } + vs->fidp->fid_type = P9_FID_DIR; + vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, 0); + vs->err = vs->offset; } else { - if (s->proto_version == V9FS_PROTO_2000L) { + if (vs->s->proto_version == V9FS_PROTO_2000L) { flags = vs->mode; flags &= ~(O_NOCTTY | O_ASYNC | O_CREAT); /* Ignore direct disk access hint until the server supports it. */ @@ -1879,47 +1862,43 @@ static void v9fs_open_post_lstat(V9fsState *s, V9fsOpenState *vs, int err) } else { flags = omode_to_uflags(vs->mode); } - vs->fidp->fs.fd = v9fs_do_open(s, &vs->fidp->path, flags); - v9fs_open_post_open(s, vs, err); + vs->fidp->fs.fd = v9fs_do_open(vs->s, &vs->fidp->path, flags); + + if (vs->fidp->fs.fd == -1) { + vs->err = -errno; + goto out; + } + vs->fidp->fid_type = P9_FID_FILE; + vs->iounit = get_iounit(vs->s, &vs->fidp->path); + vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, + vs->iounit); + vs->err = vs->offset; } - return; out: - complete_pdu(s, vs->pdu, err); - qemu_free(vs); + qemu_rwmutex_unlock(&global_rename_lock); + v9fs_async_helper_done(v9fs_open_do_complete, vs); } static void v9fs_open(V9fsState *s, V9fsPDU *pdu) { - int32_t fid; V9fsOpenState *vs; - ssize_t err = 0; vs = qemu_malloc(sizeof(*vs)); vs->pdu = pdu; vs->offset = 7; vs->mode = 0; + vs->err = 0; + vs->s = s; if (s->proto_version == V9FS_PROTO_2000L) { - pdu_unmarshal(vs->pdu, vs->offset, "dd", &fid, &vs->mode); + pdu_unmarshal(vs->pdu, vs->offset, "dd", &vs->fid, &vs->mode); } else { - pdu_unmarshal(vs->pdu, vs->offset, "db", &fid, &vs->mode); + pdu_unmarshal(vs->pdu, vs->offset, "db", &vs->fid, &vs->mode); } - vs->fidp = lookup_fid(s, fid); - if (vs->fidp == NULL) { - err = -ENOENT; - goto out; - } - - BUG_ON(vs->fidp->fid_type != P9_FID_NONE); - - err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf); - - v9fs_open_post_lstat(s, vs, err); + vs->work.func = v9fs_open_worker; + submit_threadlet(&vs->work); return; -out: - complete_pdu(s, pdu, err); - qemu_free(vs); } static void v9fs_post_lcreate(V9fsState *s, V9fsLcreateState *vs, int err) diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h index 59f7a4e..1581bbe 100644 --- a/hw/virtio-9p.h +++ b/hw/virtio-9p.h @@ -306,6 +306,10 @@ typedef struct V9fsOpenState { V9fsQID qid; struct stat stbuf; int iounit; + V9fsState *s; + int32_t fid; + int32_t err; + ThreadletWork work; } V9fsOpenState; typedef struct V9fsReadState {