All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <aliguori@us.ibm.com>
To: qemu-devel@nongnu.org
Cc: Anthony Liguori <aliguori@us.ibm.com>,
	"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>,
	Gautham R Shenoy <ego@in.ibm.com>
Subject: [Qemu-devel] [PATCH 05/17] virtio-9p: Implement P9_TWALK
Date: Wed,  3 Mar 2010 13:01:02 -0600	[thread overview]
Message-ID: <1267642874-15001-7-git-send-email-aliguori@us.ibm.com> (raw)
In-Reply-To: <1267642874-15001-1-git-send-email-aliguori@us.ibm.com>

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 hw/virtio-9p-local.c |   12 +++
 hw/virtio-9p.c       |  219 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 229 insertions(+), 2 deletions(-)

diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
index 9752f76..ac0dce5 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -78,10 +78,22 @@ static ssize_t local_readlink(void *opaque, const char *path,
     return readlink(rpath(path), buf, bufsz);
 }
 
+static int local_close(void *opaque, int fd)
+{
+    return close(fd);
+}
+
+static int local_closedir(void *opaque, DIR *dir)
+{
+    return closedir(dir);
+}
+
 static V9fsPosixFileOperations ops = {
     .lstat = local_lstat,
     .setuid = local_setuid,
     .readlink = local_readlink,
+    .close = local_close,
+    .closedir = local_closedir,
 };
 
 V9fsPosixFileOperations *virtio_9p_init_local(const char *path)
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 10bcd89..685646a 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -117,6 +117,22 @@ static ssize_t posix_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
     return len;
 }
 
+static int posix_close(V9fsState *s, int fd)
+{
+    return s->ops->close(s->ops->opaque, fd);
+}
+
+static int posix_closedir(V9fsState *s, DIR *dir)
+{
+    return s->ops->closedir(s->ops->opaque, dir);
+}
+
+static void v9fs_string_init(V9fsString *str)
+{
+    str->data = NULL;
+    str->size = 0;
+}
+
 static void v9fs_string_free(V9fsString *str)
 {
     free(str->data);
@@ -144,6 +160,12 @@ static void v9fs_string_sprintf(V9fsString *str, const char *fmt, ...)
     str->size = err;
 }
 
+static void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs)
+{
+    v9fs_string_free(lhs);
+    v9fs_string_sprintf(lhs, "%s", rhs->data);
+}
+
 static size_t v9fs_string_size(V9fsString *str)
 {
     return str->size;
@@ -184,6 +206,31 @@ static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid)
     return f;
 }
 
+static int free_fid(V9fsState *s, int32_t fid)
+{
+    V9fsFidState **fidpp, *fidp;
+
+    for (fidpp = &s->fid_list; *fidpp; fidpp = &(*fidpp)->next) {
+	if ((*fidpp)->fid == fid)
+	    break;
+    }
+
+    if (*fidpp == NULL)
+	return -ENOENT;
+
+    fidp = *fidpp;
+    *fidpp = fidp->next;
+
+    if (fidp->fd != -1)
+	posix_close(s, fidp->fd);
+    if (fidp->dir)
+	posix_closedir(s, fidp->dir);
+    v9fs_string_free(&fidp->path);
+    qemu_free(fidp);
+
+    return 0;
+}
+
 #define P9_QID_TYPE_DIR		0x80
 #define P9_QID_TYPE_SYMLINK	0x02
 
@@ -691,10 +738,178 @@ out:
     qemu_free(vs);
 }
 
