qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 6/7] tests: virtio-9p: add LCREATE operation test


From: Greg Kurz
Subject: [Qemu-devel] [PATCH 6/7] tests: virtio-9p: add LCREATE operation test
Date: Tue, 10 Jan 2017 15:32:46 +0100
User-agent: StGit/0.17.1-20-gc0b1b-dirty

The "fs_lcreate" test clones the root directory fid, walks to it and
issues a LCREATE operation, which is expected to succeed. It then
ensures a file was indeed created in the underlying filesystem.
Note that LCREATE is the CREATE operation implemented by the 9P2000.L
version of the 9P protocol, which is used by the linux kernel client.

References:

https://github.com/chaos/diod/blob/master/protocol.md#lcreate----create-regular-file
http://man.cat-v.org/plan_9/5/open

Signed-off-by: Greg Kurz <address@hidden>
---
 tests/virtio-9p-test.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c
index 334833f88a6e..7f2ee41ca0f0 100644
--- a/tests/virtio-9p-test.c
+++ b/tests/virtio-9p-test.c
@@ -244,6 +244,7 @@ static const char *rmessage_name(uint8_t id)
         id == P9_RATTACH ? "RATTACH" :
         id == P9_RWALK ? "RWALK" :
         id == P9_RLOPEN ? "RLOPEN" :
+        id == P9_RLCREATE ? "RLCREATE" :
         "<unknown>";
 }
 
@@ -423,6 +424,38 @@ static void v9fs_rlopen(P9Req *req, v9fs_qid *qid, 
uint32_t *iounit)
     v9fs_req_free(req);
 }
 
+/* size[4] Tlcreate tag[2] fid[4] name[s] flags[4] mode[4] gid[4] */
+static P9Req *v9fs_tlcreate(QVirtIO9P *v9p, uint32_t fid, const char *name,
+                            uint32_t flags, uint32_t mode, uint32_t gid)
+{
+    P9Req *req;
+
+    req = v9fs_req_init(v9p,  4 + 4 + v9fs_string_size(name) + 4 + 4 + 4,
+                        P9_TLCREATE, ++(v9p->p9_req_tag));
+    v9fs_uint32_write(req, fid);
+    v9fs_string_write(req, name);
+    v9fs_uint32_write(req, flags);
+    v9fs_uint32_write(req, mode);
+    v9fs_uint32_write(req, gid);
+    v9fs_req_send(req);
+    return req;
+}
+
+/* size[4] Rlcreate tag[2] qid[13] iounit[4] */
+static void v9fs_rlcreate(P9Req *req, v9fs_qid *qid, uint32_t *iounit)
+{
+    v9fs_req_recv(req, P9_RLCREATE);
+    if (qid) {
+        v9fs_memread(req, qid, 13);
+    } else {
+        v9fs_memskip(req, 13);
+    }
+    if (iounit) {
+        v9fs_uint32_read(req, iounit);
+    }
+    v9fs_req_free(req);
+}
+
 static void fs_version(QVirtIO9P *v9p)
 {
     const char *version = "9P2000.L";
@@ -560,6 +593,34 @@ static void fs_lopen_fifo_not_allowed(QVirtIO9P *v9p)
     g_free(wnames[0]);
 }
 
+static void fs_lcreate(QVirtIO9P *v9p)
+{
+    char *const wnames[] = { g_strdup(__func__) };
+    char *path = g_strdup_printf("%s/%s", v9p->test_share, wnames[0]);
+    uint32_t iounit;
+    P9Req *req;
+
+    fs_attach(v9p);
+    /* Clone the root directory fid and open it */
+    req = v9fs_twalk(v9p, 0, 1, 0, NULL);
+    v9fs_rwalk(req, NULL, NULL);
+    req = v9fs_tlopen(v9p, 1, O_RDWR);
+    v9fs_rlopen(req, NULL, NULL);
+
+    req = v9fs_tlcreate(v9p, 1, wnames[0], O_RDONLY, 0600, getgid());
+    v9fs_rlcreate(req, NULL, &iounit);
+
+    g_assert_cmpint(iounit, <=, P9_MAX_SIZE - P9_IOHDRSZ);
+
+    /* Was the file created ? */
+    req = v9fs_twalk(v9p, 0, 2, 1, wnames);
+    v9fs_rwalk(req, NULL, NULL);
+
+    unlink(path);
+    g_free(path);
+    g_free(wnames[0]);
+}
+
 typedef void (*v9fs_test_fn)(QVirtIO9P *v9p);
 
 static void v9fs_run_pci_test(gconstpointer data)
@@ -592,6 +653,7 @@ int main(int argc, char **argv)
     v9fs_qtest_pci_add("/virtio/9p/pci/fs/lopen/basic", fs_lopen);
     v9fs_qtest_pci_add("/virtio/9p/pci/fs/lopen/fifo_not_allowed",
                        fs_lopen_fifo_not_allowed);
+    v9fs_qtest_pci_add("/virtio/9p/pci/fs/lcreate/basic", fs_lcreate);
 
     return g_test_run();
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]