All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: ericvh@gmail.com, v9fs-developer@lists.sourceforge.net,
	aliguori@us.ibm.com,
	"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Subject: [Qemu-devel] [PATCH 2/4] virtio-9p: Implement TXATTRWALK
Date: Tue,  1 Jun 2010 14:58:47 +0530	[thread overview]
Message-ID: <1275384529-28757-2-git-send-email-aneesh.kumar@linux.vnet.ibm.com> (raw)
In-Reply-To: <1275384529-28757-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com>

TXATTRWALK: Descend a ATTR namespace

 size[4] TXATTRWALK tag[2] fid[4] newfid[4] name[s]
 size [4] RXATTRWALK tag[2] size[8]

txattrwalk gets a fid pointing to xattr. This fid can later be
used to get read the xattr value. If name is NULL the fid returned
can be used to get the list of extended attribute associated to
the file system object.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 hw/file-op-9p.h      |    2 +
 hw/virtio-9p-debug.c |   10 +++
 hw/virtio-9p-local.c |   14 ++++
 hw/virtio-9p.c       |  202 +++++++++++++++++++++++++++++++++++++++++++++++++-
 hw/virtio-9p.h       |    2 +
 5 files changed, 228 insertions(+), 2 deletions(-)

diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h
index 120c803..d5bab9a 100644
--- a/hw/file-op-9p.h
+++ b/hw/file-op-9p.h
@@ -75,6 +75,8 @@ typedef struct FileOperations
     int (*truncate)(FsContext *, const char *, off_t);
     int (*fsync)(FsContext *, int);
     int (*statfs)(FsContext *s, const char *path, struct statfs *stbuf);
+    int (*lgetxattr)(FsContext *, const char *, const char *, void *, size_t);
+    int (*llistxattr)(FsContext *, const char *, void *, size_t);
     void *opaque;
 } FileOperations;
 #endif
diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c
index 7325418..5be1670 100644
--- a/hw/virtio-9p-debug.c
+++ b/hw/virtio-9p-debug.c
@@ -540,6 +540,16 @@ void pprint_pdu(V9fsPDU *pdu)
     case P9_RWSTAT:
         fprintf(llogfile, "RWSTAT: (");
         break;
+    case P9_TXATTRWALK:
+        fprintf(llogfile, "TXATTRWALK: (");
+        pprint_int32(pdu, 0, &offset, "fid");
+        pprint_int32(pdu, 0, &offset, ", newfid");
+        pprint_str(pdu, 0, &offset, ", xattr name");
+        break;
+    case P9_RXATTRWALK:
+        fprintf(llogfile, "RXATTRWALK: (");
+        pprint_int64(pdu, 1, &offset, "xattrsize");
+        break;
     default:
         fprintf(llogfile, "unknown(%d): (", pdu->id);
         break;
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
index dd60354..97b1544 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -472,6 +472,18 @@ static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf)
    return statfs(rpath(s, path), stbuf);
 }
 
+static int local_lgetxattr(FsContext *ctx, const char *path, const char *name,
+                           void *value, size_t size)
+{
+    return lgetxattr(rpath(ctx, path), name, value, size);
+}
+
+static int local_llistxattr(FsContext *ctx, const char *path,
+                            void *value, size_t size)
+{
+    return llistxattr(rpath(ctx, path), value, size);
+}
+
 FileOperations local_ops = {
     .lstat = local_lstat,
     .readlink = local_readlink,
@@ -500,4 +512,6 @@ FileOperations local_ops = {
     .remove = local_remove,
     .fsync = local_fsync,
     .statfs = local_statfs,
+    .lgetxattr = local_lgetxattr,
+    .llistxattr = local_llistxattr,
 };
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 2558e0e..de2ec41 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -270,6 +270,21 @@ static int v9fs_do_fsync(V9fsState *s, int fd)
     return s->ops->fsync(&s->ctx, fd);
 }
 
+static int v9fs_do_lgetxattr(V9fsState *s, V9fsString *path,
+                             V9fsString *xattr_name,
+                             void *value, size_t size)
+{
+    return s->ops->lgetxattr(&s->ctx, path->data,
+                             xattr_name->data, value, size);
+}
+
+static int v9fs_do_llistxattr(V9fsState *s, V9fsString *path,
+                              void *value, size_t size)
+{
+    return s->ops->llistxattr(&s->ctx, path->data,
+                              value, size);
+}
+
 static void v9fs_string_init(V9fsString *str)
 {
     str->data = NULL;
@@ -1640,6 +1655,31 @@ out:
     qemu_free(vs);
 }
 
