* [Qemu-devel] [PATCH 1/4] virtio-9p: Add fidtype so that we can do type specific operation
@ 2010-06-01 9:28 Aneesh Kumar K.V
2010-06-01 9:28 ` [Qemu-devel] [PATCH 2/4] virtio-9p: Implement TXATTRWALK Aneesh Kumar K.V
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Aneesh Kumar K.V @ 2010-06-01 9:28 UTC (permalink / raw)
To: qemu-devel; +Cc: ericvh, v9fs-developer, aliguori, Aneesh Kumar K.V
We want to add type specific operation during read/write
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
hw/virtio-9p.c | 99 +++++++++++++++++++++++++++++++-------------------------
hw/virtio-9p.h | 24 ++++++++++++-
2 files changed, 77 insertions(+), 46 deletions(-)
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 1c7a428..2558e0e 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -415,8 +415,7 @@ static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid)
f = qemu_mallocz(sizeof(V9fsFidState));
f->fid = fid;
- f->fd = -1;
- f->dir = NULL;
+ f->fid_type = P9_FID_NONE;
f->next = s->fid_list;
s->fid_list = f;
@@ -441,11 +440,20 @@ static int free_fid(V9fsState *s, int32_t fid)
fidp = *fidpp;
*fidpp = fidp->next;
- if (fidp->fd != -1) {
- v9fs_do_close(s, fidp->fd);
+ if (fidp->fid_type == P9_FID_FILE) {
+ if (fidp->fs.fd != -1) {
+ v9fs_do_close(s, fidp->fs.fd);
+ }
+ }
+ if (fidp->fid_type == P9_FID_DIR) {
+ if (fidp->fs.dir) {
+ v9fs_do_closedir(s, fidp->fs.dir);
+ }
}
- if (fidp->dir) {
- v9fs_do_closedir(s, fidp->dir);
+ if (fidp->fid_type == P9_FID_XATTR) {
+ if (fidp->fs.xattr.value) {
+ qemu_free(fidp->fs.xattr.value);
+ }
}
v9fs_string_free(&fidp->path);
qemu_free(fidp);
@@ -1343,8 +1351,7 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
/* FIXME: is this really valid? */
if (fid == newfid) {
- BUG_ON(vs->fidp->fd != -1);
- BUG_ON(vs->fidp->dir);
+ BUG_ON(vs->fidp->fid_type != P9_FID_NONE);
v9fs_string_init(&vs->path);
vs->name_idx = 0;
@@ -1388,11 +1395,12 @@ out:
static void v9fs_open_post_opendir(V9fsState *s, V9fsOpenState *vs, int err)
{
- if (vs->fidp->dir == NULL) {
+ if (vs->fidp->fs.dir == NULL) {
err = -errno;
goto out;
}
+ vs->fidp->fid_type = P9_FID_DIR;
vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, 0);
err = vs->offset;
out:
@@ -1403,11 +1411,12 @@ out:
static void v9fs_open_post_open(V9fsState *s, V9fsOpenState *vs, int err)
{
- if (vs->fidp->fd == -1) {
+ if (vs->fidp->fs.fd == -1) {
err = -errno;
goto out;
}
+ vs->fidp->fid_type = P9_FID_FILE;
vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, 0);
err = vs->offset;
out:
@@ -1425,10 +1434,10 @@ static void v9fs_open_post_lstat(V9fsState *s, V9fsOpenState *vs, int err)
stat_to_qid(&vs->stbuf, &vs->qid);
if (S_ISDIR(vs->stbuf.st_mode)) {
- vs->fidp->dir = v9fs_do_opendir(s, &vs->fidp->path);
+ vs->fidp->fs.dir = v9fs_do_opendir(s, &vs->fidp->path);
v9fs_open_post_opendir(s, vs, err);
} else {
- vs->fidp->fd = v9fs_do_open(s, &vs->fidp->path,
+ vs->fidp->fs.fd = v9fs_do_open(s, &vs->fidp->path,
omode_to_uflags(vs->mode));
v9fs_open_post_open(s, vs, err);
}
@@ -1457,8 +1466,7 @@ static void v9fs_open(V9fsState *s, V9fsPDU *pdu)
goto out;
}
- BUG_ON(vs->fidp->fd != -1);
- BUG_ON(vs->fidp->dir);
+ BUG_ON(vs->fidp->fid_type != P9_FID_NONE);
err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
@@ -1522,7 +1530,7 @@ static void v9fs_read_post_dir_lstat(V9fsState *s, V9fsReadState *vs,
&vs->v9stat);
if ((vs->len != (vs->v9stat.size + 2)) ||
((vs->count + vs->len) > vs->max_count)) {
- v9fs_do_seekdir(s, vs->fidp->dir, vs->dir_pos);
+ v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->dir_pos);
v9fs_read_post_seekdir(s, vs, err);
return;
}
@@ -1530,11 +1538,11 @@ static void v9fs_read_post_dir_lstat(V9fsState *s, V9fsReadState *vs,
v9fs_stat_free(&vs->v9stat);
v9fs_string_free(&vs->name);
vs->dir_pos = vs->dent->d_off;
- vs->dent = v9fs_do_readdir(s, vs->fidp->dir);
+ vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir);
v9fs_read_post_readdir(s, vs, err);
return;
out:
- v9fs_do_seekdir(s, vs->fidp->dir, vs->dir_pos);
+ v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->dir_pos);
v9fs_read_post_seekdir(s, vs, err);
return;
@@ -1562,7 +1570,7 @@ static void v9fs_read_post_readdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
static void v9fs_read_post_telldir(V9fsState *s, V9fsReadState *vs, ssize_t err)
{
- vs->dent = v9fs_do_readdir(s, vs->fidp->dir);
+ vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir);
v9fs_read_post_readdir(s, vs, err);
return;
}
@@ -1570,7 +1578,7 @@ static void v9fs_read_post_telldir(V9fsState *s, V9fsReadState *vs, ssize_t err)
static void v9fs_read_post_rewinddir(V9fsState *s, V9fsReadState *vs,
ssize_t err)
{
- vs->dir_pos = v9fs_do_telldir(s, vs->fidp->dir);
+ vs->dir_pos = v9fs_do_telldir(s, vs->fidp->fs.dir);
v9fs_read_post_telldir(s, vs, err);
return;
}
@@ -1589,7 +1597,7 @@ static void v9fs_read_post_readv(V9fsState *s, V9fsReadState *vs, ssize_t err)
if (0) {
print_sg(vs->sg, vs->cnt);
}
- vs->len = v9fs_do_readv(s, vs->fidp->fd, vs->sg, vs->cnt);
+ vs->len = v9fs_do_readv(s, vs->fidp->fs.fd, vs->sg, vs->cnt);
} while (vs->len == -1 && errno == EINTR);
if (vs->len == -1) {
err = -errno;
@@ -1619,7 +1627,7 @@ static void v9fs_read_post_lseek(V9fsState *s, V9fsReadState *vs, ssize_t err)
if (0) {
print_sg(vs->sg, vs->cnt);
}
- vs->len = v9fs_do_readv(s, vs->fidp->fd, vs->sg, vs->cnt);
+ vs->len = v9fs_do_readv(s, vs->fidp->fs.fd, vs->sg, vs->cnt);
} while (vs->len == -1 && errno == EINTR);
if (vs->len == -1) {
err = -errno;
@@ -1653,18 +1661,18 @@ static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
goto out;
}
- if (vs->fidp->dir) {
+ if (vs->fidp->fs.dir) {
vs->max_count = vs->count;
vs->count = 0;
if (vs->off == 0) {
- v9fs_do_rewinddir(s, vs->fidp->dir);
+ v9fs_do_rewinddir(s, vs->fidp->fs.dir);
}
v9fs_read_post_rewinddir(s, vs, err);
return;
- } else if (vs->fidp->fd != -1) {
+ } else if (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->fd, vs->off, SEEK_SET);
+ err = v9fs_do_lseek(s, vs->fidp->fs.fd, vs->off, SEEK_SET);
v9fs_read_post_lseek(s, vs, err);
return;
} else {
@@ -1711,7 +1719,7 @@ static void v9fs_readdir_post_readdir(V9fsState *s, V9fsReadDirState *vs)
if ((vs->count + V9_READDIR_DATA_SZ) > vs->max_count) {
/* Ran out of buffer. Set dir back to old position and return */
- v9fs_do_seekdir(s, vs->fidp->dir, vs->saved_dir_pos);
+ v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->saved_dir_pos);
v9fs_readdir_post_seekdir(s, vs);
return;
}
@@ -1722,7 +1730,7 @@ static void v9fs_readdir_post_readdir(V9fsState *s, V9fsReadDirState *vs)
vs->count += len;
v9fs_string_free(&vs->name);
vs->saved_dir_pos = vs->dent->d_off;
- vs->dent = v9fs_do_readdir(s, vs->fidp->dir);
+ vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir);
v9fs_readdir_post_readdir(s, vs);
return;
}
@@ -1736,14 +1744,14 @@ static void v9fs_readdir_post_readdir(V9fsState *s, V9fsReadDirState *vs)
static void v9fs_readdir_post_telldir(V9fsState *s, V9fsReadDirState *vs)
{
- vs->dent = v9fs_do_readdir(s, vs->fidp->dir);
+ vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir);
v9fs_readdir_post_readdir(s, vs);
return;
}
static void v9fs_readdir_post_setdir(V9fsState *s, V9fsReadDirState *vs)
{
- vs->saved_dir_pos = v9fs_do_telldir(s, vs->fidp->dir);
+ vs->saved_dir_pos = v9fs_do_telldir(s, vs->fidp->fs.dir);
v9fs_readdir_post_telldir(s, vs);
return;
}
@@ -1764,15 +1772,17 @@ static void v9fs_readdir(V9fsState *s, V9fsPDU *pdu)
&vs->max_count);
vs->fidp = lookup_fid(s, fid);
- if (vs->fidp == NULL || !(vs->fidp->dir)) {
+ if (vs->fidp == NULL ||
+ vs->fidp->fid_type != P9_FID_DIR ||
+ !(vs->fidp->fs.dir)) {
err = -EINVAL;
goto out;
}
if (vs->initial_offset == 0) {
- v9fs_do_rewinddir(s, vs->fidp->dir);
+ v9fs_do_rewinddir(s, vs->fidp->fs.dir);
} else {
- v9fs_do_seekdir(s, vs->fidp->dir, vs->initial_offset);
+ v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->initial_offset);
}
v9fs_readdir_post_setdir(s, vs);
@@ -1799,7 +1809,7 @@ static void v9fs_write_post_writev(V9fsState *s, V9fsWriteState *vs,
if (0) {
print_sg(vs->sg, vs->cnt);
}
- vs->len = v9fs_do_writev(s, vs->fidp->fd, vs->sg, vs->cnt);
+ vs->len = v9fs_do_writev(s, vs->fidp->fs.fd, vs->sg, vs->cnt);
} while (vs->len == -1 && errno == EINTR);
if (vs->len == -1) {
err = -errno;
@@ -1828,7 +1838,7 @@ static void v9fs_write_post_lseek(V9fsState *s, V9fsWriteState *vs, ssize_t err)
if (0) {
print_sg(vs->sg, vs->cnt);
}
- vs->len = v9fs_do_writev(s, vs->fidp->fd, vs->sg, vs->cnt);
+ vs->len = v9fs_do_writev(s, vs->fidp->fs.fd, vs->sg, vs->cnt);
} while (vs->len == -1 && errno == EINTR);
if (vs->len == -1) {
err = -errno;
@@ -1865,12 +1875,12 @@ static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
goto out;
}
- if (vs->fidp->fd == -1) {
+ if (vs->fidp->fs.fd == -1) {
err = -EINVAL;
goto out;
}
- err = v9fs_do_lseek(s, vs->fidp->fd, vs->off, SEEK_SET);
+ err = v9fs_do_lseek(s, vs->fidp->fs.fd, vs->off, SEEK_SET);
v9fs_write_post_lseek(s, vs, err);
return;
@@ -1909,9 +1919,10 @@ static void v9fs_create_post_perms(V9fsState *s, V9fsCreateState *vs, int err)
static void v9fs_create_post_opendir(V9fsState *s, V9fsCreateState *vs,
int err)
{
- if (!vs->fidp->dir) {
+ if (!vs->fidp->fs.dir) {
err = -errno;
}
+ vs->fidp->fid_type = P9_FID_DIR;
v9fs_post_create(s, vs, err);
}
@@ -1923,7 +1934,7 @@ static void v9fs_create_post_dir_lstat(V9fsState *s, V9fsCreateState *vs,
goto out;
}
- vs->fidp->dir = v9fs_do_opendir(s, &vs->fullname);
+ vs->fidp->fs.dir = v9fs_do_opendir(s, &vs->fullname);
v9fs_create_post_opendir(s, vs, err);
return;
@@ -1949,7 +1960,7 @@ out:
static void v9fs_create_post_fstat(V9fsState *s, V9fsCreateState *vs, int err)
{
if (err) {
- vs->fidp->fd = -1;
+ vs->fidp->fs.fd = -1;
err = -errno;
}
@@ -1959,12 +1970,12 @@ static void v9fs_create_post_fstat(V9fsState *s, V9fsCreateState *vs, int err)
static void v9fs_create_post_open2(V9fsState *s, V9fsCreateState *vs, int err)
{
- if (vs->fidp->fd == -1) {
+ if (vs->fidp->fs.fd == -1) {
err = -errno;
goto out;
}
-
- err = v9fs_do_fstat(s, vs->fidp->fd, &vs->stbuf);
+ vs->fidp->fid_type = P9_FID_FILE;
+ err = v9fs_do_fstat(s, vs->fidp->fs.fd, &vs->stbuf);
v9fs_create_post_fstat(s, vs, err);
return;
@@ -2031,7 +2042,7 @@ static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err)
err = v9fs_do_mknod(s, vs, S_IFSOCK | (vs->perm & 0777), 0);
v9fs_post_create(s, vs, err);
} else {
- vs->fidp->fd = v9fs_do_open2(s, vs);
+ vs->fidp->fs.fd = v9fs_do_open2(s, vs);
v9fs_create_post_open2(s, vs, err);
}
@@ -2420,7 +2431,7 @@ static void v9fs_wstat(V9fsState *s, V9fsPDU *pdu)
/* do we need to sync the file? */
if (donttouch_stat(&vs->v9stat)) {
- err = v9fs_do_fsync(s, vs->fidp->fd);
+ err = v9fs_do_fsync(s, vs->fidp->fs.fd);
v9fs_wstat_post_fsync(s, vs, err);
return;
}
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index d033271..942e448 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -137,12 +137,32 @@ typedef struct V9fsStat
int32_t n_muid;
} V9fsStat;
+enum {
+ P9_FID_NONE = 0,
+ P9_FID_FILE,
+ P9_FID_DIR,
+ P9_FID_XATTR,
+};
+
+typedef struct V9fsXattr
+{
+ int64_t copied_len;
+ int64_t len;
+ void *value;
+ V9fsString name;
+ int flags;
+} V9fsXattr;
+
struct V9fsFidState
{
+ int fid_type;
int32_t fid;
V9fsString path;
- int fd;
- DIR *dir;
+ union {
+ int fd;
+ DIR *dir;
+ V9fsXattr xattr;
+ } fs;
uid_t uid;
V9fsFidState *next;
};
--
1.7.1.236.g81fa0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 2/4] virtio-9p: Implement TXATTRWALK
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
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
2 siblings, 0 replies; 4+ messages in thread
From: Aneesh Kumar K.V @ 2010-06-01 9:28 UTC (permalink / raw)
To: qemu-devel; +Cc: ericvh, v9fs-developer, aliguori, Aneesh Kumar K.V
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
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 3/4] virtio-9p: Implement TXATTRCREATE
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 ` [Qemu-devel] [PATCH 2/4] virtio-9p: Implement TXATTRWALK Aneesh Kumar K.V
@ 2010-06-01 9:28 ` 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
2 siblings, 0 replies; 4+ messages in thread
From: Aneesh Kumar K.V @ 2010-06-01 9:28 UTC (permalink / raw)
To: qemu-devel; +Cc: ericvh, v9fs-developer, aliguori, Aneesh Kumar K.V
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 <aneesh.kumar@linux.vnet.ibm.com>
---
hw/file-op-9p.h | 1 +
hw/virtio-9p-debug.c | 10 ++++
hw/virtio-9p-local.c | 7 +++
hw/virtio-9p.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++---
hw/virtio-9p.h | 2 +
5 files changed, 156 insertions(+), 9 deletions(-)
diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h
index d5bab9a..a33fc9c 100644
--- a/hw/file-op-9p.h
+++ b/hw/file-op-9p.h
@@ -77,6 +77,7 @@ typedef struct FileOperations
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);
+ 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 5be1670..0916a07 100644
--- a/hw/virtio-9p-debug.c
+++ b/hw/virtio-9p-debug.c
@@ -550,6 +550,16 @@ void pprint_pdu(V9fsPDU *pdu)
fprintf(llogfile, "RXATTRWALK: (");
pprint_int64(pdu, 1, &offset, "xattrsize");
break;
+ 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);
break;
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
index 97b1544..4799fa9 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -484,6 +484,12 @@ static int 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,
@@ -514,4 +520,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 de2ec41..7330df0 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -285,6 +285,14 @@ static int 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;
@@ -438,8 +446,41 @@ 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);
+ if (retval < 0)
+ retval = -errno;
+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) {
@@ -466,14 +507,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
@@ -1895,6 +1934,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;
@@ -1910,7 +1991,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) {
@@ -1918,11 +1999,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);
@@ -2709,6 +2800,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);
@@ -2718,6 +2844,7 @@ static pdu_handler_t *pdu_handlers[] = {
[P9_TGETATTR] = v9fs_getattr,
[P9_TSYMLINK] = v9fs_symlink,
[P9_TXATTRWALK] = v9fs_xattrwalk,
+ [P9_TXATTRCREATE] = v9fs_xattrcreate,
[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 c534923..172eb3d 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -21,6 +21,8 @@ enum {
P9_RGETATTR,
P9_TXATTRWALK = 30,
P9_RXATTRWALK,
+ P9_TXATTRCREATE = 32,
+ P9_RXATTRCREATE,
P9_TREADDIR = 40,
P9_RREADDIR,
P9_TLINK = 70,
--
1.7.1.236.g81fa0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 4/4] virtio-9p: Hide user.virtfs xattr in case of mapped security.
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 ` [Qemu-devel] [PATCH 2/4] virtio-9p: Implement TXATTRWALK Aneesh Kumar K.V
2010-06-01 9:28 ` [Qemu-devel] [PATCH 3/4] virtio-9p: Implement TXATTRCREATE Aneesh Kumar K.V
@ 2010-06-01 9:28 ` Aneesh Kumar K.V
2 siblings, 0 replies; 4+ messages in thread
From: Aneesh Kumar K.V @ 2010-06-01 9:28 UTC (permalink / raw)
To: qemu-devel; +Cc: ericvh, v9fs-developer, aliguori, Aneesh Kumar K.V
With mapped security mode we use "user.virtfs" namespace is used
to store the virtFs related attributes. So hide it from user.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
hw/virtio-9p-local.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
index 4799fa9..a52e9e8 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -475,18 +475,87 @@ static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf)
static int local_lgetxattr(FsContext *ctx, const char *path, const char *name,
void *value, size_t size)
{
+
+ if ((ctx->fs_sm == SM_MAPPED) &&
+ (strncmp(name, "user.virtfs.", 12) == 0)) {
+ /*
+ * Don't allow fetch of user.virtfs namesapce
+ * in case of mapped security
+ */
+ errno = ENOATTR;
+ return -1;
+ }
return lgetxattr(rpath(ctx, path), name, value, size);
}
-static int local_llistxattr(FsContext *ctx, const char *path,
+static ssize_t local_llistxattr(FsContext *ctx, const char *path,
void *value, size_t size)
{
- return llistxattr(rpath(ctx, path), value, size);
+ ssize_t retval;
+ ssize_t actual_len = 0;
+ char *orig_value, *orig_value_start;
+ char *temp_value, *temp_value_start;
+ ssize_t xattr_len, parsed_len = 0, attr_len;
+
+ if (ctx->fs_sm != SM_MAPPED) {
+ return llistxattr(rpath(ctx, path), value, size);
+ }
+
+ /* Get the actual len */
+ xattr_len = llistxattr(rpath(ctx, path), value, 0);
+
+ /* Now fetch the xattr and find the actual size */
+ orig_value = qemu_malloc(xattr_len);
+ xattr_len = llistxattr(rpath(ctx, path), orig_value, xattr_len);
+
+ /*
+ * For mapped security model drop user.virtfs namespace
+ * from the list
+ */
+ temp_value = qemu_mallocz(xattr_len);
+ temp_value_start = temp_value;
+ orig_value_start = orig_value;
+ while (xattr_len > parsed_len) {
+ attr_len = strlen(orig_value) + 1;
+ if (strncmp(orig_value, "user.virtfs.", 12) != 0) {
+ /* Copy this entry */
+ strcat(temp_value, orig_value);
+ temp_value += attr_len;
+ actual_len += attr_len;
+ }
+ parsed_len += attr_len;
+ orig_value += attr_len;
+ }
+ if (!size) {
+ retval = actual_len;
+ goto out;
+ } else if (size >= actual_len) {
+ /* now copy the parsed attribute list back */
+ memset(value, 0, size);
+ memcpy(value, temp_value_start, actual_len);
+ retval = actual_len;
+ goto out;
+ }
+ errno = ERANGE;
+ retval = -1;
+out:
+ qemu_free(orig_value_start);
+ qemu_free(temp_value_start);
+ return retval;
}
static int local_lsetxattr(FsContext *ctx, const char *path, const char *name,
void *value, size_t size, int flags)
{
+ if ((ctx->fs_sm == SM_MAPPED) &&
+ (strncmp(name, "user.virtfs.", 12) == 0)) {
+ /*
+ * Don't allow fetch of user.virtfs namesapce
+ * in case of mapped security
+ */
+ errno = EACCES;
+ return -1;
+ }
return lsetxattr(rpath(ctx, path), name, value, size, flags);
}
--
1.7.1.236.g81fa0
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-06-01 9:29 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [Qemu-devel] [PATCH 2/4] virtio-9p: Implement TXATTRWALK Aneesh Kumar K.V
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).