aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/9pfs/9p-local.c5
-rw-r--r--hw/9pfs/9p-posix-acl.c5
-rw-r--r--hw/9pfs/9p-proxy.c5
-rw-r--r--hw/9pfs/9p-synth.c5
-rw-r--r--hw/9pfs/9p-util.c5
-rw-r--r--hw/9pfs/9p-xattr-user.c5
-rw-r--r--hw/9pfs/9p-xattr.c5
-rw-r--r--hw/9pfs/9p.c142
-rw-r--r--hw/9pfs/9p.h2
-rw-r--r--hw/9pfs/codir.c5
-rw-r--r--hw/9pfs/cofile.c5
-rw-r--r--hw/9pfs/cofs.c5
-rw-r--r--hw/9pfs/coth.c5
-rw-r--r--hw/9pfs/coxattr.c5
-rw-r--r--hw/9pfs/virtio-9p-device.c5
-rw-r--r--hw/9pfs/xen-9p-backend.c5
16 files changed, 166 insertions, 48 deletions
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index af52c1daac..210d9e7705 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -10,6 +10,11 @@
* the COPYING file in the top-level directory.
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include "9p.h"
#include "9p-local.h"
diff --git a/hw/9pfs/9p-posix-acl.c b/hw/9pfs/9p-posix-acl.c
index bbf89064f7..eadae270dd 100644
--- a/hw/9pfs/9p-posix-acl.c
+++ b/hw/9pfs/9p-posix-acl.c
@@ -11,6 +11,11 @@
*
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include "qemu/xattr.h"
#include "9p.h"
diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c
index 4aa4e0a3ba..09bd9f1464 100644
--- a/hw/9pfs/9p-proxy.c
+++ b/hw/9pfs/9p-proxy.c
@@ -10,6 +10,11 @@
* the COPYING file in the top-level directory.
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include <sys/socket.h>
#include <sys/un.h>
diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c
index 473ef914b0..b38088e066 100644
--- a/hw/9pfs/9p-synth.c
+++ b/hw/9pfs/9p-synth.c
@@ -12,6 +12,11 @@
*
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include "9p.h"
#include "fsdev/qemu-fsdev.h"
diff --git a/hw/9pfs/9p-util.c b/hw/9pfs/9p-util.c
index 614b7fc34d..3221d9b498 100644
--- a/hw/9pfs/9p-util.c
+++ b/hw/9pfs/9p-util.c
@@ -10,6 +10,11 @@
* See the COPYING file in the top-level directory.
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include "qemu/xattr.h"
#include "9p-util.h"
diff --git a/hw/9pfs/9p-xattr-user.c b/hw/9pfs/9p-xattr-user.c
index 2c90817b75..f2ae9582e6 100644
--- a/hw/9pfs/9p-xattr-user.c
+++ b/hw/9pfs/9p-xattr-user.c
@@ -11,6 +11,11 @@
*
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include "9p.h"
#include "fsdev/file-op-9p.h"
diff --git a/hw/9pfs/9p-xattr.c b/hw/9pfs/9p-xattr.c
index c696d8f846..9ae69dd8db 100644
--- a/hw/9pfs/9p-xattr.c
+++ b/hw/9pfs/9p-xattr.c
@@ -11,6 +11,11 @@
*
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include "9p.h"
#include "fsdev/file-op-9p.h"
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 134806db52..2815257f42 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -11,6 +11,11 @@
*
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include <glib/gprintf.h>
#include "hw/virtio/virtio.h"
@@ -966,23 +971,6 @@ static int stat_to_qid(V9fsPDU *pdu, const struct stat *stbuf, V9fsQID *qidp)
return 0;
}
-static int coroutine_fn fid_to_qid(V9fsPDU *pdu, V9fsFidState *fidp,
- V9fsQID *qidp)
-{
- struct stat stbuf;
- int err;
-
- err = v9fs_co_lstat(pdu, &fidp->path, &stbuf);
- if (err < 0) {
- return err;
- }
- err = stat_to_qid(pdu, &stbuf, qidp);
- if (err < 0) {
- return err;
- }
- return 0;
-}
-
V9fsPDU *pdu_alloc(V9fsState *s)
{
V9fsPDU *pdu = NULL;
@@ -1395,6 +1383,7 @@ static void coroutine_fn v9fs_attach(void *opaque)
size_t offset = 7;
V9fsQID qid;
ssize_t err;
+ struct stat stbuf;
v9fs_string_init(&uname);
v9fs_string_init(&aname);
@@ -1417,7 +1406,13 @@ static void coroutine_fn v9fs_attach(void *opaque)
clunk_fid(s, fid);
goto out;
}
- err = fid_to_qid(pdu, fidp, &qid);
+ err = v9fs_co_lstat(pdu, &fidp->path, &stbuf);
+ if (err < 0) {
+ err = -EINVAL;
+ clunk_fid(s, fid);
+ goto out;
+ }
+ err = stat_to_qid(pdu, &stbuf, &qid);
if (err < 0) {
err = -EINVAL;
clunk_fid(s, fid);
@@ -1449,7 +1444,7 @@ static void coroutine_fn v9fs_attach(void *opaque)
}
err += offset;
- memcpy(&s->root_qid, &qid, sizeof(qid));
+ memcpy(&s->root_st, &stbuf, sizeof(stbuf));
trace_v9fs_attach_return(pdu->tag, pdu->id,
qid.type, qid.version, qid.path);
out:
@@ -1700,12 +1695,9 @@ static bool name_is_illegal(const char *name)
return !*name || strchr(name, '/') != NULL;
}
-static bool not_same_qid(const V9fsQID *qid1, const V9fsQID *qid2)
+static bool same_stat_id(const struct stat *a, const struct stat *b)
{
- return
- qid1->type != qid2->type ||
- qid1->version != qid2->version ||
- qid1->path != qid2->path;
+ return a->st_dev == b->st_dev && a->st_ino == b->st_ino;
}
static void coroutine_fn v9fs_walk(void *opaque)
@@ -1713,9 +1705,9 @@ static void coroutine_fn v9fs_walk(void *opaque)
int name_idx;
V9fsQID *qids = NULL;
int i, err = 0;
- V9fsPath dpath, path;
+ V9fsPath dpath, path, *pathes = NULL;
uint16_t nwnames;
- struct stat stbuf;
+ struct stat stbuf, fidst, *stbufs = NULL;
size_t offset = 7;
int32_t fid, newfid;
V9fsString *wnames = NULL;
@@ -1734,9 +1726,15 @@ static void coroutine_fn v9fs_walk(void *opaque)
trace_v9fs_walk(pdu->tag, pdu->id, fid, newfid, nwnames);
- if (nwnames && nwnames <= P9_MAXWELEM) {
+ if (nwnames > P9_MAXWELEM) {
+ err = -EINVAL;
+ goto out_nofid;
+ }
+ if (nwnames) {
wnames = g_new0(V9fsString, nwnames);
qids = g_new0(V9fsQID, nwnames);
+ stbufs = g_new0(struct stat, nwnames);
+ pathes = g_new0(V9fsPath, nwnames);
for (i = 0; i < nwnames; i++) {
err = pdu_unmarshal(pdu, offset, "s", &wnames[i]);
if (err < 0) {
@@ -1748,9 +1746,6 @@ static void coroutine_fn v9fs_walk(void *opaque)
}
offset += err;
}
- } else if (nwnames > P9_MAXWELEM) {
- err = -EINVAL;
- goto out_nofid;
}
fidp = get_fid(pdu, fid);
if (fidp == NULL) {
@@ -1760,35 +1755,85 @@ static void coroutine_fn v9fs_walk(void *opaque)
v9fs_path_init(&dpath);
v9fs_path_init(&path);
+ /*
+ * Both dpath and path initially point to fidp.
+ * Needed to handle request with nwnames == 0
+ */
+ v9fs_path_copy(&dpath, &fidp->path);
+ v9fs_path_copy(&path, &fidp->path);
- err = fid_to_qid(pdu, fidp, &qid);
+ /*
+ * To keep latency (i.e. overall execution time for processing this
+ * Twalk client request) as small as possible, run all the required fs
+ * driver code altogether inside the following block.
+ */
+ v9fs_co_run_in_worker({
+ if (v9fs_request_cancelled(pdu)) {
+ err = -EINTR;
+ break;
+ }
+ err = s->ops->lstat(&s->ctx, &dpath, &fidst);
+ if (err < 0) {
+ err = -errno;
+ break;
+ }
+ stbuf = fidst;
+ for (name_idx = 0; name_idx < nwnames; name_idx++) {
+ if (v9fs_request_cancelled(pdu)) {
+ err = -EINTR;
+ break;
+ }
+ if (!same_stat_id(&pdu->s->root_st, &stbuf) ||
+ strcmp("..", wnames[name_idx].data))
+ {
+ err = s->ops->name_to_path(&s->ctx, &dpath,
+ wnames[name_idx].data, &path);
+ if (err < 0) {
+ err = -errno;
+ break;
+ }
+ if (v9fs_request_cancelled(pdu)) {
+ err = -EINTR;
+ break;
+ }
+ err = s->ops->lstat(&s->ctx, &path, &stbuf);
+ if (err < 0) {
+ err = -errno;
+ break;
+ }
+ stbufs[name_idx] = stbuf;
+ v9fs_path_copy(&dpath, &path);
+ v9fs_path_copy(&pathes[name_idx], &path);
+ }
+ }
+ });
+ /*
+ * Handle all the rest of this Twalk request on main thread ...
+ */
if (err < 0) {
goto out;
}
- /*
- * Both dpath and path initially poin to fidp.
- * Needed to handle request with nwnames == 0
- */
+ err = stat_to_qid(pdu, &fidst, &qid);
+ if (err < 0) {
+ goto out;
+ }
+ stbuf = fidst;
+
+ /* reset dpath and path */
v9fs_path_copy(&dpath, &fidp->path);
v9fs_path_copy(&path, &fidp->path);
- for (name_idx = 0; name_idx < nwnames; name_idx++) {
- if (not_same_qid(&pdu->s->root_qid, &qid) ||
- strcmp("..", wnames[name_idx].data)) {
- err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data,
- &path);
- if (err < 0) {
- goto out;
- }
- err = v9fs_co_lstat(pdu, &path, &stbuf);
- if (err < 0) {
- goto out;
- }
+ for (name_idx = 0; name_idx < nwnames; name_idx++) {
+ if (!same_stat_id(&pdu->s->root_st, &stbuf) ||
+ strcmp("..", wnames[name_idx].data))
+ {
+ stbuf = stbufs[name_idx];
err = stat_to_qid(pdu, &stbuf, &qid);
if (err < 0) {
goto out;
}
+ v9fs_path_copy(&path, &pathes[name_idx]);
v9fs_path_copy(&dpath, &path);
}
memcpy(&qids[name_idx], &qid, sizeof(qid));
@@ -1824,9 +1869,12 @@ out_nofid:
if (nwnames && nwnames <= P9_MAXWELEM) {
for (name_idx = 0; name_idx < nwnames; name_idx++) {
v9fs_string_free(&wnames[name_idx]);
+ v9fs_path_free(&pathes[name_idx]);
}
g_free(wnames);
g_free(qids);
+ g_free(stbufs);
+ g_free(pathes);
}
}
diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
index 00381591ff..1567b67841 100644
--- a/hw/9pfs/9p.h
+++ b/hw/9pfs/9p.h
@@ -355,7 +355,7 @@ struct V9fsState {
int32_t root_fid;
Error *migration_blocker;
V9fsConf fsconf;
- V9fsQID root_qid;
+ struct stat root_st;
dev_t dev_id;
struct qht qpd_table;
struct qht qpp_table;
diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c
index 1f70a58df5..032cce04c4 100644
--- a/hw/9pfs/codir.c
+++ b/hw/9pfs/codir.c
@@ -11,6 +11,11 @@
*
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index 83bb6c14e0..20f93a90e7 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -11,6 +11,11 @@
*
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 0b321b456e..9d0adc2e78 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -11,6 +11,11 @@
*
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
diff --git a/hw/9pfs/coth.c b/hw/9pfs/coth.c
index 9778f24b00..2802d41cce 100644
--- a/hw/9pfs/coth.c
+++ b/hw/9pfs/coth.c
@@ -12,6 +12,11 @@
*
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include "block/thread-pool.h"
#include "qemu/coroutine.h"
diff --git a/hw/9pfs/coxattr.c b/hw/9pfs/coxattr.c
index 0e00ffaa0d..dbcd09e0fd 100644
--- a/hw/9pfs/coxattr.c
+++ b/hw/9pfs/coxattr.c
@@ -11,6 +11,11 @@
*
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 14371a78ef..54ee93b71f 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -11,6 +11,11 @@
*
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include "hw/virtio/virtio.h"
#include "qemu/sockets.h"
diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c
index a969fcc54c..65c4979c3c 100644
--- a/hw/9pfs/xen-9p-backend.c
+++ b/hw/9pfs/xen-9p-backend.c
@@ -8,6 +8,11 @@
*
*/
+/*
+ * Not so fast! You might want to read the 9p developer docs first:
+ * https://wiki.qemu.org/Documentation/9p
+ */
+
#include "qemu/osdep.h"
#include "hw/9pfs/9p.h"