+static void v9fs_xattr_read(V9fsState *s, V9fsReadState *vs)
+{
+    ssize_t err = 0;
+    int read_count;
+    int64_t xattr_len;
+
+    xattr_len = vs->fidp->fs.xattr.len;
+    read_count = xattr_len - vs->off;
+    if (read_count > vs->count) {
+	read_count = vs->count;
+    } else if (read_count < 0) {
+	/*
+	 * read beyond XATTR value
+	 */
+	read_count = 0;
+    }
+    vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", read_count);
+    vs->offset += pdu_pack(vs->pdu, vs->offset,
+			   ((char *)vs->fidp->fs.xattr.value) + vs->off,
+			   read_count);
+    err = vs->offset;
+    complete_pdu(s, vs->pdu, err);
+    qemu_free(vs);
+}
+
 static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
 {
     int32_t fid;
@@ -1661,7 +1701,7 @@ static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
         goto out;
     }
 
-    if (vs->fidp->fs.dir) {
+    if (vs->fidp->fid_type == P9_FID_DIR && vs->fidp->fs.dir) {
         vs->max_count = vs->count;
         vs->count = 0;
         if (vs->off == 0) {
@@ -1669,12 +1709,15 @@ static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
         }
         v9fs_read_post_rewinddir(s, vs, err);
         return;
-    } else if (vs->fidp->fs.fd != -1) {
+    } else if (vs->fidp->fid_type == P9_FID_FILE && vs->fidp->fs.fd != -1) {
         vs->sg = vs->iov;
         pdu_marshal(vs->pdu, vs->offset + 4, "v", vs->sg, &vs->cnt);
         err = v9fs_do_lseek(s, vs->fidp->fs.fd, vs->off, SEEK_SET);
         v9fs_read_post_lseek(s, vs, err);
         return;
+    } else if (vs->fidp->fid_type == P9_FID_XATTR) {
+	v9fs_xattr_read(s, vs);
+	return;
     } else {
         err = -EINVAL;
     }
@@ -2513,6 +2556,160 @@ out:
     qemu_free(vs);
 }
 
