[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH-V3 18/24] virtio-9p: Implement TXATTRWALK
From: |
Venkateswararao Jujjuri (JV) |
Subject: |
[Qemu-devel] [PATCH-V3 18/24] virtio-9p: Implement TXATTRWALK |
Date: |
Thu, 22 Jul 2010 08:58:05 -0700 |
From: Aneesh Kumar K.V <address@hidden>
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 <address@hidden>
Signed-off-by: Venkateswararao Jujjuri <address@hidden>
---
hw/file-op-9p.h | 2 +
hw/virtio-9p-debug.c | 10 +++
hw/virtio-9p-local.c | 14 ++++
hw/virtio-9p.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++-
hw/virtio-9p.h | 14 ++++
5 files changed, 228 insertions(+), 2 deletions(-)
diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h
index 120c803..c4f29e9 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);
+ ssize_t (*lgetxattr)(FsContext *, const char *, const char *, void *,
size_t);
+ ssize_t (*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 949a4bf..4554eb6 100644
--- a/hw/virtio-9p-debug.c
+++ b/hw/virtio-9p-debug.c
@@ -579,6 +579,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 1f72f2e..3088782 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -477,6 +477,18 @@ static int local_statfs(FsContext *s, const char *path,
struct statfs *stbuf)
return statfs(rpath(s, path), stbuf);
}
+static ssize_t local_lgetxattr(FsContext *ctx, const char *path, const char
*name,
+ void *value, size_t size)
+{
+ return lgetxattr(rpath(ctx, path), name, value, size);
+}
+
+static ssize_t 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,
@@ -505,4 +517,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 f3943a0..2782637 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -263,6 +263,21 @@ static int v9fs_do_statfs(V9fsState *s, V9fsString *path,
struct statfs *stbuf)
return s->ops->statfs(&s->ctx, path->data, stbuf);
}
+static ssize_t 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 ssize_t 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;
@@ -1942,6 +1957,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;
@@ -1963,7 +2003,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->max_count = vs->count;
vs->count = 0;
if (vs->off == 0) {
@@ -1971,12 +2011,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->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;
}
@@ -3086,6 +3129,148 @@ out:
qemu_free(vs);
}
+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, ssize_t
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, ssize_t
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[] = {
@@ -3093,6 +3278,7 @@ static pdu_handler_t *pdu_handlers[] = {
[P9_TSTATFS] = v9fs_statfs,
[P9_TGETATTR] = v9fs_getattr,
[P9_TSETATTR] = v9fs_setattr,
+ [P9_TXATTRWALK] = v9fs_xattrwalk,
[P9_TMKNOD] = v9fs_mknod,
[P9_TRENAME] = v9fs_rename,
[P9_TMKDIR] = v9fs_mkdir,
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 3edbdaa..e7a8ea5 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -29,6 +29,8 @@ enum {
P9_RGETATTR,
P9_TSETATTR = 26,
P9_RSETATTR,
+ P9_TXATTRWALK = 30,
+ P9_RXATTRWALK,
P9_TREADDIR = 40,
P9_RREADDIR,
P9_TLINK = 70,
@@ -416,6 +418,18 @@ typedef struct V9fsRenameState {
V9fsString name;
} V9fsRenameState;
+typedef struct V9fsXattrState
+{
+ V9fsPDU *pdu;
+ size_t offset;
+ V9fsFidState *file_fidp;
+ V9fsFidState *xattr_fidp;
+ V9fsString name;
+ int64_t size;
+ int flags;
+ void *value;
+} V9fsXattrState;
+
extern size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
size_t offset, size_t size, int pack);
--
1.6.5.2
- [Qemu-devel] [PATCH-V3 02/24] qemu: virtio-9p: Implement statfs support in server, (continued)
- [Qemu-devel] [PATCH-V3 02/24] qemu: virtio-9p: Implement statfs support in server, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 01/24] qemu: virtio-9p: Recognize 9P2000.L protocol, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 17/24] virtio-9p: Add fidtype so that we can do type specific operation, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 14/24] qemu: virtio-9p: Implement TMKDIR, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 11/24] [virtio-9p] Define and implement TSYMLINK for 9P2000.L, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 12/24] [virtio-9p] This patch implements TLCREATE for 9p2000.L protocol., Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 21/24] virtio-9p: Add SM_NONE security model, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 05/24] virtio-9p: Compute iounit based on host filesystem block size, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 24/24] virtio-9p: Fix formatting issues in v9fs_wstat_post_chown(), Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 08/24] [virtio-9p] Make v9fs_do_utimensat accept timespec structures instead of v9stat., Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 18/24] virtio-9p: Implement TXATTRWALK,
Venkateswararao Jujjuri (JV) <=
- [Qemu-devel] [PATCH-V3 13/24] qemu: virtio-9p: Implement TMKNOD, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 15/24] rename - change name of file or directory, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 16/24] qemu: virtio-9p: Implement LOPEN, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 19/24] virtio-9p: Implement TXATTRCREATE, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 23/24] virtio-9p: Fix the memset usage, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 22/24] virtio-9p: Use lchown which won't follow symlink, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 20/24] virtio-9p: Hide user.virtfs xattr in case of mapped security., Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 03/24] virtio-9p: Return correct error from v9fs_remove, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 07/24] virtio-9p: Do not reset atime, Venkateswararao Jujjuri (JV), 2010/07/22
- [Qemu-devel] [PATCH-V3 06/24] virtio-9p: getattr server implementation for 9P2000.L protocol., Venkateswararao Jujjuri (JV), 2010/07/22