aboutsummaryrefslogtreecommitdiff
path: root/hw/9pfs/9p.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-02-02 16:26:41 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-02-02 16:26:41 +0000
commitf74425e267f81f0f94adf47ecbd66224e0461936 (patch)
treeb73f3aed99966e35fac6a38126bc79882c69b396 /hw/9pfs/9p.c
parentfabbd691fd7db2e71c6702089c9656e7047eac24 (diff)
parent9ea776ee7d4061c043d0fbf89aa85f86ec0cf8a2 (diff)
downloadqemu-f74425e267f81f0f94adf47ecbd66224e0461936.zip
qemu-f74425e267f81f0f94adf47ecbd66224e0461936.tar.gz
qemu-f74425e267f81f0f94adf47ecbd66224e0461936.tar.bz2
Merge remote-tracking branch 'remotes/gkurz/tags/for-upstream' into staging
This series is mostly about 9p request cancellation. It fixes a long standing bug (read "specification violation") where the server would send an invalid response when the client has cancelled an in-flight request. This was causing annoying spurious EINTR returns in linux. The fix comes with some related testing in QTEST. Other patches are code cleanup and improvements. # gpg: Signature made Fri 02 Feb 2018 10:16:03 GMT # gpg: using RSA key 71D4D5E5822F73D6 # gpg: Good signature from "Greg Kurz <groug@kaod.org>" # gpg: aka "Gregory Kurz <gregory.kurz@free.fr>" # gpg: aka "[jpeg image of size 3330]" # Primary key fingerprint: B482 8BAF 9431 40CE F2A3 4910 71D4 D5E5 822F 73D6 * remotes/gkurz/tags/for-upstream: tests/virtio-9p: explicitly handle potential integer overflows tests: virtio-9p: add FLUSH operation test libqos/virtio: return length written into used descriptor tests: virtio-9p: add WRITE operation test tests: virtio-9p: add LOPEN operation test tests: virtio-9p: use the synth backend tests: virtio-9p: wait for completion in the test code tests: virtio-9p: move request tag to the test functions 9pfs: Correctly handle cancelled requests 9pfs: drop v9fs_register_transport() Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/9pfs/9p.c')
-rw-r--r--hw/9pfs/9p.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 909a611..85a1ed8 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -24,6 +24,7 @@
#include "coth.h"
#include "trace.h"
#include "migration/blocker.h"
+#include "sysemu/qtest.h"
int open_fd_hw;
int total_open_fd;
@@ -630,6 +631,24 @@ static void coroutine_fn pdu_complete(V9fsPDU *pdu, ssize_t len)
V9fsState *s = pdu->s;
int ret;
+ /*
+ * The 9p spec requires that successfully cancelled pdus receive no reply.
+ * Sending a reply would confuse clients because they would
+ * assume that any EINTR is the actual result of the operation,
+ * rather than a consequence of the cancellation. However, if
+ * the operation completed (succesfully or with an error other
+ * than caused be cancellation), we do send out that reply, both
+ * for efficiency and to avoid confusing the rest of the state machine
+ * that assumes passing a non-error here will mean a successful
+ * transmission of the reply.
+ */
+ bool discard = pdu->cancelled && len == -EINTR;
+ if (discard) {
+ trace_v9fs_rcancel(pdu->tag, pdu->id);
+ pdu->size = 0;
+ goto out_notify;
+ }
+
if (len < 0) {
int err = -len;
len = 7;
@@ -3485,7 +3504,8 @@ void pdu_submit(V9fsPDU *pdu, P9MsgHeader *hdr)
}
/* Returns 0 on success, 1 on failure. */
-int v9fs_device_realize_common(V9fsState *s, Error **errp)
+int v9fs_device_realize_common(V9fsState *s, const V9fsTransport *t,
+ Error **errp)
{
int i, len;
struct stat stat;
@@ -3493,6 +3513,9 @@ int v9fs_device_realize_common(V9fsState *s, Error **errp)
V9fsPath path;
int rc = 1;
+ assert(!s->transport);
+ s->transport = t;
+
/* initialize pdu allocator */
QLIST_INIT(&s->free_list);
QLIST_INIT(&s->active_list);