+typedef struct V9fsWalkState {
+    V9fsPDU *pdu;
+    size_t offset;
+    int32_t fid;
+    int32_t newfid;
+    int16_t nwnames;
+    int name_idx;
+    V9fsQID *qids;
+    V9fsFidState *fidp;
+    V9fsFidState *newfidp;
+    V9fsString path;
+    V9fsString *wnames;
+    struct stat stbuf;
+} V9fsWalkState;
+
+static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
+{
+    complete_pdu(s, vs->pdu, err);
+
+    if(vs->nwnames) {
+        for (vs->name_idx = 0; vs->name_idx < vs->nwnames; vs->name_idx++)
+            v9fs_string_free(&vs->wnames[vs->name_idx]);
+
+        qemu_free(vs->wnames);
+        qemu_free(vs->qids);
+    }
+}
+
+static void v9fs_walk_marshal(V9fsWalkState *vs)
+{
+    int i;
+    vs->offset = 7;
+    vs->offset += pdu_marshal(vs->pdu, vs->offset, "w", vs->nwnames);
+
+    for (i = 0; i < vs->nwnames; i++)
+        vs->offset += pdu_marshal(vs->pdu, vs->offset, "Q", &vs->qids[i]);
+}
+
+static void v9fs_walk_post_newfid_lstat(V9fsState *s, V9fsWalkState *vs,
+                                                                int err)
+{
+    if (err == -1) {
+        free_fid(s, vs->newfid);
+        v9fs_string_free(&vs->path);
+        err = -ENOENT;
+        goto out;
+    }
+
+    stat_to_qid(&vs->stbuf, &vs->qids[vs->name_idx]);
+
+    vs->name_idx++;
+    if (vs->name_idx < vs->nwnames) {
+        v9fs_string_sprintf(&vs->path, "%s/%s", vs->newfidp->path.data,
+                                            vs->wnames[vs->name_idx].data);
+        v9fs_string_copy(&vs->newfidp->path, &vs->path);
+
+        err = posix_lstat(s, &vs->newfidp->path, &vs->stbuf);
+        v9fs_walk_post_newfid_lstat(s, vs, err);
+        return;
+    }
+
+    v9fs_string_free(&vs->path);
+    v9fs_walk_marshal(vs);
+    err = vs->offset;
+out:
+    v9fs_walk_complete(s, vs, err);
+}
+
+static void v9fs_walk_post_oldfid_lstat(V9fsState *s, V9fsWalkState *vs,
+                                                                int err)
+{
+    if (err == -1) {
+        v9fs_string_free(&vs->path);
+        err = -ENOENT;
+        goto out;
+    }
+
+    stat_to_qid(&vs->stbuf, &vs->qids[vs->name_idx]);
+    vs->name_idx++;
+    if (vs->name_idx < vs->nwnames) {
+
+            v9fs_string_sprintf(&vs->path, "%s/%s",
+                vs->fidp->path.data, vs->wnames[vs->name_idx].data);
+            v9fs_string_copy(&vs->fidp->path, &vs->path);
+
+            err = posix_lstat(s, &vs->fidp->path, &vs->stbuf);
+            v9fs_walk_post_oldfid_lstat(s, vs, err);
+            return;
+    }
+
+    v9fs_string_free(&vs->path);
+    v9fs_walk_marshal(vs);
+    err = vs->offset;
+out:
+    v9fs_walk_complete(s, vs, err);
+}
+
 static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
 {
-    if (debug_9p_pdu)
-	pprint_pdu(pdu);
+    V9fsWalkState *vs;
+    int err = 0;
+    int i;
+
+    vs = qemu_malloc(sizeof(*vs));
+    vs->pdu =pdu;
+    vs->wnames = NULL;
+    vs->qids = NULL;
+    vs->offset = 7;
+
+    vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "ddw", &vs->fid,
+                                            &vs->newfid, &vs->nwnames);
+
+    if(vs->nwnames) {
+        vs->wnames = qemu_mallocz(sizeof(vs->wnames[0]) * vs->nwnames);
+        BUG_ON(vs->wnames == NULL);
+
+        vs->qids = qemu_mallocz(sizeof(vs->qids[0]) * vs->nwnames);
+        BUG_ON(vs->qids == NULL);
+
+        for (i = 0; i < vs->nwnames; i++) {
+            vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "s",
+                                            &vs->wnames[i]);
+        }
+    }
+
+    vs->fidp = lookup_fid(s, vs->fid);
+    if (vs->fidp == NULL) {
+        err = -ENOENT;
+        goto out;
+    }
+
+    /* FIXME: is this really valid? */
+    if (vs->fid == vs->newfid) {
+        v9fs_string_init(&vs->path);
+        vs->name_idx = 0;
+
+        if (vs->name_idx < vs->nwnames) {
+            v9fs_string_sprintf(&vs->path, "%s/%s",
+                vs->fidp->path.data, vs->wnames[vs->name_idx].data);
+            v9fs_string_copy(&vs->fidp->path, &vs->path);
+
+            err = posix_lstat(s, &vs->fidp->path, &vs->stbuf);
+            v9fs_walk_post_oldfid_lstat(s, vs, err);
+            return;
+        }
+    } else {
+        vs->newfidp = alloc_fid(s, vs->newfid);
+        if (vs->newfidp == NULL) {
+            err = -EINVAL;
+            goto out;
+        }
+
+        vs->newfidp->uid = vs->fidp->uid;
+        v9fs_string_init(&vs->path);
+        vs->name_idx = 0;
+        v9fs_string_copy(&vs->newfidp->path, &vs->fidp->path);
+
+        if (vs->name_idx < vs->nwnames) {
+            v9fs_string_sprintf(&vs->path, "%s/%s", vs->newfidp->path.data,
+                                vs->wnames[vs->name_idx].data);
+            v9fs_string_copy(&vs->newfidp->path, &vs->path);
+
+            err = posix_lstat(s, &vs->newfidp->path, &vs->stbuf);
+            v9fs_walk_post_newfid_lstat(s, vs, err);
+            return;
+        }
+    }
+
+    v9fs_walk_marshal(vs);
+    err = vs->offset;
+out:
+    v9fs_walk_complete(s, vs, err);
 }
 
 static void v9fs_clunk(V9fsState *s, V9fsPDU *pdu)
