Patchwork qemu-virtio-9p: Implement TREADLINK operation for 9p2000.L

login
register
mail settings
Submitter Mohan Kumar M
Date Sept. 21, 2010, 2:10 p.m.
Message ID <1285078220-25523-1-git-send-email-mohan@in.ibm.com>
Download mbox | patch
Permalink /patch/65310/
State New
Headers show

Comments

Mohan Kumar M - Sept. 21, 2010, 2:10 p.m.
Synopsis

        size[4] TReadlink tag[2] fid[4]
        size[4] RReadlink tag[2] target[s]

Description
        Readlink is used to return the contents of the symoblic link
        referred by fid. Contents of symboic link is returned as a
        response.

        target[s] - Contents of the symbolic link referred by fid.

Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 hw/virtio-9p-debug.c |    8 ++++++++
 hw/virtio-9p.c       |   44 ++++++++++++++++++++++++++++++++++++++++++++
 hw/virtio-9p.h       |    9 +++++++++
 3 files changed, 61 insertions(+), 0 deletions(-)

Patch

diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c
index 6f6a0ec..cfaae6b 100644
--- a/hw/virtio-9p-debug.c
+++ b/hw/virtio-9p-debug.c
@@ -502,6 +502,14 @@  void pprint_pdu(V9fsPDU *pdu)
         fprintf(llogfile, "RMKNOD: )");
         pprint_qid(pdu, 0, &offset, "qid");
         break;
+    case P9_TREADLINK:
+	fprintf(llogfile, "TREADLINK: (");
+        pprint_int32(pdu, 0, &offset, "fid");
+        break;
+    case P9_RREADLINK:
+	fprintf(llogfile, "RREADLINK: (");
+        pprint_str(pdu, 0, &offset, "target");
+        break;
     case P9_TREAD:
         fprintf(llogfile, "TREAD: (");
         pprint_int32(pdu, 0, &offset, "fid");
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index fd2147e..5d1fbee 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -3403,6 +3403,49 @@  out:
     qemu_free(vs);
 }
 
+static void v9fs_readlink_post_readlink(V9fsState *s, V9fsReadLinkState *vs,
+                                                    int err)
+{
+    if (err < 0) {
+        err = -errno;
+        goto out;
+    }
+    vs->offset += pdu_marshal(vs->pdu, vs->offset, "s", &vs->target);
+    err = vs->offset;
+out:
+    complete_pdu(s, vs->pdu, err);
+    v9fs_string_free(&vs->target);
+    qemu_free(vs);
+}
+
+static void v9fs_readlink(V9fsState *s, V9fsPDU *pdu)
+{
+    int32_t fid;
+    V9fsReadLinkState *vs;
+    int err = 0;
+    V9fsFidState *fidp;
+
+    vs = qemu_malloc(sizeof(*vs));
+    vs->pdu = pdu;
+    vs->offset = 7;
+
+    pdu_unmarshal(vs->pdu, vs->offset, "d", &fid);
+
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
+        err = -ENOENT;
+        goto out;
+    }
+
+    v9fs_string_init(&vs->target);
+    err = v9fs_do_readlink(s, &fidp->path, &vs->target);
+    v9fs_readlink_post_readlink(s, vs, err);
+    return;
+out:
+    complete_pdu(s, vs->pdu, err);
+    qemu_free(vs);
+}
+
 typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU *pdu);
 
 static pdu_handler_t *pdu_handlers[] = {
@@ -3414,6 +3457,7 @@  static pdu_handler_t *pdu_handlers[] = {
     [P9_TXATTRCREATE] = v9fs_xattrcreate,
     [P9_TMKNOD] = v9fs_mknod,
     [P9_TRENAME] = v9fs_rename,
+    [P9_TREADLINK] = v9fs_readlink,
     [P9_TMKDIR] = v9fs_mkdir,
     [P9_TVERSION] = v9fs_version,
     [P9_TLOPEN] = v9fs_open,
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 0816ad6..bbc23d5 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -27,6 +27,8 @@  enum {
     P9_RMKNOD,
     P9_TRENAME = 20,
     P9_RRENAME,
+    P9_TREADLINK = 22,
+    P9_RREADLINK,
     P9_TGETATTR = 24,
     P9_RGETATTR,
     P9_TSETATTR = 26,
@@ -434,6 +436,13 @@  typedef struct V9fsXattrState
     void *value;
 } V9fsXattrState;
 
+typedef struct V9fsReadLinkState
+{
+    V9fsPDU *pdu;
+    size_t offset;
+    V9fsString target;
+} V9fsReadLinkState;
+
 extern size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
                             size_t offset, size_t size, int pack);