[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 19/20] virtio-9p: Implement TXATTRCREATE
From: |
Venkateswararao Jujjuri (JV) |
Subject: |
[Qemu-devel] [PATCH 19/20] virtio-9p: Implement TXATTRCREATE |
Date: |
Mon, 28 Jun 2010 14:55:16 -0700 |
From: Aneesh Kumar K.V <address@hidden>
TXATTRCREATE: Prepare a fid for setting xattr value on a file system object.
size[4] TXATTRCREATE tag[2] fid[4] name[s] attr_size[8] flags[4]
size[4] RXATTRWALK tag[2]
txattrcreate gets a fid pointing to xattr. This fid can later be
used to get set the xattr value.
flag value is derived from set Linux setxattr. The manpage says
"The flags parameter can be used to refine the semantics of the operation.
XATTR_CREATE specifies a pure create, which fails if the named attribute
exists already. XATTR_REPLACE specifies a pure replace operation, which
fails if the named attribute does not already exist. By default (no flags),
the extended attribute will be created if need be, or will simply replace
the value if the attribute exists."
The actual setxattr operation happens when the fid is clunked. At that point
the written byte count and the attr_size specified in TXATTRCREATE should be
same otherwise an error will be returned.
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 | 9 +++
hw/virtio-9p-local.c | 7 +++
hw/virtio-9p.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++---
hw/virtio-9p.h | 2 +
5 files changed, 154 insertions(+), 9 deletions(-)
diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h
index 8f466b4..2563f7b 100644
--- a/hw/file-op-9p.h
+++ b/hw/file-op-9p.h
@@ -78,6 +78,8 @@ typedef struct FileOperations
ssize_t (*lgetxattr)(FsContext *, const char *, const char *, void *,
size_t);
ssize_t (*llistxattr)(FsContext *, const char *, void *, size_t);
+ int (*lsetxattr)(FsContext *, const char *, const char *, void *, size_t,
+ int);
void *opaque;
} FileOperations;
#endif
diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c
index 47d565a..70f2aec 100644
--- a/hw/virtio-9p-debug.c
+++ b/hw/virtio-9p-debug.c
@@ -586,6 +586,15 @@ void pprint_pdu(V9fsPDU *pdu)
case P9_RXATTRWALK:
fprintf(llogfile, "RXATTRWALK: (");
pprint_int64(pdu, 1, &offset, "xattrsize");
+ case P9_TXATTRCREATE:
+ fprintf(llogfile, "TXATTRCREATE: (");
+ pprint_int32(pdu, 0, &offset, "fid");
+ pprint_str(pdu, 0, &offset, ", name");
+ pprint_int64(pdu, 0, &offset, ", xattrsize");
+ pprint_int32(pdu, 0, &offset, ", flags");
+ break;
+ case P9_RXATTRCREATE:
+ fprintf(llogfile, "RXATTRCREATE: (");
break;
default:
fprintf(llogfile, "unknown(%d): (", pdu->id);
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
index 5a3f5b8..3944cf3 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -489,6 +489,12 @@ static ssize_t local_llistxattr(FsContext *ctx, const char
*path,
return llistxattr(rpath(ctx, path), value, size);
}
+static int local_lsetxattr(FsContext *ctx, const char *path, const char *name,
+ void *value, size_t size, int flags)
+{
+ return lsetxattr(rpath(ctx, path), name, value, size, flags);
+}
+
FileOperations local_ops = {
.lstat = local_lstat,
.readlink = local_readlink,
@@ -519,4 +525,5 @@ FileOperations local_ops = {
.statfs = local_statfs,
.lgetxattr = local_lgetxattr,
.llistxattr = local_llistxattr,
+ .lsetxattr = local_lsetxattr,
};
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index ad383f9..f7ca0f6 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -278,6 +278,14 @@ static ssize_t v9fs_do_llistxattr(V9fsState *s, V9fsString
*path,
value, size);
}
+static int v9fs_do_lsetxattr(V9fsState *s, V9fsString *path,
+ V9fsString *xattr_name,
+ void *value, size_t size, int flags)
+{
+ return s->ops->lsetxattr(&s->ctx, path->data,
+ xattr_name->data, value, size, flags);
+}
+
static void v9fs_string_init(V9fsString *str)
{
str->data = NULL;
@@ -431,8 +439,39 @@ static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid)
return f;
}
+static int v9fs_xattr_fid_clunk(V9fsState *s, V9fsFidState *fidp)
+{
+ int retval = 0;
+
+ if (fidp->fs.xattr.copied_len == -1) {
+ /* getxattr/listxattr fid */
+ goto free_value;
+ }
+ /*
+ * if this is fid for setxattr. clunk should
+ * result in setxattr localcall
+ */
+ if (fidp->fs.xattr.len != fidp->fs.xattr.copied_len) {
+ /* clunk after partial write */
+ retval = -EINVAL;
+ goto free_out;
+ }
+ retval = v9fs_do_lsetxattr(s, &fidp->path, &fidp->fs.xattr.name,
+ fidp->fs.xattr.value,
+ fidp->fs.xattr.len,
+ fidp->fs.xattr.flags);
+free_out:
+ v9fs_string_free(&fidp->fs.xattr.name);
+free_value:
+ if (fidp->fs.xattr.value) {
+ qemu_free(fidp->fs.xattr.value);
+ }
+ return retval;
+}
+
static int free_fid(V9fsState *s, int32_t fid)
{
+ int retval = 0;
V9fsFidState **fidpp, *fidp;
for (fidpp = &s->fid_list; *fidpp; fidpp = &(*fidpp)->next) {
@@ -459,14 +498,12 @@ static int free_fid(V9fsState *s, int32_t fid)
}
}
if (fidp->fid_type == P9_FID_XATTR) {
- if (fidp->fs.xattr.value) {
- qemu_free(fidp->fs.xattr.value);
- }
+ retval = v9fs_xattr_fid_clunk(s, fidp);
}
v9fs_string_free(&fidp->path);
qemu_free(fidp);
- return 0;
+ return retval;
}
#define P9_QID_TYPE_DIR 0x80
@@ -2181,6 +2218,48 @@ out:
qemu_free(vs);
}
+static void v9fs_xattr_write(V9fsState *s, V9fsWriteState *vs)
+{
+ int i, to_copy;
+ ssize_t err = 0;
+ int write_count;
+ int64_t xattr_len;
+
+ xattr_len = vs->fidp->fs.xattr.len;
+ write_count = xattr_len - vs->off;
+ if (write_count > vs->count) {
+ write_count = vs->count;
+ } else if (write_count < 0) {
+ /*
+ * write beyond XATTR value len specified in
+ * xattrcreate
+ */
+ err = -ENOSPC;
+ goto out;
+ }
+ vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", write_count);
+ err = vs->offset;
+ vs->fidp->fs.xattr.copied_len += write_count;
+ /*
+ * Now copy the content from sg list
+ */
+ for (i = 0; i < vs->cnt; i++) {
+ if (write_count > vs->sg[i].iov_len) {
+ to_copy = vs->sg[i].iov_len;
+ } else {
+ to_copy = write_count;
+ }
+ memcpy((char *)vs->fidp->fs.xattr.value + vs->off,
+ vs->sg[i].iov_base, to_copy);
+ /* updating vs->off since we are not using below */
+ vs->off += to_copy;
+ write_count -= to_copy;
+ }
+out:
+ complete_pdu(s, vs->pdu, err);
+ qemu_free(vs);
+}
+
static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
{
int32_t fid;
@@ -2196,7 +2275,7 @@ static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
vs->len = 0;
pdu_unmarshal(vs->pdu, vs->offset, "dqdv", &fid, &vs->off, &vs->count,
- vs->sg, &vs->cnt);
+ vs->sg, &vs->cnt);
vs->fidp = lookup_fid(s, fid);
if (vs->fidp == NULL) {
@@ -2204,11 +2283,21 @@ static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
goto out;
}
- if (vs->fidp->fs.fd == -1) {
- err = -EINVAL;
- goto out;
+ if (vs->fidp->fid_type == P9_FID_FILE) {
+ if (vs->fidp->fs.fd == -1) {
+ err = -EINVAL;
+ goto out;
+ }
+ } else if (vs->fidp->fid_type == P9_FID_XATTR) {
+ /*
+ * setxattr operation
+ */
+ v9fs_xattr_write(s, vs);
+ return;
+ } else {
+ err = -EINVAL;
+ goto out;
}
-
err = v9fs_do_lseek(s, vs->fidp->fs.fd, vs->off, SEEK_SET);
v9fs_write_post_lseek(s, vs, err);
@@ -3247,6 +3336,41 @@ out:
qemu_free(vs);
}
+static void v9fs_xattrcreate(V9fsState *s, V9fsPDU *pdu)
+{
+ int flags;
+ int32_t fid;
+ ssize_t err = 0;
+ V9fsXattrState *vs;
+
+ vs = qemu_malloc(sizeof(*vs));
+ vs->pdu = pdu;
+ vs->offset = 7;
+
+ pdu_unmarshal(vs->pdu, vs->offset, "dsqd",
+ &fid, &vs->name, &vs->size, &flags);
+
+ vs->file_fidp = lookup_fid(s, fid);
+ if (vs->file_fidp == NULL) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ /* Make the file fid point to xattr */
+ vs->xattr_fidp = vs->file_fidp;
+ vs->xattr_fidp->fid_type = P9_FID_XATTR;
+ vs->xattr_fidp->fs.xattr.copied_len = 0;
+ vs->xattr_fidp->fs.xattr.len = vs->size;
+ vs->xattr_fidp->fs.xattr.flags = flags;
+ v9fs_string_init(&vs->xattr_fidp->fs.xattr.name);
+ v9fs_string_copy(&vs->xattr_fidp->fs.xattr.name, &vs->name);
+ vs->xattr_fidp->fs.xattr.value = qemu_malloc(vs->size);
+
+out:
+ complete_pdu(s, vs->pdu, err);
+ v9fs_string_free(&vs->name);
+ qemu_free(vs);
+}
typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU *pdu);
@@ -3256,6 +3380,7 @@ static pdu_handler_t *pdu_handlers[] = {
[P9_TGETATTR] = v9fs_getattr,
[P9_TSETATTR] = v9fs_setattr,
[P9_TXATTRWALK] = v9fs_xattrwalk,
+ [P9_TXATTRCREATE] = v9fs_xattrcreate,
[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 d4e3abd..00734cb 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -31,6 +31,8 @@ enum {
P9_RSETATTR,
P9_TXATTRWALK = 30,
P9_RXATTRWALK,
+ P9_TXATTRCREATE = 32,
+ P9_RXATTRCREATE,
P9_TREADDIR = 40,
P9_RREADDIR,
P9_TLINK = 70,
--
1.6.5.2
- [Qemu-devel] [PATCH 07/20] virtio-9p: Do not reset atime, (continued)
- [Qemu-devel] [PATCH 07/20] virtio-9p: Do not reset atime, Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 04/20] [V4] virtio-9p: readdir implementation for 9p2000.L, Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 09/20] virtio-9p: Implement server side of setattr for 9P2000.L protocol., Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 12/20] [virtio-9p] This patch implements TLCREATE for 9p2000.L protocol., Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 05/20] virtio-9p: Compute iounit based on host filesystem block size, Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 18/20] virtio-9p: Implement TXATTRWALK, Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 10/20] [virtio-9p] Implement TLINK for 9P2000.L, Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 06/20] virtio-9p: getattr server implementation for 9P2000.L protocol., Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 17/20] virtio-9p: Add fidtype so that we can do type specific operation, Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 03/20] virtio-9p: Return correct error from v9fs_remove, Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 19/20] virtio-9p: Implement TXATTRCREATE,
Venkateswararao Jujjuri (JV) <=
- [Qemu-devel] [PATCH 16/20] qemu: virtio-9p: Implement LOPEN, Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 02/20] qemu: virtio-9p: Implement statfs support in server, Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 11/20] [virtio-9p] Define and implement TSYMLINK for 9P2000.L, Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 13/20] qemu: virtio-9p: Implement TMKNOD, Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 08/20] [virtio-9p] Make v9fs_do_utimensat accept timespec structures instead of v9stat., Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 20/20] virtio-9p: Hide user.virtfs xattr in case of mapped security., Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 14/20] qemu: virtio-9p: Implement TMKDIR, Venkateswararao Jujjuri (JV), 2010/06/28
- [Qemu-devel] [PATCH 15/20] rename - change name of file or directory, Venkateswararao Jujjuri (JV), 2010/06/28