Commit b1ba6810f1 for qemu.org

commit b1ba6810f10139f5346c8fe49102d534aa94ce88
Author: Christian Schoenebeck <qemu_oss@crudebyte.com>
Date:   Wed Oct 7 12:27:59 2026 +0200

    tests/9p-client: track the negotiated 9p version for session

    So far v9fs_tattach() always sent an implied Tversion request, which
    was supposed to be a convenient mechanisms such that not every test
    case code would need to call v9fs_tversion() prior to a
    v9fs_tattach(). The problem however is that this implicit Tversion
    defaults to 9p2000.L, and it would also be (re)sent if an explicit
    v9fs_tversion() call had been issued with 9p2000.u before, which then
    would reset the session to the unintended 9p2000.L protocol version.

    Fix this by storing the initial Tversion request's (desired) protocol
    version to the client object. And only issue the implicit Tversion
    request inside of v9fs_tattach() if no protocol version had been
    negotiated already.

    This is a preparatory patch for the subsequently added race test,
    which negotiates a 9p2000.u session.

    It also allows request / response handling to later become more
    protocol dialect aware (e.g. expecting specific request / response
    types according to negotiated protocol version during a session).

    Link: https://lore.kernel.org/qemu-devel/419b2b047c0f61b9e4a7e58f117c03ec6feea1ea.1791368962.git.qemu_oss@crudebyte.com
    Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>

diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c
index ce67a4b8c5..20c7af91bd 100644
--- a/tests/qtest/libqos/virtio-9p-client.c
+++ b/tests/qtest/libqos/virtio-9p-client.c
@@ -366,6 +366,15 @@ TVersionRes v9fs_tversion(TVersionOpt opt)
     v9fs_string_write(req, opt.version);
     v9fs_req_send(req);

+    /* store session's protocol version to client object */
+    if (!strcmp(opt.version, "9P2000.u")) {
+        opt.client->proto_version = V9FS_PROTO_2000U;
+    } else if (!strcmp(opt.version, "9P2000.L")) {
+        opt.client->proto_version = V9FS_PROTO_2000L;
+    } else {
+        g_assert_not_reached();
+    }
+
     if (!opt.requestOnly) {
         v9fs_req_wait_for_reply(req, NULL);
         if (opt.expectErr) {
@@ -412,7 +421,11 @@ TAttachRes v9fs_tattach(TAttachOpt opt)
     /* expecting either Rattach or Rlerror, but obviously not both */
     g_assert(!opt.expectErr || !opt.rattach.qid);

-    if (!opt.requestOnly) {
+    /*
+     * convenience feature: send an implicit Tversion request, however only if
+     * Tversion has not been issued for this session before.
+     */
+    if (!opt.requestOnly && opt.client->proto_version == 0) {
         v9fs_tversion((TVersionOpt) { .client = opt.client });
     }

diff --git a/tests/qtest/libqos/virtio-9p.h b/tests/qtest/libqos/virtio-9p.h
index e7efeef7a1..db21c5059c 100644
--- a/tests/qtest/libqos/virtio-9p.h
+++ b/tests/qtest/libqos/virtio-9p.h
@@ -22,6 +22,7 @@
 #include "qgraph.h"
 #include "virtio.h"
 #include "virtio-pci.h"
+#include "hw/9pfs/9p.h"

 typedef struct QVirtio9P QVirtio9P;
 typedef struct QVirtio9PPCI QVirtio9PPCI;
@@ -32,6 +33,11 @@ typedef struct QVirtio9PDevice QVirtio9PDevice;
 struct QVirtio9P {
     QVirtioDevice *vdev;
     QVirtQueue *vq;
+    /*
+     * The protocol version negotiated for this 9p session via Tversion request
+     * (0 if no protocol version negotiated yet)
+     */
+    P9ProtoVersion proto_version;
 };

 struct QVirtio9PPCI {