-- 
1.6.5.2

  parent reply	other threads:[~2010-03-03 19:01 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-03 19:00 [Qemu-devel] [PATCH 00/17][RFC] virtio-9p: paravirtual filesystem passthrough Anthony Liguori
2010-03-03 19:00 ` Anthony Liguori
2010-03-03 19:00 ` [Qemu-devel] [PATCH 01/17] vitio-9p: Add a virtio 9p device to qemu Anthony Liguori
2010-03-03 19:00 ` [Qemu-devel] [PATCH 02/17] vrtio-9p: Implement P9_TVERSION for 9P Anthony Liguori
2010-03-04  9:23   ` [Qemu-devel] " Michael S. Tsirkin
2010-03-04 14:30     ` Aneesh Kumar K. V
2010-03-03 19:01 ` [Qemu-devel] [PATCH 03/17] virtio-9p: Implement P9_TATTACH Anthony Liguori
2010-03-03 19:01 ` [Qemu-devel] [PATCH 04/17] virtio-9p: Implement P9_TSTAT Anthony Liguori
2010-03-03 20:35   ` malc
2010-03-04 14:15     ` Aneesh Kumar K. V
2010-03-09  2:08       ` jvrao
2010-03-09 12:30         ` Paul Brook
2010-03-09 14:35           ` Aneesh Kumar K. V
2010-03-09 15:59           ` jvrao
2010-03-11 16:37             ` Paul Brook
2010-03-03 19:01 ` Anthony Liguori [this message]
2010-03-03 19:01 ` [Qemu-devel] [PATCH 06/17] virtio-9p: Implement P9_TOPEN Anthony Liguori
2010-03-03 19:01 ` [Qemu-devel] [PATCH 07/17] virtio-9p: Implement P9_TREAD Anthony Liguori
2010-03-03 19:01 ` [Qemu-devel] [PATCH 08/17] virtio-9p: Implement P9_TCLUNK Anthony Liguori
2010-03-03 19:01 ` [Qemu-devel] [PATCH 09/17] virtio-9p: Implement P9_TWRITE Anthony Liguori
2010-03-03 19:01 ` [Qemu-devel] [PATCH 10/17] virtio-9p: Implement P9_TCREATE Anthony Liguori
2010-03-03 19:01 ` [Qemu-devel] [PATCH 11/17] virtio-9p: Implement P9_TWSTAT Anthony Liguori
2010-03-03 19:01 ` [Qemu-devel] [PATCH 12/17] virtio-9p: Implement P9_TREMOVE Anthony Liguori
2010-03-03 19:01 ` [Qemu-devel] [PATCH 13/17] virtio-9p: Implement P9_TFLUSH Anthony Liguori
2010-03-03 19:01 ` [Qemu-devel] [PATCH 14/17] virtio-9p: Add multiple mount point support Anthony Liguori
2010-03-03 19:01 ` [Qemu-devel] [PATCH 15/17] virtio-9p: Use little endian format on virtio Anthony Liguori
2010-03-03 19:01 ` [Qemu-devel] [PATCH 16/17] virtio-9p: Add support for hardlink Anthony Liguori
2010-03-03 19:01 ` [Qemu-devel] [PATCH 17/17] Implement sync support in 9p server Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1267642874-15001-7-git-send-email-aliguori@us.ibm.com \
    --to=aliguori@us.ibm.com \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=ego@in.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.