* [Qemu-devel] [PATCH 1/6] This patch converts v9fs_stat() to make use of the threadlets infrastructure.
2010-10-13 17:09 [Qemu-devel] [RFC PATCH 0/6] First Threading Model Arun R Bharadwaj
@ 2010-10-13 17:09 ` Arun R Bharadwaj
2010-10-13 17:09 ` [Qemu-devel] [PATCH 2/6] This patch converts v9fs_wstat() " Arun R Bharadwaj
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:09 UTC (permalink / raw)
To: qemu-devel
From: Gautham R Shenoy <ego@in.ibm.com>
Every call to v9fs_stat() is processed in the context of the vcpu thread before
offloading the actual stat operation onto an async-thread. The post operation is
handled in the context of the io-thread which in turn does the complete()
operation for this particular v9fs_stat() operation.
Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
---
hw/virtio-9p.c | 34 ++++++++++++++++++++++------------
hw/virtio-9p.h | 6 ++++++
2 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 174300d..5f6ce56 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -1356,26 +1356,38 @@ out:
v9fs_string_free(&aname);
}
-static void v9fs_stat_post_lstat(V9fsState *s, V9fsStatState *vs, int err)
+static void v9fs_stat_post_lstat(void *opaque)
{
- if (err == -1) {
- err = -errno;
+ V9fsStatState *vs = (V9fsStatState *)opaque;
+
+ if (vs->err == -1) {
+ vs->err = -(vs->v9fs_errno);
goto out;
}
- err = stat_to_v9stat(s, &vs->fidp->path, &vs->stbuf, &vs->v9stat);
- if (err) {
+ vs->err = stat_to_v9stat(vs->s, &vs->fidp->path, &vs->stbuf, &vs->v9stat);
+ if (vs->err) {
goto out;
}
vs->offset += pdu_marshal(vs->pdu, vs->offset, "wS", 0, &vs->v9stat);
- err = vs->offset;
+ vs->err = vs->offset;
out:
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
v9fs_stat_free(&vs->v9stat);
qemu_free(vs);
}
+static void v9fs_stat_do_lstat(ThreadletWork *work)
+{
+ V9fsStatState *vs = container_of(work, V9fsStatState, work);
+
+ vs->err = v9fs_do_lstat(vs->s, &vs->fidp->path, &vs->stbuf);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
{
int32_t fid;
@@ -1385,6 +1397,7 @@ static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
vs = qemu_malloc(sizeof(*vs));
vs->pdu = pdu;
vs->offset = 7;
+ vs->s = s;
memset(&vs->v9stat, 0, sizeof(vs->v9stat));
@@ -1396,8 +1409,8 @@ static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
goto out;
}
- err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
- v9fs_stat_post_lstat(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_stat_do_lstat, &vs->post_fn,
+ v9fs_stat_post_lstat);
return;
out:
@@ -3882,8 +3895,5 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
qemu_mutex_init(&(v9fs_async_struct.lock));
/* Create async queue. */
- (void)v9fs_do_async_posix;
- (void)v9fs_async_helper_done;
-
return &s->vdev;
}
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 6c23319..769d3fc 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -7,6 +7,7 @@
#include <utime.h>
#include "file-op-9p.h"
+#include "qemu-threadlets.h"
/* The feature bitmap for virtio 9P */
/* The mount point is specified in a config variable */
@@ -246,6 +247,11 @@ typedef struct V9fsStatState {
V9fsStat v9stat;
V9fsFidState *fidp;
struct stat stbuf;
+ V9fsState *s;
+ int err;
+ int v9fs_errno;
+ ThreadletWork work;
+ void (*post_fn)(void *arg);
} V9fsStatState;
typedef struct V9fsStatDotl {
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 2/6] This patch converts v9fs_wstat() to make use of the threadlets infrastructure.
2010-10-13 17:09 [Qemu-devel] [RFC PATCH 0/6] First Threading Model Arun R Bharadwaj
2010-10-13 17:09 ` [Qemu-devel] [PATCH 1/6] This patch converts v9fs_stat() to make use of the threadlets infrastructure Arun R Bharadwaj
@ 2010-10-13 17:09 ` Arun R Bharadwaj
2010-10-13 17:09 ` [Qemu-devel] [PATCH 3/6] This patch converts v9fs_read() " Arun R Bharadwaj
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:09 UTC (permalink / raw)
To: qemu-devel
From: Gautham R Shenoy <ego@in.ibm.com>
This patch offloads all the blocking calls invoked for v9fs_wstat onto
the helper threads belonging to the threadlets infrastructure.The handling
of the v9fs_post_*wstat* calls is done from the io-thread context.
Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
---
hw/virtio-9p.c | 291 +++++++++++++++++++++++++++++++++++++++++++++-----------
hw/virtio-9p.h | 7 +
2 files changed, 243 insertions(+), 55 deletions(-)
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 5f6ce56..cf7e012 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -2853,36 +2853,126 @@ out:
qemu_free(vs);
}
-static void v9fs_wstat_post_truncate(V9fsState *s, V9fsWstatState *vs, int err)
+/*********************** v9fs_wstat operations ************************/
+
+static void v9fs_wstat_do_fsync(ThreadletWork *work)
+ {
+ V9fsWstatState *vs;
+
+ vs = container_of(work, V9fsWstatState, work);
+ vs->err = v9fs_do_fsync(vs->s, vs->fidp->fs.fd);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_wstat_do_lstat(ThreadletWork *work)
{
- if (err < 0) {
+ V9fsWstatState *vs;
+
+ vs = container_of(work, V9fsWstatState, work);
+ vs->err = v9fs_do_lstat(vs->s, &vs->fidp->path, &vs->stbuf);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_wstat_do_utimensat(ThreadletWork *work)
+{
+ V9fsWstatState *vs;
+
+ vs = container_of(work, V9fsWstatState, work);
+ vs->err = v9fs_do_utimensat(vs->s, &vs->fidp->path, vs->times);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+
+}
+
+static void v9fs_wstat_do_chmod(ThreadletWork *work)
+{
+ V9fsWstatState *vs;
+
+ vs = container_of(work, V9fsWstatState, work);
+ vs->err = v9fs_do_chmod(vs->s, &vs->fidp->path,
+ v9mode_to_mode(vs->v9stat.mode,
+ &vs->v9stat.extension));
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_wstat_do_chown(ThreadletWork *work)
+{
+ V9fsWstatState *vs;
+
+ vs = container_of(work, V9fsWstatState, work);
+ vs->err = v9fs_do_chown(vs->s, &vs->fidp->path, vs->v9stat.n_uid,
+ vs->v9stat.n_gid);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_wstat_do_rename(ThreadletWork *work)
+{
+ V9fsWstatState *vs;
+
+ vs = container_of(work, V9fsWstatState, work);
+ vs->err = v9fs_do_rename(vs->s, &vs->fidp->path, &vs->nname);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_wstat_do_truncate(ThreadletWork *work)
+{
+ V9fsWstatState *vs;
+
+ vs = container_of(work, V9fsWstatState, work);
+ vs->err = v9fs_do_truncate(vs->s, &vs->fidp->path,
+ vs->v9stat.length);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_wstat_post_truncate(void *opaque)
+{
+ V9fsWstatState *vs = (V9fsWstatState *)opaque;
+
+ if (vs->err < 0) {
+ vs->err = -vs->v9fs_errno;
goto out;
}
- err = vs->offset;
+ vs->err = vs->offset;
out:
v9fs_stat_free(&vs->v9stat);
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
}
-static void v9fs_wstat_post_rename(V9fsState *s, V9fsWstatState *vs, int err)
+static void v9fs_wstat_post_rename(void *opaque)
{
- if (err < 0) {
+ V9fsWstatState *vs = (V9fsWstatState *)opaque;
+
+ if (vs->err < 0) {
+ vs->err = -vs->v9fs_errno;
goto out;
}
if (vs->v9stat.length != -1) {
- if (v9fs_do_truncate(s, &vs->fidp->path, vs->v9stat.length) < 0) {
- err = -errno;
- }
+ v9fs_do_async_posix(&vs->work, v9fs_wstat_do_truncate,
+ &vs->post_fn, v9fs_wstat_post_truncate);
+ return;
}
- v9fs_wstat_post_truncate(s, vs, err);
+ v9fs_wstat_post_truncate(vs);
return;
out:
v9fs_stat_free(&vs->v9stat);
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
}
@@ -2964,6 +3054,7 @@ static void v9fs_rename_post_rename(V9fsState *s, V9fsRenameState *vs, int err)
qemu_free(vs);
}
+#if 0
static void v9fs_wstat_post_chown(V9fsState *s, V9fsWstatState *vs, int err)
{
if (err < 0) {
@@ -2992,6 +3083,91 @@ out:
complete_pdu(s, vs->pdu, err);
qemu_free(vs);
}
+#endif
+
+static void v9fs_wstat_post_rename_new(void *opaque)
+{
+ V9fsWstatState *vs = (V9fsWstatState *)opaque;
+ V9fsFidState *fidp;
+
+ if (vs->err < 0) {
+ vs->err = -vs->v9fs_errno;
+ goto out;
+ }
+
+ /*
+ * Fixup fid's pointing to the old name to
+ * start pointing to the new name
+ */
+ for (fidp = vs->s->fid_list; fidp; fidp = fidp->next) {
+ if (vs->fidp == fidp) {
+ /*
+ * we replace name of this fid towards the end
+ * so that our below strcmp will work
+ */
+ continue;
+ }
+ if (!strncmp(vs->fidp->path.data, fidp->path.data,
+ strlen(vs->fidp->path.data))) {
+ /* replace the name */
+ v9fs_fix_path(&fidp->path, &vs->nname,
+ strlen(vs->fidp->path.data));
+ }
+ }
+
+ v9fs_string_copy(&vs->fidp->path, &vs->nname);
+
+out:
+ v9fs_wstat_post_rename(vs);
+ return;
+}
+
+static void v9fs_wstat_post_chown(void *opaque)
+{
+ V9fsWstatState *vs = (V9fsWstatState *)opaque;
+
+ if (vs->err < 0) {
+ vs->err = -vs->v9fs_errno;
+ goto out;
+ }
+
+ if (vs->v9stat.name.size != 0) {
+ char *old_name, *new_name;
+ char *end;
+
+ old_name = vs->fidp->path.data;
+ end = strrchr(old_name, '/');
+ if (end) {
+ end++;
+ } else {
+ end = old_name;
+ }
+
+ new_name = qemu_malloc(end - old_name + vs->v9stat.name.size + 1);
+
+ memset(new_name, 0, end - old_name + vs->v9stat.name.size + 1);
+ memcpy(new_name, old_name, end - old_name);
+ memcpy(new_name + (end - old_name), vs->v9stat.name.data,
+ vs->v9stat.name.size);
+ vs->nname.data = new_name;
+ vs->nname.size = strlen(new_name);
+
+ if (strcmp(new_name, vs->fidp->path.data) != 0) {
+ v9fs_do_async_posix(&vs->work, v9fs_wstat_do_rename,
+ &vs->post_fn, v9fs_wstat_post_rename_new);
+ return;
+ }
+ }
+
+ v9fs_wstat_post_rename(vs);
+ return;
+
+out:
+ v9fs_stat_free(&vs->v9stat);
+ complete_pdu(vs->s, vs->pdu, vs->err);
+ qemu_free(vs);
+}
+
static void v9fs_rename(V9fsState *s, V9fsPDU *pdu)
{
@@ -3021,78 +3197,85 @@ out:
qemu_free(vs);
}
-static void v9fs_wstat_post_utime(V9fsState *s, V9fsWstatState *vs, int err)
+static void v9fs_wstat_post_utime(void *opaque)
{
- if (err < 0) {
+ V9fsWstatState *vs = (V9fsWstatState *)opaque;
+
+ if (vs->err < 0) {
+ vs->err = -vs->v9fs_errno;
goto out;
}
if (vs->v9stat.n_gid != -1 || vs->v9stat.n_uid != -1) {
- if (v9fs_do_chown(s, &vs->fidp->path, vs->v9stat.n_uid,
- vs->v9stat.n_gid)) {
- err = -errno;
- }
+ v9fs_do_async_posix(&vs->work, v9fs_wstat_do_chown, &vs->post_fn,
+ v9fs_wstat_post_chown);
+ return;
}
- v9fs_wstat_post_chown(s, vs, err);
+ v9fs_wstat_post_chown(vs);
return;
out:
v9fs_stat_free(&vs->v9stat);
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
}
-static void v9fs_wstat_post_chmod(V9fsState *s, V9fsWstatState *vs, int err)
+static void v9fs_wstat_post_chmod(void *opaque)
{
- if (err < 0) {
+ V9fsWstatState *vs = (V9fsWstatState *)opaque;
+
+ if (vs->err < 0) {
+ vs->err = -vs->v9fs_errno;
goto out;
}
if (vs->v9stat.mtime != -1 || vs->v9stat.atime != -1) {
- struct timespec times[2];
if (vs->v9stat.atime != -1) {
- times[0].tv_sec = vs->v9stat.atime;
- times[0].tv_nsec = 0;
+ vs->times[0].tv_sec = vs->v9stat.atime;
+ vs->times[0].tv_nsec = 0;
} else {
- times[0].tv_nsec = UTIME_OMIT;
+ vs->times[0].tv_nsec = UTIME_OMIT;
}
if (vs->v9stat.mtime != -1) {
- times[1].tv_sec = vs->v9stat.mtime;
- times[1].tv_nsec = 0;
+ vs->times[1].tv_sec = vs->v9stat.mtime;
+ vs->times[1].tv_nsec = 0;
} else {
- times[1].tv_nsec = UTIME_OMIT;
+ vs->times[1].tv_nsec = UTIME_OMIT;
}
- if (v9fs_do_utimensat(s, &vs->fidp->path, times)) {
- err = -errno;
- }
+ v9fs_do_async_posix(&vs->work, v9fs_wstat_do_utimensat,
+ &vs->post_fn, v9fs_wstat_post_utime);
+ return;
}
- v9fs_wstat_post_utime(s, vs, err);
+ v9fs_wstat_post_utime(vs);
return;
out:
v9fs_stat_free(&vs->v9stat);
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
}
-static void v9fs_wstat_post_fsync(V9fsState *s, V9fsWstatState *vs, int err)
+static void v9fs_wstat_post_fsync(void *opaque)
{
- if (err == -1) {
- err = -errno;
+ V9fsWstatState *vs = (V9fsWstatState *)opaque;
+
+ if (vs->err == -1) {
+ vs->err = -vs->v9fs_errno;
}
v9fs_stat_free(&vs->v9stat);
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
}
-static void v9fs_wstat_post_lstat(V9fsState *s, V9fsWstatState *vs, int err)
+static void v9fs_wstat_post_lstat(void *opaque)
{
uint32_t v9_mode;
+ V9fsWstatState *vs = (V9fsWstatState *)opaque;
- if (err == -1) {
- err = -errno;
+ if (vs->err == -1) {
+ vs->err = -vs->v9fs_errno;
goto out;
}
@@ -3101,20 +3284,17 @@ static void v9fs_wstat_post_lstat(V9fsState *s, V9fsWstatState *vs, int err)
if ((vs->v9stat.mode & P9_STAT_MODE_TYPE_BITS) !=
(v9_mode & P9_STAT_MODE_TYPE_BITS)) {
/* Attempting to change the type */
- err = -EIO;
+ vs->err = -EIO;
goto out;
}
- if (v9fs_do_chmod(s, &vs->fidp->path, v9mode_to_mode(vs->v9stat.mode,
- &vs->v9stat.extension))) {
- err = -errno;
- }
- v9fs_wstat_post_chmod(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_wstat_do_chmod, &vs->post_fn,
+ v9fs_wstat_post_chmod);
return;
out:
v9fs_stat_free(&vs->v9stat);
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
}
@@ -3122,39 +3302,40 @@ static void v9fs_wstat(V9fsState *s, V9fsPDU *pdu)
{
int32_t fid;
V9fsWstatState *vs;
- int err = 0;
vs = qemu_malloc(sizeof(*vs));
vs->pdu = pdu;
vs->offset = 7;
+ vs->s = s;
+ vs->err = 0;
pdu_unmarshal(pdu, vs->offset, "dwS", &fid, &vs->unused, &vs->v9stat);
vs->fidp = lookup_fid(s, fid);
if (vs->fidp == NULL) {
- err = -EINVAL;
+ vs->err = -EINVAL;
goto out;
}
/* do we need to sync the file? */
if (donttouch_stat(&vs->v9stat)) {
- err = v9fs_do_fsync(s, vs->fidp->fs.fd);
- v9fs_wstat_post_fsync(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_wstat_do_fsync, &vs->post_fn,
+ v9fs_wstat_post_fsync);
return;
}
if (vs->v9stat.mode != -1) {
- err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
- v9fs_wstat_post_lstat(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_wstat_do_lstat, &vs->post_fn,
+ v9fs_wstat_post_lstat);
return;
}
- v9fs_wstat_post_chmod(s, vs, err);
+ v9fs_wstat_post_chmod(vs);
return;
out:
v9fs_stat_free(&vs->v9stat);
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(s, vs->pdu, vs->err);
qemu_free(vs);
}
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 769d3fc..74d7b68 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -354,6 +354,13 @@ typedef struct V9fsWstatState
V9fsStat v9stat;
V9fsFidState *fidp;
struct stat stbuf;
+ V9fsString nname;
+ V9fsState *s;
+ int err;
+ int v9fs_errno;
+ struct timespec times[2];
+ ThreadletWork work;
+ void (*post_fn)(void *arg);
} V9fsWstatState;
typedef struct V9fsSymlinkState
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 3/6] This patch converts v9fs_read() to make use of the threadlets infrastructure.
2010-10-13 17:09 [Qemu-devel] [RFC PATCH 0/6] First Threading Model Arun R Bharadwaj
2010-10-13 17:09 ` [Qemu-devel] [PATCH 1/6] This patch converts v9fs_stat() to make use of the threadlets infrastructure Arun R Bharadwaj
2010-10-13 17:09 ` [Qemu-devel] [PATCH 2/6] This patch converts v9fs_wstat() " Arun R Bharadwaj
@ 2010-10-13 17:09 ` Arun R Bharadwaj
2010-10-13 17:10 ` [Qemu-devel] [PATCH 4/6] This patch converts v9fs_write() " Arun R Bharadwaj
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:09 UTC (permalink / raw)
To: qemu-devel
From: Gautham R Shenoy <ego@in.ibm.com>
This patch offloads all the blocking calls invoked for v9fs_read onto the
helper threads belonging to the threadlets infrastructure. The handling of
the v9fs_post_*read* calls is done from the io-thread context.
Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Arun R Bharadwaj <arun@linux.vnet.ibm.com>
---
hw/virtio-9p.c | 218 +++++++++++++++++++++++++++++++++++++++++---------------
hw/virtio-9p.h | 5 +
2 files changed, 164 insertions(+), 59 deletions(-)
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index cf7e012..da185c3 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -2037,33 +2037,136 @@ out:
complete_pdu(s, pdu, err);
}
-static void v9fs_read_post_readdir(V9fsState *, V9fsReadState *, ssize_t);
+/********************** v9fs_read calls ******************************/
+static void v9fs_read_do_preadv(ThreadletWork *work)
+{
+ V9fsReadState *vs;
+
+ vs = container_of(work, V9fsReadState, work);
+ v9fs_do_preadv(vs->s, vs->fidp->fs.fd, vs->sg, vs->cnt, vs->off);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_rewinddir(ThreadletWork *work)
+ {
+ V9fsReadState *vs;
+
+ vs = container_of(work, V9fsReadState, work);
+ v9fs_do_rewinddir(vs->s, vs->fidp->fs.dir);
+ vs->v9fs_errno = errno;
-static void v9fs_read_post_seekdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_lseek(ThreadletWork *work)
{
- if (err) {
+ V9fsReadState *vs;
+
+ vs = container_of(work, V9fsReadState, work);
+ vs->err = v9fs_do_lseek(vs->s, vs->fidp->fs.fd, vs->off, SEEK_SET);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_readv(ThreadletWork *work)
+{
+ V9fsReadState *vs;
+
+ vs = container_of(work, V9fsReadState, work);
+ do {
+ if (0) {
+ print_sg(vs->sg, vs->cnt);
+ }
+ vs->len = v9fs_do_readv(vs->s, vs->fidp->fs.fd, vs->sg, vs->cnt);
+ } while (vs->len == -1 && errno == EINTR);
+ vs->v9fs_errno = errno;
+
+ if (vs->len == -1) {
+ vs->err = -vs->v9fs_errno;
+ }
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_telldir(ThreadletWork *work)
+{
+ V9fsReadState *vs;
+
+ vs = container_of(work, V9fsReadState, work);
+ vs->dir_pos = v9fs_do_telldir(vs->s, vs->fidp->fs.dir);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_readdir(ThreadletWork *work)
+{
+ V9fsReadState *vs;
+
+ vs = container_of(work, V9fsReadState, work);
+ vs->dent = v9fs_do_readdir(vs->s, vs->fidp->fs.dir);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_lstat(ThreadletWork *work)
+{
+ V9fsReadState *vs;
+
+ vs = container_of(work, V9fsReadState, work);
+ vs->err = v9fs_do_lstat(vs->s, &vs->name, &vs->stbuf);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_read_do_seekdir(ThreadletWork *work)
+{
+ V9fsReadState *vs;
+
+ vs = container_of(work, V9fsReadState, work);
+ v9fs_do_seekdir(vs->s, vs->fidp->fs.dir, vs->dir_pos);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+
+
+static void v9fs_read_post_readdir(void *);
+
+static void v9fs_read_post_seekdir(void *opaque)
+{
+ V9fsReadState *vs = (V9fsReadState *)opaque;
+
+ if (vs->err) {
goto out;
}
v9fs_stat_free(&vs->v9stat);
v9fs_string_free(&vs->name);
vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count);
vs->offset += vs->count;
- err = vs->offset;
+ vs->err = vs->offset;
out:
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
return;
}
-static void v9fs_read_post_dir_lstat(V9fsState *s, V9fsReadState *vs,
- ssize_t err)
+static void v9fs_read_post_dir_lstat(void *opaque)
{
- if (err) {
- err = -errno;
+ V9fsReadState *vs = (V9fsReadState *)opaque;
+
+ if (vs->err) {
+ vs->err = -vs->v9fs_errno;
goto out;
}
- err = stat_to_v9stat(s, &vs->name, &vs->stbuf, &vs->v9stat);
- if (err) {
+ vs->err = stat_to_v9stat(vs->s, &vs->name, &vs->stbuf, &vs->v9stat);
+ if (vs->err) {
goto out;
}
@@ -2071,26 +2174,28 @@ 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->fs.dir, vs->dir_pos);
- v9fs_read_post_seekdir(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_read_do_seekdir, &vs->post_fn,
+ v9fs_read_post_seekdir);
return;
}
vs->count += vs->len;
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->fs.dir);
- v9fs_read_post_readdir(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_read_do_readdir, &vs->post_fn,
+ v9fs_read_post_readdir);
return;
out:
- v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->dir_pos);
- v9fs_read_post_seekdir(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_read_do_seekdir, &vs->post_fn,
+ v9fs_read_post_seekdir);
return;
}
-static void v9fs_read_post_readdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
+static void v9fs_read_post_readdir(void *opaque)
{
+ V9fsReadState *vs = (V9fsReadState *)opaque;
+
if (vs->dent) {
memset(&vs->v9stat, 0, sizeof(vs->v9stat));
v9fs_string_init(&vs->name);
@@ -2098,64 +2203,61 @@ static void v9fs_read_post_readdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
vs->dent->d_name);
err = v9fs_do_lstat(s, &vs->name, &vs->stbuf);
v9fs_read_post_dir_lstat(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_read_do_lstat, &vs->post_fn,
+ v9fs_read_post_dir_lstat);
return;
}
vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count);
vs->offset += vs->count;
- err = vs->offset;
- complete_pdu(s, vs->pdu, err);
+ vs->err = vs->offset;
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
return;
}
-static void v9fs_read_post_telldir(V9fsState *s, V9fsReadState *vs, ssize_t err)
+static void v9fs_read_post_telldir(void *opaque)
{
- vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir);
- v9fs_read_post_readdir(s, vs, err);
+ V9fsReadState *vs = (V9fsReadState *)opaque;
+
+ v9fs_do_async_posix(&vs->work, v9fs_read_do_readdir, &vs->post_fn,
+ v9fs_read_post_readdir);
return;
}
-static void v9fs_read_post_rewinddir(V9fsState *s, V9fsReadState *vs,
- ssize_t err)
+static void v9fs_read_post_rewinddir(void *opaque)
{
- vs->dir_pos = v9fs_do_telldir(s, vs->fidp->fs.dir);
- v9fs_read_post_telldir(s, vs, err);
+ V9fsReadState *vs = (V9fsReadState *)opaque;
+
+ v9fs_do_async_posix(&vs->work, v9fs_read_do_telldir, &vs->post_fn,
+ v9fs_read_post_telldir);
return;
}
-static void v9fs_read_post_preadv(V9fsState *s, V9fsReadState *vs, ssize_t err)
+static void v9fs_read_post_preadv(void *opaque)
{
- if (err < 0) {
+ V9fsReadState *vs = (V9fsReadState *)opaque;
+
+ if (vs->err < 0) {
/* IO error return the error */
- err = -errno;
+ vs->err = -errno;
goto out;
+ } else {
+ vs->off += vs->len;
}
vs->total += vs->len;
vs->sg = adjust_sg(vs->sg, vs->len, &vs->cnt);
if (vs->total < vs->count && vs->len > 0) {
- do {
- if (0) {
- print_sg(vs->sg, vs->cnt);
- }
- vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
- vs->off);
- if (vs->len > 0) {
- vs->off += vs->len;
- }
- } while (vs->len == -1 && errno == EINTR);
- if (vs->len == -1) {
- err = -errno;
- }
- v9fs_read_post_preadv(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_read_do_preadv, &vs->post_fn,
+ v9fs_read_post_preadv);
return;
}
vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total);
vs->offset += vs->count;
- err = vs->offset;
+ vs->err = vs->offset;
out:
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
}
@@ -2188,7 +2290,6 @@ static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
{
int32_t fid;
V9fsReadState *vs;
- ssize_t err = 0;
vs = qemu_malloc(sizeof(*vs));
vs->pdu = pdu;
@@ -2196,12 +2297,13 @@ static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
vs->total = 0;
vs->len = 0;
vs->count = 0;
+ vs->s = s;
pdu_unmarshal(vs->pdu, vs->offset, "dqd", &fid, &vs->off, &vs->count);
vs->fidp = lookup_fid(s, fid);
if (vs->fidp == NULL) {
- err = -EINVAL;
+ vs->err = -EINVAL;
goto out;
}
@@ -2209,32 +2311,30 @@ static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
vs->max_count = vs->count;
vs->count = 0;
if (vs->off == 0) {
- v9fs_do_rewinddir(s, vs->fidp->fs.dir);
+ v9fs_do_async_posix(&vs->work, v9fs_read_do_rewinddir,
+ &vs->post_fn, v9fs_read_post_rewinddir);
+ return;
}
- v9fs_read_post_rewinddir(s, vs, err);
+ v9fs_read_post_rewinddir(vs);
return;
} 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);
vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
if (vs->total <= vs->count) {
- vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
- vs->off);
- if (vs->len > 0) {
- vs->off += vs->len;
- }
- err = vs->len;
- v9fs_read_post_preadv(s, vs, err);
+ vs->err = vs->len;
+ v9fs_do_async_posix(&vs->work, v9fs_read_do_preadv,
+ &vs->post_fn, v9fs_read_post_preadv);
}
return;
} else if (vs->fidp->fid_type == P9_FID_XATTR) {
v9fs_xattr_read(s, vs);
return;
} else {
- err = -EINVAL;
+ vs->err = -EINVAL;
}
out:
- complete_pdu(s, pdu, err);
+ complete_pdu(s, pdu, vs->err);
qemu_free(vs);
}
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 74d7b68..fcea434 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -325,6 +325,11 @@ typedef struct V9fsReadState {
int32_t len;
int32_t cnt;
int32_t max_count;
+ V9fsState *s;
+ int err;
+ int v9fs_errno;
+ ThreadletWork work;
+ void (*post_fn)(void *arg);
} V9fsReadState;
typedef struct V9fsWriteState {
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 4/6] This patch converts v9fs_write() to make use of the threadlets infrastructure.
2010-10-13 17:09 [Qemu-devel] [RFC PATCH 0/6] First Threading Model Arun R Bharadwaj
` (2 preceding siblings ...)
2010-10-13 17:09 ` [Qemu-devel] [PATCH 3/6] This patch converts v9fs_read() " Arun R Bharadwaj
@ 2010-10-13 17:10 ` Arun R Bharadwaj
2010-10-13 17:10 ` [Qemu-devel] [PATCH 5/6] This patch converts v9fs_open() " Arun R Bharadwaj
2010-10-13 17:10 ` [Qemu-devel] [PATCH 6/6] This patch converts v9fs_walk() " Arun R Bharadwaj
5 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:10 UTC (permalink / raw)
To: qemu-devel
From: Gautham R Shenoy <ego@in.ibm.com>
This patch offloads all the blocking calls invoked for v9fs_write onto the
helper threads belonging to the threadlets infrastructure. The handling of
the v9fs_post_*write* calls is done from the io-thread context.
Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
Signed-off-by: Arun R Bharadwaj <arun@linux.vnet.ibm.com>
---
hw/virtio-9p.c | 63 ++++++++++++++++++++++++++++----------------------------
hw/virtio-9p.h | 5 ++++
2 files changed, 37 insertions(+), 31 deletions(-)
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index da185c3..5fb7dc4 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -2459,37 +2459,41 @@ out:
return;
}
-static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs,
- ssize_t err)
+/************************ v9fs_write calls ************************/
+
+static void v9fs_write_do_pwritev(ThreadletWork *work)
+{
+ V9fsWriteState *vs;
+
+ vs = container_of(work, V9fsWriteState, work);
+ v9fs_do_pwritev(vs->s, vs->fidp->fs.fd, vs->sg, vs->cnt, vs->off);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_write_post_pwritev(void *opaque)
{
- if (err < 0) {
+ V9fsWriteState *vs = (V9fsWriteState *)opaque;
+
+ if (vs->err < 0) {
/* IO error return the error */
- err = -errno;
+ vs->err = -errno;
goto out;
+ } else {
+ vs->off += vs->len;
}
vs->total += vs->len;
vs->sg = adjust_sg(vs->sg, vs->len, &vs->cnt);
if (vs->total < vs->count && vs->len > 0) {
- do {
- if (0) {
- print_sg(vs->sg, vs->cnt);
- }
- vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
- vs->off);
- if (vs->len > 0) {
- vs->off += vs->len;
- }
- } while (vs->len == -1 && errno == EINTR);
- if (vs->len == -1) {
- err = -errno;
- }
- v9fs_write_post_pwritev(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_write_do_pwritev, &vs->post_fn,
+ v9fs_write_post_pwritev);
return;
}
vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total);
- err = vs->offset;
+ vs->err = vs->offset;
out:
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
}
@@ -2539,7 +2543,6 @@ static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
{
int32_t fid;
V9fsWriteState *vs;
- ssize_t err;
vs = qemu_malloc(sizeof(*vs));
@@ -2548,19 +2551,20 @@ static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
vs->sg = vs->iov;
vs->total = 0;
vs->len = 0;
+ vs->s = s;
pdu_unmarshal(vs->pdu, vs->offset, "dqdv", &fid, &vs->off, &vs->count,
vs->sg, &vs->cnt);
vs->fidp = lookup_fid(s, fid);
if (vs->fidp == NULL) {
- err = -EINVAL;
+ vs->err = -EINVAL;
goto out;
}
if (vs->fidp->fid_type == P9_FID_FILE) {
if (vs->fidp->fs.fd == -1) {
- err = -EINVAL;
+ vs->err = -EINVAL;
goto out;
}
} else if (vs->fidp->fid_type == P9_FID_XATTR) {
@@ -2570,21 +2574,18 @@ static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
v9fs_xattr_write(s, vs);
return;
} else {
- err = -EINVAL;
+ vs->err = -EINVAL;
goto out;
}
vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
if (vs->total <= vs->count) {
- vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt, vs->off);
- if (vs->len > 0) {
- vs->off += vs->len;
- }
- err = vs->len;
- v9fs_write_post_pwritev(s, vs, err);
+ vs->err = vs->len;
+ v9fs_do_async_posix(&vs->work, v9fs_write_do_pwritev, &vs->post_fn,
+ v9fs_write_post_pwritev);
}
return;
out:
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
}
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index fcea434..be87d5f 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -343,6 +343,11 @@ typedef struct V9fsWriteState {
struct iovec iov[128]; /* FIXME: bad, bad, bad */
struct iovec *sg;
int cnt;
+ V9fsState *s;
+ int err;
+ int v9fs_errno;
+ ThreadletWork work;
+ void (*post_fn)(void *arg);
} V9fsWriteState;
typedef struct V9fsRemoveState {
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 5/6] This patch converts v9fs_open() to make use of the threadlets infrastructure.
2010-10-13 17:09 [Qemu-devel] [RFC PATCH 0/6] First Threading Model Arun R Bharadwaj
` (3 preceding siblings ...)
2010-10-13 17:10 ` [Qemu-devel] [PATCH 4/6] This patch converts v9fs_write() " Arun R Bharadwaj
@ 2010-10-13 17:10 ` Arun R Bharadwaj
2010-10-13 17:10 ` [Qemu-devel] [PATCH 6/6] This patch converts v9fs_walk() " Arun R Bharadwaj
5 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:10 UTC (permalink / raw)
To: qemu-devel
From: Gautham R Shenoy <ego@in.ibm.com>
This patch offloads all the blocking calls invoked for v9fs_open onto the
helper threads belonging to the threadlets infrastructure. The handling of
the v9fs_post_*open* calls is done from the io-thread context.
Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
---
hw/virtio-9p.c | 86 +++++++++++++++++++++++++++++++++++++++++---------------
hw/virtio-9p.h | 5 +++
2 files changed, 68 insertions(+), 23 deletions(-)
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 5fb7dc4..75d4be3 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -1777,6 +1777,41 @@ out:
v9fs_walk_complete(s, vs, err);
}
+/********************* v9fs_open calls *********************************/
+static void v9fs_open_do_lstat(ThreadletWork *work)
+{
+ V9fsOpenState *vs;
+
+ vs = container_of(work, V9fsOpenState, work);
+ vs->err = v9fs_do_lstat(vs->s, &vs->fidp->path, &vs->stbuf);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_open_do_opendir(ThreadletWork *work)
+{
+ V9fsOpenState *vs;
+
+ vs = container_of(work, V9fsOpenState, work);
+ vs->fidp->fs.dir = v9fs_do_opendir(vs->s, &vs->fidp->path);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_open_do_open(ThreadletWork *work)
+{
+ V9fsOpenState *vs;
+
+ vs = container_of(work, V9fsOpenState, work);
+ vs->fidp->fs.fd = v9fs_do_open(vs->s, &vs->fidp->path,
+ omode_to_uflags(vs->mode));
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
static int32_t get_iounit(V9fsState *s, V9fsString *name)
{
struct statfs stbuf;
@@ -1797,17 +1832,19 @@ static int32_t get_iounit(V9fsState *s, V9fsString *name)
return iounit;
}
-static void v9fs_open_post_opendir(V9fsState *s, V9fsOpenState *vs, int err)
+static void v9fs_open_post_opendir(void *opaque)
{
+ V9fsOpenState *vs = (V9fsOpenState *)opaque;
+
if (vs->fidp->fs.dir == NULL) {
- err = -errno;
+ vs->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;
+ vs->err = vs->offset;
out:
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
}
@@ -1821,35 +1858,39 @@ static void v9fs_open_post_getiounit(V9fsState *s, V9fsOpenState *vs)
qemu_free(vs);
}
-static void v9fs_open_post_open(V9fsState *s, V9fsOpenState *vs, int err)
+static void v9fs_open_post_open(void *opaque)
{
+ V9fsOpenState *vs = (V9fsOpenState *)opaque;
+
if (vs->fidp->fs.fd == -1) {
- err = -errno;
+ vs->err = -errno;
goto out;
}
vs->fidp->fid_type = P9_FID_FILE;
- vs->iounit = get_iounit(s, &vs->fidp->path);
- v9fs_open_post_getiounit(s, vs);
+ /* FIXME: Need a new state here */
+ vs->iounit = get_iounit(vs->s, &vs->fidp->path);
+ v9fs_open_post_getiounit(vs->s, vs);
return;
out:
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
}
-static void v9fs_open_post_lstat(V9fsState *s, V9fsOpenState *vs, int err)
+static void v9fs_open_post_lstat(void *opaque)
{
+ V9fsOpenState *vs = (V9fsOpenState *)opaque;
int flags;
- if (err) {
- err = -errno;
+ if (vs->err) {
+ vs->err = -errno;
goto out;
}
stat_to_qid(&vs->stbuf, &vs->qid);
if (S_ISDIR(vs->stbuf.st_mode)) {
- vs->fidp->fs.dir = v9fs_do_opendir(s, &vs->fidp->path);
- v9fs_open_post_opendir(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_open_do_opendir, &vs->post_fn,
+ v9fs_open_post_opendir);
} else {
if (s->proto_version == V9FS_PROTO_2000L) {
flags = vs->mode;
@@ -1859,12 +1900,12 @@ static void v9fs_open_post_lstat(V9fsState *s, V9fsOpenState *vs, int err)
} else {
flags = omode_to_uflags(vs->mode);
}
- vs->fidp->fs.fd = v9fs_do_open(s, &vs->fidp->path, flags);
- v9fs_open_post_open(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_open_do_open, &vs->post_fn,
+ v9fs_open_post_open);
}
return;
out:
- complete_pdu(s, vs->pdu, err);
+ complete_pdu(vs->s, vs->pdu, vs->err);
qemu_free(vs);
}
@@ -1872,12 +1913,12 @@ static void v9fs_open(V9fsState *s, V9fsPDU *pdu)
{
int32_t fid;
V9fsOpenState *vs;
- ssize_t err = 0;
vs = qemu_malloc(sizeof(*vs));
vs->pdu = pdu;
vs->offset = 7;
vs->mode = 0;
+ vs->s = s;
if (s->proto_version == V9FS_PROTO_2000L) {
pdu_unmarshal(vs->pdu, vs->offset, "dd", &fid, &vs->mode);
@@ -1887,18 +1928,17 @@ static void v9fs_open(V9fsState *s, V9fsPDU *pdu)
vs->fidp = lookup_fid(s, fid);
if (vs->fidp == NULL) {
- err = -ENOENT;
+ vs->err = -ENOENT;
goto out;
}
BUG_ON(vs->fidp->fid_type != P9_FID_NONE);
- err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-
- v9fs_open_post_lstat(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_open_do_lstat, &vs->post_fn,
+ v9fs_open_post_lstat);
return;
out:
- complete_pdu(s, pdu, err);
+ complete_pdu(vs->s, pdu, vs->err);
qemu_free(vs);
}
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index be87d5f..294de83 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -306,6 +306,11 @@ typedef struct V9fsOpenState {
V9fsQID qid;
struct stat stbuf;
int iounit;
+ V9fsState *s;
+ int err;
+ int v9fs_errno;
+ ThreadletWork work;
+ void (*post_fn)(void *arg);
} V9fsOpenState;
typedef struct V9fsReadState {
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 6/6] This patch converts v9fs_walk() to make use of the threadlets infrastructure.
2010-10-13 17:09 [Qemu-devel] [RFC PATCH 0/6] First Threading Model Arun R Bharadwaj
` (4 preceding siblings ...)
2010-10-13 17:10 ` [Qemu-devel] [PATCH 5/6] This patch converts v9fs_open() " Arun R Bharadwaj
@ 2010-10-13 17:10 ` Arun R Bharadwaj
5 siblings, 0 replies; 9+ messages in thread
From: Arun R Bharadwaj @ 2010-10-13 17:10 UTC (permalink / raw)
To: qemu-devel
From: Gautham R Shenoy <ego@in.ibm.com>
This patch offloads all the blocking calls invoked for v9fs_walk onto the
helper threads belonging to the threadlets infrastructure. The handling of
the v9fs_post_*walk* calls is done from the io-thread context.
Signed-off-by: Gautham R Shenoy <ego@in.ibm.com>
---
hw/virtio-9p.c | 78 +++++++++++++++++++++++++++++++++++++-------------------
hw/virtio-9p.h | 5 ++++
2 files changed, 57 insertions(+), 26 deletions(-)
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 75d4be3..e95bf50 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -1615,6 +1615,29 @@ out:
qemu_free(vs);
}
+/************************* v9fs_walk calls *****************************/
+static void v9fs_walk_do_lstat_old(ThreadletWork *work)
+{
+ V9fsWalkState *vs;
+
+ vs = container_of(work, V9fsWalkState, work);
+ vs->err = v9fs_do_lstat(vs->s, &vs->fidp->path, &vs->stbuf);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
+static void v9fs_walk_do_lstat_new(ThreadletWork *work)
+{
+ V9fsWalkState *vs;
+
+ vs = container_of(work, V9fsWalkState, work);
+ vs->err = v9fs_do_lstat(vs->s, &vs->newfidp->path, &vs->stbuf);
+ vs->v9fs_errno = errno;
+
+ v9fs_async_helper_done(vs->post_fn, vs);
+}
+
static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
{
complete_pdu(s, vs->pdu, err);
@@ -1640,13 +1663,14 @@ static void v9fs_walk_marshal(V9fsWalkState *vs)
}
}
-static void v9fs_walk_post_newfid_lstat(V9fsState *s, V9fsWalkState *vs,
- int err)
+static void v9fs_walk_post_newfid_lstat(void *opaque)
{
- if (err == -1) {
- free_fid(s, vs->newfidp->fid);
+ V9fsWalkState *vs = (V9fsWalkState *)opaque;
+
+ if (vs->err == -1) {
+ free_fid(vs->s, vs->newfidp->fid);
v9fs_string_free(&vs->path);
- err = -ENOENT;
+ vs->err = -ENOENT;
goto out;
}
@@ -1658,24 +1682,25 @@ static void v9fs_walk_post_newfid_lstat(V9fsState *s, V9fsWalkState *vs,
vs->wnames[vs->name_idx].data);
v9fs_string_copy(&vs->newfidp->path, &vs->path);
- err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf);
- v9fs_walk_post_newfid_lstat(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_new, &vs->post_fn,
+ v9fs_walk_post_newfid_lstat);
return;
}
v9fs_string_free(&vs->path);
v9fs_walk_marshal(vs);
- err = vs->offset;
+ vs->err = vs->offset;
out:
- v9fs_walk_complete(s, vs, err);
+ v9fs_walk_complete(vs->s, vs, vs->err);
}
-static void v9fs_walk_post_oldfid_lstat(V9fsState *s, V9fsWalkState *vs,
- int err)
+static void v9fs_walk_post_oldfid_lstat(void *opaque)
{
- if (err == -1) {
+ V9fsWalkState *vs = (V9fsWalkState *)opaque;
+
+ if (vs->err == -1) {
v9fs_string_free(&vs->path);
- err = -ENOENT;
+ vs->err = -ENOENT;
goto out;
}
@@ -1687,23 +1712,22 @@ static void v9fs_walk_post_oldfid_lstat(V9fsState *s, V9fsWalkState *vs,
vs->fidp->path.data, vs->wnames[vs->name_idx].data);
v9fs_string_copy(&vs->fidp->path, &vs->path);
- err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
- v9fs_walk_post_oldfid_lstat(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_old, &vs->post_fn,
+ v9fs_walk_post_oldfid_lstat);
return;
}
v9fs_string_free(&vs->path);
v9fs_walk_marshal(vs);
- err = vs->offset;
+ vs->err = vs->offset;
out:
- v9fs_walk_complete(s, vs, err);
+ v9fs_walk_complete(vs->s, vs, vs->err);
}
static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
{
int32_t fid, newfid;
V9fsWalkState *vs;
- int err = 0;
int i;
vs = qemu_malloc(sizeof(*vs));
@@ -1711,6 +1735,8 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
vs->wnames = NULL;
vs->qids = NULL;
vs->offset = 7;
+ vs->err = 0;
+ vs->s = s;
vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "ddw", &fid,
&newfid, &vs->nwnames);
@@ -1728,7 +1754,7 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
vs->fidp = lookup_fid(s, fid);
if (vs->fidp == NULL) {
- err = -ENOENT;
+ vs->err = -ENOENT;
goto out;
}
@@ -1744,14 +1770,14 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
vs->fidp->path.data, vs->wnames[vs->name_idx].data);
v9fs_string_copy(&vs->fidp->path, &vs->path);
- err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
- v9fs_walk_post_oldfid_lstat(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_old,
+ &vs->post_fn, v9fs_walk_post_oldfid_lstat);
return;
}
} else {
vs->newfidp = alloc_fid(s, newfid);
if (vs->newfidp == NULL) {
- err = -EINVAL;
+ vs->err = -EINVAL;
goto out;
}
@@ -1765,16 +1791,16 @@ static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
vs->wnames[vs->name_idx].data);
v9fs_string_copy(&vs->newfidp->path, &vs->path);
- err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf);
- v9fs_walk_post_newfid_lstat(s, vs, err);
+ v9fs_do_async_posix(&vs->work, v9fs_walk_do_lstat_new,
+ &vs->post_fn, v9fs_walk_post_newfid_lstat);
return;
}
}
v9fs_walk_marshal(vs);
- err = vs->offset;
+ vs->err = vs->offset;
out:
- v9fs_walk_complete(s, vs, err);
+ v9fs_walk_complete(s, vs, vs->err);
}
/********************* v9fs_open calls *********************************/
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 294de83..f88b5fc 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -296,6 +296,11 @@ typedef struct V9fsWalkState {
V9fsString path;
V9fsString *wnames;
struct stat stbuf;
+ V9fsState *s;
+ int err;
+ int v9fs_errno;
+ ThreadletWork work;
+ void (*post_fn)(void *arg);
} V9fsWalkState;
typedef struct V9fsOpenState {
^ permalink raw reply related [flat|nested] 9+ messages in thread