aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-07-05 17:25:02 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-07-05 17:25:02 +0100
commit9bef7ea9d93ee6b6297a5be6cb5a557f7d1764c9 (patch)
tree0487aa4c5694180a48d6aa12364e3f277405f538 /hw
parent715167a36c2b152f6511cff690180c1254ae039f (diff)
parent8d6cb100731c4d28535adbf2a3c2d1f29be3fef4 (diff)
downloadqemu-9bef7ea9d93ee6b6297a5be6cb5a557f7d1764c9.zip
qemu-9bef7ea9d93ee6b6297a5be6cb5a557f7d1764c9.tar.gz
qemu-9bef7ea9d93ee6b6297a5be6cb5a557f7d1764c9.tar.bz2
Merge remote-tracking branch 'remotes/cschoenebeck/tags/pull-9p-20210705' into staging
9pfs: misc patches * Add link to 9p developer docs. * Fix runtime check whether client supplied relative path is the export root. * Performance optimization of Twalk requests. * Code cleanup. # gpg: Signature made Mon 05 Jul 2021 12:13:34 BST # gpg: using RSA key 96D8D110CF7AF8084F88590134C2B58765A47395 # gpg: issuer "qemu_oss@crudebyte.com" # gpg: Good signature from "Christian Schoenebeck <qemu_oss@crudebyte.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: ECAB 1A45 4014 1413 BA38 4926 30DB 47C3 A012 D5F4 # Subkey fingerprint: 96D8 D110 CF7A F808 4F88 5901 34C2 B587 65A4 7395 * remotes/cschoenebeck/tags/pull-9p-20210705: 9pfs: reduce latency of Twalk 9pfs: drop root_qid 9pfs: replace not_same_qid() by same_stat_id() 9pfs: drop fid_to_qid() 9pfs: capture root stat 9pfs: fix not_same_qid() 9pfs: simplify v9fs_walk() 9pfs: add link to 9p developer docs Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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 af52c1d..210d9e7 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 bbf8906..eadae27 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 4aa4e0a..09bd9f1 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 473ef91..b38088e 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 614b7fc..3221d9b 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 2c90817..f2ae958 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 c696d8f..9ae69dd 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 134806d..2815257 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 0038159..1567b67 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 1f70a58..032cce0 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 83bb6c1..20f93a9 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 0b321b4..9d0adc2 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 9778f24..2802d41 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 0e00ffa..dbcd09e 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 14371a7..54ee93b 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 a969fcc..65c4979 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"