+typedef struct V9fsXattrState
+{
+    V9fsPDU *pdu;
+    size_t offset;
+    V9fsFidState *file_fidp;
+    V9fsFidState *xattr_fidp;
+    V9fsString name;
+    int64_t size;
+    int flags;
+    void *value;
+} V9fsXattrState;
+
+static void v9fs_post_xattr_getvalue(V9fsState *s, V9fsXattrState *vs, int err)
+{
+
+    if (err < 0) {
+        err = -errno;
+        free_fid(s, vs->xattr_fidp->fid);
+        goto out;
+    }
+    vs->offset += pdu_marshal(vs->pdu, vs->offset, "q", vs->size);
+    err = vs->offset;
+out:
+    complete_pdu(s, vs->pdu, err);
+    v9fs_string_free(&vs->name);
+    qemu_free(vs);
+    return;
+}
+
+static void v9fs_post_xattr_check(V9fsState *s, V9fsXattrState *vs, int err)
+{
+    if (err < 0) {
+        err = -errno;
+        free_fid(s, vs->xattr_fidp->fid);
+        goto out;
+    }
+    /*
+     * Read the xattr value
+     */
+    vs->xattr_fidp->fs.xattr.len = vs->size;
+    vs->xattr_fidp->fid_type = P9_FID_XATTR;
+    vs->xattr_fidp->fs.xattr.copied_len = -1;
+    if (vs->size) {
+        vs->xattr_fidp->fs.xattr.value = qemu_malloc(vs->size);
+        err = v9fs_do_lgetxattr(s, &vs->xattr_fidp->path,
+                                &vs->name, vs->xattr_fidp->fs.xattr.value,
+                                vs->xattr_fidp->fs.xattr.len);
+    }
+    v9fs_post_xattr_getvalue(s, vs, err);
+    return;
+out:
+    complete_pdu(s, vs->pdu, err);
+    v9fs_string_free(&vs->name);
+    qemu_free(vs);
+}
+
+static void v9fs_post_lxattr_getvalue(V9fsState *s, V9fsXattrState *vs, int err)
+{
+    if (err < 0) {
+        err = -errno;
+        free_fid(s, vs->xattr_fidp->fid);
+        goto out;
+    }
+    vs->offset += pdu_marshal(vs->pdu, vs->offset, "q", vs->size);
+    err = vs->offset;
+out:
+    complete_pdu(s, vs->pdu, err);
+    v9fs_string_free(&vs->name);
+    qemu_free(vs);
+    return;
+}
+
+static void v9fs_post_lxattr_check(V9fsState *s, V9fsXattrState *vs, int err)
+{
+    if (err < 0) {
+        err = -errno;
+        free_fid(s, vs->xattr_fidp->fid);
+        goto out;
+    }
+    /*
+     * Read the xattr value
+     */
+    vs->xattr_fidp->fs.xattr.len = vs->size;
+    vs->xattr_fidp->fid_type = P9_FID_XATTR;
+    vs->xattr_fidp->fs.xattr.copied_len = -1;
+    if (vs->size) {
+        vs->xattr_fidp->fs.xattr.value = qemu_malloc(vs->size);
+        err = v9fs_do_llistxattr(s, &vs->xattr_fidp->path,
+                                 vs->xattr_fidp->fs.xattr.value,
+                                 vs->xattr_fidp->fs.xattr.len);
+    }
+    v9fs_post_lxattr_getvalue(s, vs, err);
+    return;
+out:
+    complete_pdu(s, vs->pdu, err);
+    v9fs_string_free(&vs->name);
+    qemu_free(vs);
+}
+
+static void v9fs_xattrwalk(V9fsState *s, V9fsPDU *pdu)
+{
+    ssize_t err = 0;
+    V9fsXattrState *vs;
+    int32_t fid, newfid;
+
+    vs = qemu_malloc(sizeof(*vs));
+    vs->pdu = pdu;
+    vs->offset = 7;
+
+    pdu_unmarshal(vs->pdu, vs->offset, "dds", &fid, &newfid, &vs->name);
+    vs->file_fidp = lookup_fid(s, fid);
+    if (vs->file_fidp == NULL) {
+        err = -ENOENT;
+        goto out;
+    }
+
+    vs->xattr_fidp = alloc_fid(s, newfid);
+    if (vs->xattr_fidp == NULL) {
+	err = -EINVAL;
+	goto out;
+    }
+
+    v9fs_string_copy(&vs->xattr_fidp->path, &vs->file_fidp->path);
+    if (vs->name.data[0] == 0) {
+	/*
+	 * listxattr request. Get the size first
+	 */
+	vs->size = v9fs_do_llistxattr(s, &vs->xattr_fidp->path,
+				      NULL, 0);
+	if (vs->size < 0) {
+	    err = vs->size;
+	}
+	v9fs_post_lxattr_check(s, vs, err);
+	return;
+    } else {
+	/*
+	 * specific xattr fid. We check for xattr
+	 * presence also collect the xattr size
+	 */
+	vs->size = v9fs_do_lgetxattr(s, &vs->xattr_fidp->path,
+				     &vs->name, NULL, 0);
+	if (vs->size < 0) {
+	    err = vs->size;
+	}
+	v9fs_post_xattr_check(s, vs, err);
+	return;
+    }
+out:
+    complete_pdu(s, vs->pdu, err);
+    v9fs_string_free(&vs->name);
+    qemu_free(vs);
+}
+
+
 typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU *pdu);
 
 static pdu_handler_t *pdu_handlers[] = {
@@ -2520,6 +2717,7 @@ static pdu_handler_t *pdu_handlers[] = {
     [P9_TSTATFS] = v9fs_statfs,
     [P9_TGETATTR] = v9fs_getattr,
     [P9_TSYMLINK] = v9fs_symlink,
+    [P9_TXATTRWALK] = v9fs_xattrwalk,
     [P9_TVERSION] = v9fs_version,
     [P9_TATTACH] = v9fs_attach,
     [P9_TSTAT] = v9fs_stat,
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 942e448..c534923 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -19,6 +19,8 @@ enum {
     P9_RSYMLINK,
     P9_TGETATTR = 24,
     P9_RGETATTR,
+    P9_TXATTRWALK = 30,
+    P9_RXATTRWALK,
     P9_TREADDIR = 40,
     P9_RREADDIR,
     P9_TLINK = 70,
-- 
1.7.1.236.g81fa0

  reply	other threads:[~2010-06-01  9:29 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-01  9:28 [Qemu-devel] [PATCH 1/4] virtio-9p: Add fidtype so that we can do type specific operation Aneesh Kumar K.V
2010-06-01  9:28 ` Aneesh Kumar K.V [this message]
2010-06-01  9:28 ` [Qemu-devel] [PATCH 3/4] virtio-9p: Implement TXATTRCREATE Aneesh Kumar K.V
2010-06-01  9:28 ` [Qemu-devel] [PATCH 4/4] virtio-9p: Hide user.virtfs xattr in case of mapped security Aneesh Kumar K.V

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=1275384529-28757-2-git-send-email-aneesh.kumar@linux.vnet.ibm.com \
    --to=aneesh.kumar@linux.vnet.ibm.com \
    --cc=aliguori@us.ibm.com \
    --cc=ericvh@gmail.com \
    --cc=qemu-devel@nongnu.org \
    --cc=v9fs-developer@lists.sourceforge.net \
    /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.