xref: /qemu/tests/qtest/libqos/virtio-9p-client.h (revision 43e0d9fb)
1684f9120SChristian Schoenebeck /*
2684f9120SChristian Schoenebeck  * 9P network client for VirtIO 9P test cases (based on QTest)
3684f9120SChristian Schoenebeck  *
4684f9120SChristian Schoenebeck  * Copyright (c) 2014 SUSE LINUX Products GmbH
5684f9120SChristian Schoenebeck  *
6684f9120SChristian Schoenebeck  * This work is licensed under the terms of the GNU GPL, version 2 or later.
7684f9120SChristian Schoenebeck  * See the COPYING file in the top-level directory.
8684f9120SChristian Schoenebeck  */
9684f9120SChristian Schoenebeck 
10684f9120SChristian Schoenebeck /*
11684f9120SChristian Schoenebeck  * Not so fast! You might want to read the 9p developer docs first:
12684f9120SChristian Schoenebeck  * https://wiki.qemu.org/Documentation/9p
13684f9120SChristian Schoenebeck  */
14684f9120SChristian Schoenebeck 
15684f9120SChristian Schoenebeck #ifndef TESTS_LIBQOS_VIRTIO_9P_CLIENT_H
16684f9120SChristian Schoenebeck #define TESTS_LIBQOS_VIRTIO_9P_CLIENT_H
17684f9120SChristian Schoenebeck 
18684f9120SChristian Schoenebeck #include "hw/9pfs/9p.h"
19684f9120SChristian Schoenebeck #include "hw/9pfs/9p-synth.h"
20684f9120SChristian Schoenebeck #include "virtio-9p.h"
21684f9120SChristian Schoenebeck #include "qgraph.h"
22684f9120SChristian Schoenebeck #include "tests/qtest/libqtest-single.h"
23684f9120SChristian Schoenebeck 
24684f9120SChristian Schoenebeck #define P9_MAX_SIZE 4096 /* Max size of a T-message or R-message */
25684f9120SChristian Schoenebeck 
26684f9120SChristian Schoenebeck typedef struct {
27684f9120SChristian Schoenebeck     QTestState *qts;
28684f9120SChristian Schoenebeck     QVirtio9P *v9p;
29684f9120SChristian Schoenebeck     uint16_t tag;
30684f9120SChristian Schoenebeck     uint64_t t_msg;
31684f9120SChristian Schoenebeck     uint32_t t_size;
32684f9120SChristian Schoenebeck     uint64_t r_msg;
33684f9120SChristian Schoenebeck     /* No r_size, it is hardcoded to P9_MAX_SIZE */
34684f9120SChristian Schoenebeck     size_t t_off;
35684f9120SChristian Schoenebeck     size_t r_off;
36684f9120SChristian Schoenebeck     uint32_t free_head;
37684f9120SChristian Schoenebeck } P9Req;
38684f9120SChristian Schoenebeck 
39684f9120SChristian Schoenebeck /* type[1] version[4] path[8] */
40684f9120SChristian Schoenebeck typedef char v9fs_qid[13];
41684f9120SChristian Schoenebeck 
42684f9120SChristian Schoenebeck typedef struct v9fs_attr {
43684f9120SChristian Schoenebeck     uint64_t valid;
44684f9120SChristian Schoenebeck     v9fs_qid qid;
45684f9120SChristian Schoenebeck     uint32_t mode;
46684f9120SChristian Schoenebeck     uint32_t uid;
47684f9120SChristian Schoenebeck     uint32_t gid;
48684f9120SChristian Schoenebeck     uint64_t nlink;
49684f9120SChristian Schoenebeck     uint64_t rdev;
50684f9120SChristian Schoenebeck     uint64_t size;
51684f9120SChristian Schoenebeck     uint64_t blksize;
52684f9120SChristian Schoenebeck     uint64_t blocks;
53684f9120SChristian Schoenebeck     uint64_t atime_sec;
54684f9120SChristian Schoenebeck     uint64_t atime_nsec;
55684f9120SChristian Schoenebeck     uint64_t mtime_sec;
56684f9120SChristian Schoenebeck     uint64_t mtime_nsec;
57684f9120SChristian Schoenebeck     uint64_t ctime_sec;
58684f9120SChristian Schoenebeck     uint64_t ctime_nsec;
59684f9120SChristian Schoenebeck     uint64_t btime_sec;
60684f9120SChristian Schoenebeck     uint64_t btime_nsec;
61684f9120SChristian Schoenebeck     uint64_t gen;
62684f9120SChristian Schoenebeck     uint64_t data_version;
63684f9120SChristian Schoenebeck } v9fs_attr;
64684f9120SChristian Schoenebeck 
65684f9120SChristian Schoenebeck #define P9_GETATTR_BASIC    0x000007ffULL /* Mask for fields up to BLOCKS */
662af5be47SChristian Schoenebeck #define P9_GETATTR_ALL      0x00003fffULL /* Mask for ALL fields */
67684f9120SChristian Schoenebeck 
68684f9120SChristian Schoenebeck struct V9fsDirent {
69684f9120SChristian Schoenebeck     v9fs_qid qid;
70684f9120SChristian Schoenebeck     uint64_t offset;
71684f9120SChristian Schoenebeck     uint8_t type;
72684f9120SChristian Schoenebeck     char *name;
73684f9120SChristian Schoenebeck     struct V9fsDirent *next;
74684f9120SChristian Schoenebeck };
75684f9120SChristian Schoenebeck 
76569f3b63SChristian Schoenebeck /* options for 'Twalk' 9p request */
77569f3b63SChristian Schoenebeck typedef struct TWalkOpt {
78569f3b63SChristian Schoenebeck     /* 9P client being used (mandatory) */
79569f3b63SChristian Schoenebeck     QVirtio9P *client;
80569f3b63SChristian Schoenebeck     /* user supplied tag number being returned with response (optional) */
81569f3b63SChristian Schoenebeck     uint16_t tag;
82569f3b63SChristian Schoenebeck     /* file ID of directory from where walk should start (optional) */
83569f3b63SChristian Schoenebeck     uint32_t fid;
84569f3b63SChristian Schoenebeck     /* file ID for target directory being walked to (optional) */
85569f3b63SChristian Schoenebeck     uint32_t newfid;
86569f3b63SChristian Schoenebeck     /* low level variant of path to walk to (optional) */
87569f3b63SChristian Schoenebeck     uint16_t nwname;
88569f3b63SChristian Schoenebeck     char **wnames;
89569f3b63SChristian Schoenebeck     /* high level variant of path to walk to (optional) */
90569f3b63SChristian Schoenebeck     const char *path;
91569f3b63SChristian Schoenebeck     /* data being received from 9p server as 'Rwalk' response (optional) */
92569f3b63SChristian Schoenebeck     struct {
93569f3b63SChristian Schoenebeck         uint16_t *nwqid;
94569f3b63SChristian Schoenebeck         v9fs_qid **wqid;
95569f3b63SChristian Schoenebeck     } rwalk;
96569f3b63SChristian Schoenebeck     /* only send Twalk request but not wait for a reply? (optional) */
97569f3b63SChristian Schoenebeck     bool requestOnly;
98569f3b63SChristian Schoenebeck     /* do we expect an Rlerror response, if yes which error code? (optional) */
99569f3b63SChristian Schoenebeck     uint32_t expectErr;
100569f3b63SChristian Schoenebeck } TWalkOpt;
101569f3b63SChristian Schoenebeck 
102569f3b63SChristian Schoenebeck /* result of 'Twalk' 9p request */
103569f3b63SChristian Schoenebeck typedef struct TWalkRes {
104569f3b63SChristian Schoenebeck     /* file ID of target directory been walked to */
105569f3b63SChristian Schoenebeck     uint32_t newfid;
106569f3b63SChristian Schoenebeck     /* if requestOnly was set: request object for further processing */
107569f3b63SChristian Schoenebeck     P9Req *req;
108569f3b63SChristian Schoenebeck } TWalkRes;
109569f3b63SChristian Schoenebeck 
110bee8fda2SChristian Schoenebeck /* options for 'Tversion' 9p request */
111bee8fda2SChristian Schoenebeck typedef struct TVersionOpt {
112bee8fda2SChristian Schoenebeck     /* 9P client being used (mandatory) */
113bee8fda2SChristian Schoenebeck     QVirtio9P *client;
114bee8fda2SChristian Schoenebeck     /* user supplied tag number being returned with response (optional) */
115bee8fda2SChristian Schoenebeck     uint16_t tag;
116bee8fda2SChristian Schoenebeck     /* maximum message size that can be handled by client (optional) */
117bee8fda2SChristian Schoenebeck     uint32_t msize;
118bee8fda2SChristian Schoenebeck     /* protocol version (optional) */
119bee8fda2SChristian Schoenebeck     const char *version;
120bee8fda2SChristian Schoenebeck     /* only send Tversion request but not wait for a reply? (optional) */
121bee8fda2SChristian Schoenebeck     bool requestOnly;
122bee8fda2SChristian Schoenebeck     /* do we expect an Rlerror response, if yes which error code? (optional) */
123bee8fda2SChristian Schoenebeck     uint32_t expectErr;
124bee8fda2SChristian Schoenebeck } TVersionOpt;
125bee8fda2SChristian Schoenebeck 
126bee8fda2SChristian Schoenebeck /* result of 'Tversion' 9p request */
127bee8fda2SChristian Schoenebeck typedef struct TVersionRes {
128bee8fda2SChristian Schoenebeck     /* if requestOnly was set: request object for further processing */
129bee8fda2SChristian Schoenebeck     P9Req *req;
130bee8fda2SChristian Schoenebeck } TVersionRes;
131bee8fda2SChristian Schoenebeck 
13274a160abSChristian Schoenebeck /* options for 'Tattach' 9p request */
13374a160abSChristian Schoenebeck typedef struct TAttachOpt {
13474a160abSChristian Schoenebeck     /* 9P client being used (mandatory) */
13574a160abSChristian Schoenebeck     QVirtio9P *client;
13674a160abSChristian Schoenebeck     /* user supplied tag number being returned with response (optional) */
13774a160abSChristian Schoenebeck     uint16_t tag;
13874a160abSChristian Schoenebeck     /* file ID to be associated with root of file tree (optional) */
13974a160abSChristian Schoenebeck     uint32_t fid;
14074a160abSChristian Schoenebeck     /* numerical uid of user being introduced to server (optional) */
14174a160abSChristian Schoenebeck     uint32_t n_uname;
14274a160abSChristian Schoenebeck     /* data being received from 9p server as 'Rattach' response (optional) */
14374a160abSChristian Schoenebeck     struct {
14474a160abSChristian Schoenebeck         /* server's idea of the root of the file tree */
14574a160abSChristian Schoenebeck         v9fs_qid *qid;
14674a160abSChristian Schoenebeck     } rattach;
14774a160abSChristian Schoenebeck     /* only send Tattach request but not wait for a reply? (optional) */
14874a160abSChristian Schoenebeck     bool requestOnly;
14974a160abSChristian Schoenebeck     /* do we expect an Rlerror response, if yes which error code? (optional) */
15074a160abSChristian Schoenebeck     uint32_t expectErr;
15174a160abSChristian Schoenebeck } TAttachOpt;
15274a160abSChristian Schoenebeck 
15374a160abSChristian Schoenebeck /* result of 'Tattach' 9p request */
15474a160abSChristian Schoenebeck typedef struct TAttachRes {
15574a160abSChristian Schoenebeck     /* if requestOnly was set: request object for further processing */
15674a160abSChristian Schoenebeck     P9Req *req;
15774a160abSChristian Schoenebeck } TAttachRes;
15874a160abSChristian Schoenebeck 
1592af5be47SChristian Schoenebeck /* options for 'Tgetattr' 9p request */
1602af5be47SChristian Schoenebeck typedef struct TGetAttrOpt {
1612af5be47SChristian Schoenebeck     /* 9P client being used (mandatory) */
1622af5be47SChristian Schoenebeck     QVirtio9P *client;
1632af5be47SChristian Schoenebeck     /* user supplied tag number being returned with response (optional) */
1642af5be47SChristian Schoenebeck     uint16_t tag;
1652af5be47SChristian Schoenebeck     /* file ID of file/dir whose attributes shall be retrieved (required) */
1662af5be47SChristian Schoenebeck     uint32_t fid;
1672af5be47SChristian Schoenebeck     /* bitmask indicating attribute fields to be retrieved (optional) */
1682af5be47SChristian Schoenebeck     uint64_t request_mask;
1692af5be47SChristian Schoenebeck     /* data being received from 9p server as 'Rgetattr' response (optional) */
1702af5be47SChristian Schoenebeck     struct {
1712af5be47SChristian Schoenebeck         v9fs_attr *attr;
1722af5be47SChristian Schoenebeck     } rgetattr;
1732af5be47SChristian Schoenebeck     /* only send Tgetattr request but not wait for a reply? (optional) */
1742af5be47SChristian Schoenebeck     bool requestOnly;
1752af5be47SChristian Schoenebeck     /* do we expect an Rlerror response, if yes which error code? (optional) */
1762af5be47SChristian Schoenebeck     uint32_t expectErr;
1772af5be47SChristian Schoenebeck } TGetAttrOpt;
1782af5be47SChristian Schoenebeck 
1792af5be47SChristian Schoenebeck /* result of 'Tgetattr' 9p request */
1802af5be47SChristian Schoenebeck typedef struct TGetAttrRes {
1812af5be47SChristian Schoenebeck     /* if requestOnly was set: request object for further processing */
1822af5be47SChristian Schoenebeck     P9Req *req;
1832af5be47SChristian Schoenebeck } TGetAttrRes;
1842af5be47SChristian Schoenebeck 
1851ebacc40SChristian Schoenebeck /* options for 'Treaddir' 9p request */
1861ebacc40SChristian Schoenebeck typedef struct TReadDirOpt {
1871ebacc40SChristian Schoenebeck     /* 9P client being used (mandatory) */
1881ebacc40SChristian Schoenebeck     QVirtio9P *client;
1891ebacc40SChristian Schoenebeck     /* user supplied tag number being returned with response (optional) */
1901ebacc40SChristian Schoenebeck     uint16_t tag;
1911ebacc40SChristian Schoenebeck     /* file ID of directory whose entries shall be retrieved (required) */
1921ebacc40SChristian Schoenebeck     uint32_t fid;
1931ebacc40SChristian Schoenebeck     /* offset in entries stream, i.e. for multiple requests (optional) */
1941ebacc40SChristian Schoenebeck     uint64_t offset;
1951ebacc40SChristian Schoenebeck     /* maximum bytes to be returned by server (required) */
1961ebacc40SChristian Schoenebeck     uint32_t count;
1971ebacc40SChristian Schoenebeck     /* data being received from 9p server as 'Rreaddir' response (optional) */
1981ebacc40SChristian Schoenebeck     struct {
1991ebacc40SChristian Schoenebeck         uint32_t *count;
2001ebacc40SChristian Schoenebeck         uint32_t *nentries;
2011ebacc40SChristian Schoenebeck         struct V9fsDirent **entries;
2021ebacc40SChristian Schoenebeck     } rreaddir;
2031ebacc40SChristian Schoenebeck     /* only send Treaddir request but not wait for a reply? (optional) */
2041ebacc40SChristian Schoenebeck     bool requestOnly;
2051ebacc40SChristian Schoenebeck     /* do we expect an Rlerror response, if yes which error code? (optional) */
2061ebacc40SChristian Schoenebeck     uint32_t expectErr;
2071ebacc40SChristian Schoenebeck } TReadDirOpt;
2081ebacc40SChristian Schoenebeck 
2091ebacc40SChristian Schoenebeck /* result of 'Treaddir' 9p request */
2101ebacc40SChristian Schoenebeck typedef struct TReadDirRes {
2111ebacc40SChristian Schoenebeck     /* if requestOnly was set: request object for further processing */
2121ebacc40SChristian Schoenebeck     P9Req *req;
2131ebacc40SChristian Schoenebeck } TReadDirRes;
2141ebacc40SChristian Schoenebeck 
2153878ce4cSChristian Schoenebeck /* options for 'Tlopen' 9p request */
2163878ce4cSChristian Schoenebeck typedef struct TLOpenOpt {
2173878ce4cSChristian Schoenebeck     /* 9P client being used (mandatory) */
2183878ce4cSChristian Schoenebeck     QVirtio9P *client;
2193878ce4cSChristian Schoenebeck     /* user supplied tag number being returned with response (optional) */
2203878ce4cSChristian Schoenebeck     uint16_t tag;
2213878ce4cSChristian Schoenebeck     /* file ID of file / directory to be opened (required) */
2223878ce4cSChristian Schoenebeck     uint32_t fid;
2233878ce4cSChristian Schoenebeck     /* Linux open(2) flags such as O_RDONLY, O_RDWR, O_WRONLY (optional) */
2243878ce4cSChristian Schoenebeck     uint32_t flags;
2253878ce4cSChristian Schoenebeck     /* data being received from 9p server as 'Rlopen' response (optional) */
2263878ce4cSChristian Schoenebeck     struct {
2273878ce4cSChristian Schoenebeck         v9fs_qid *qid;
2283878ce4cSChristian Schoenebeck         uint32_t *iounit;
2293878ce4cSChristian Schoenebeck     } rlopen;
2303878ce4cSChristian Schoenebeck     /* only send Tlopen request but not wait for a reply? (optional) */
2313878ce4cSChristian Schoenebeck     bool requestOnly;
2323878ce4cSChristian Schoenebeck     /* do we expect an Rlerror response, if yes which error code? (optional) */
2333878ce4cSChristian Schoenebeck     uint32_t expectErr;
2343878ce4cSChristian Schoenebeck } TLOpenOpt;
2353878ce4cSChristian Schoenebeck 
2363878ce4cSChristian Schoenebeck /* result of 'Tlopen' 9p request */
2373878ce4cSChristian Schoenebeck typedef struct TLOpenRes {
2383878ce4cSChristian Schoenebeck     /* if requestOnly was set: request object for further processing */
2393878ce4cSChristian Schoenebeck     P9Req *req;
2403878ce4cSChristian Schoenebeck } TLOpenRes;
2413878ce4cSChristian Schoenebeck 
242ac9e4e61SChristian Schoenebeck /* options for 'Twrite' 9p request */
243ac9e4e61SChristian Schoenebeck typedef struct TWriteOpt {
244ac9e4e61SChristian Schoenebeck     /* 9P client being used (mandatory) */
245ac9e4e61SChristian Schoenebeck     QVirtio9P *client;
246ac9e4e61SChristian Schoenebeck     /* user supplied tag number being returned with response (optional) */
247ac9e4e61SChristian Schoenebeck     uint16_t tag;
248ac9e4e61SChristian Schoenebeck     /* file ID of file to write to (required) */
249ac9e4e61SChristian Schoenebeck     uint32_t fid;
250ac9e4e61SChristian Schoenebeck     /* start position of write from beginning of file (optional) */
251ac9e4e61SChristian Schoenebeck     uint64_t offset;
252ac9e4e61SChristian Schoenebeck     /* how many bytes to write */
253ac9e4e61SChristian Schoenebeck     uint32_t count;
254ac9e4e61SChristian Schoenebeck     /* data to be written */
255ac9e4e61SChristian Schoenebeck     const void *data;
256ac9e4e61SChristian Schoenebeck     /* only send Twrite request but not wait for a reply? (optional) */
257ac9e4e61SChristian Schoenebeck     bool requestOnly;
258ac9e4e61SChristian Schoenebeck     /* do we expect an Rlerror response, if yes which error code? (optional) */
259ac9e4e61SChristian Schoenebeck     uint32_t expectErr;
260ac9e4e61SChristian Schoenebeck } TWriteOpt;
261ac9e4e61SChristian Schoenebeck 
262ac9e4e61SChristian Schoenebeck /* result of 'Twrite' 9p request */
263ac9e4e61SChristian Schoenebeck typedef struct TWriteRes {
264ac9e4e61SChristian Schoenebeck     /* if requestOnly was set: request object for further processing */
265ac9e4e61SChristian Schoenebeck     P9Req *req;
266ac9e4e61SChristian Schoenebeck     /* amount of bytes written */
267ac9e4e61SChristian Schoenebeck     uint32_t count;
268ac9e4e61SChristian Schoenebeck } TWriteRes;
269ac9e4e61SChristian Schoenebeck 
270d89146fdSChristian Schoenebeck /* options for 'Tflush' 9p request */
271d89146fdSChristian Schoenebeck typedef struct TFlushOpt {
272d89146fdSChristian Schoenebeck     /* 9P client being used (mandatory) */
273d89146fdSChristian Schoenebeck     QVirtio9P *client;
274d89146fdSChristian Schoenebeck     /* user supplied tag number being returned with response (optional) */
275d89146fdSChristian Schoenebeck     uint16_t tag;
276d89146fdSChristian Schoenebeck     /* message to flush (required) */
277d89146fdSChristian Schoenebeck     uint16_t oldtag;
278d89146fdSChristian Schoenebeck     /* only send Tflush request but not wait for a reply? (optional) */
279d89146fdSChristian Schoenebeck     bool requestOnly;
280d89146fdSChristian Schoenebeck     /* do we expect an Rlerror response, if yes which error code? (optional) */
281d89146fdSChristian Schoenebeck     uint32_t expectErr;
282d89146fdSChristian Schoenebeck } TFlushOpt;
283d89146fdSChristian Schoenebeck 
284d89146fdSChristian Schoenebeck /* result of 'Tflush' 9p request */
285d89146fdSChristian Schoenebeck typedef struct TFlushRes {
286d89146fdSChristian Schoenebeck     /* if requestOnly was set: request object for further processing */
287d89146fdSChristian Schoenebeck     P9Req *req;
288d89146fdSChristian Schoenebeck } TFlushRes;
289d89146fdSChristian Schoenebeck 
290e1168010SChristian Schoenebeck /* options for 'Tmkdir' 9p request */
291e1168010SChristian Schoenebeck typedef struct TMkdirOpt {
292e1168010SChristian Schoenebeck     /* 9P client being used (mandatory) */
293e1168010SChristian Schoenebeck     QVirtio9P *client;
294e1168010SChristian Schoenebeck     /* user supplied tag number being returned with response (optional) */
295e1168010SChristian Schoenebeck     uint16_t tag;
296e1168010SChristian Schoenebeck     /* low level variant of directory where new one shall be created */
297e1168010SChristian Schoenebeck     uint32_t dfid;
298e1168010SChristian Schoenebeck     /* high-level variant of directory where new one shall be created */
299e1168010SChristian Schoenebeck     const char *atPath;
300e1168010SChristian Schoenebeck     /* New directory's name (required) */
301e1168010SChristian Schoenebeck     const char *name;
302e1168010SChristian Schoenebeck     /* Linux mkdir(2) mode bits (optional) */
303e1168010SChristian Schoenebeck     uint32_t mode;
304e1168010SChristian Schoenebeck     /* effective group ID of caller */
305e1168010SChristian Schoenebeck     uint32_t gid;
306e1168010SChristian Schoenebeck     /* data being received from 9p server as 'Rmkdir' response (optional) */
307e1168010SChristian Schoenebeck     struct {
308e1168010SChristian Schoenebeck         /* QID of newly created directory */
309e1168010SChristian Schoenebeck         v9fs_qid *qid;
310e1168010SChristian Schoenebeck     } rmkdir;
311e1168010SChristian Schoenebeck     /* only send Tmkdir request but not wait for a reply? (optional) */
312e1168010SChristian Schoenebeck     bool requestOnly;
313e1168010SChristian Schoenebeck     /* do we expect an Rlerror response, if yes which error code? (optional) */
314e1168010SChristian Schoenebeck     uint32_t expectErr;
315e1168010SChristian Schoenebeck } TMkdirOpt;
316e1168010SChristian Schoenebeck 
317e1168010SChristian Schoenebeck /* result of 'TMkdir' 9p request */
318e1168010SChristian Schoenebeck typedef struct TMkdirRes {
319e1168010SChristian Schoenebeck     /* if requestOnly was set: request object for further processing */
320e1168010SChristian Schoenebeck     P9Req *req;
321e1168010SChristian Schoenebeck } TMkdirRes;
322e1168010SChristian Schoenebeck 
323bd4660d4SChristian Schoenebeck /* options for 'Tlcreate' 9p request */
324bd4660d4SChristian Schoenebeck typedef struct TlcreateOpt {
325bd4660d4SChristian Schoenebeck     /* 9P client being used (mandatory) */
326bd4660d4SChristian Schoenebeck     QVirtio9P *client;
327bd4660d4SChristian Schoenebeck     /* user supplied tag number being returned with response (optional) */
328bd4660d4SChristian Schoenebeck     uint16_t tag;
329bd4660d4SChristian Schoenebeck     /* low-level variant of directory where new file shall be created */
330bd4660d4SChristian Schoenebeck     uint32_t fid;
331bd4660d4SChristian Schoenebeck     /* high-level variant of directory where new file shall be created */
332bd4660d4SChristian Schoenebeck     const char *atPath;
333bd4660d4SChristian Schoenebeck     /* name of new file (required) */
334bd4660d4SChristian Schoenebeck     const char *name;
335bd4660d4SChristian Schoenebeck     /* Linux kernel intent bits */
336bd4660d4SChristian Schoenebeck     uint32_t flags;
337bd4660d4SChristian Schoenebeck     /* Linux create(2) mode bits */
338bd4660d4SChristian Schoenebeck     uint32_t mode;
339bd4660d4SChristian Schoenebeck     /* effective group ID of caller */
340bd4660d4SChristian Schoenebeck     uint32_t gid;
341bd4660d4SChristian Schoenebeck     /* data being received from 9p server as 'Rlcreate' response (optional) */
342bd4660d4SChristian Schoenebeck     struct {
343bd4660d4SChristian Schoenebeck         v9fs_qid *qid;
344bd4660d4SChristian Schoenebeck         uint32_t *iounit;
345bd4660d4SChristian Schoenebeck     } rlcreate;
346bd4660d4SChristian Schoenebeck     /* only send Tlcreate request but not wait for a reply? (optional) */
347bd4660d4SChristian Schoenebeck     bool requestOnly;
348bd4660d4SChristian Schoenebeck     /* do we expect an Rlerror response, if yes which error code? (optional) */
349bd4660d4SChristian Schoenebeck     uint32_t expectErr;
350bd4660d4SChristian Schoenebeck } TlcreateOpt;
351bd4660d4SChristian Schoenebeck 
352bd4660d4SChristian Schoenebeck /* result of 'Tlcreate' 9p request */
353bd4660d4SChristian Schoenebeck typedef struct TlcreateRes {
354bd4660d4SChristian Schoenebeck     /* if requestOnly was set: request object for further processing */
355bd4660d4SChristian Schoenebeck     P9Req *req;
356bd4660d4SChristian Schoenebeck } TlcreateRes;
357bd4660d4SChristian Schoenebeck 
3589beabfa5SChristian Schoenebeck /* options for 'Tsymlink' 9p request */
3599beabfa5SChristian Schoenebeck typedef struct TsymlinkOpt {
3609beabfa5SChristian Schoenebeck     /* 9P client being used (mandatory) */
3619beabfa5SChristian Schoenebeck     QVirtio9P *client;
3629beabfa5SChristian Schoenebeck     /* user supplied tag number being returned with response (optional) */
3639beabfa5SChristian Schoenebeck     uint16_t tag;
3649beabfa5SChristian Schoenebeck     /* low-level variant of directory where symlink shall be created */
3659beabfa5SChristian Schoenebeck     uint32_t fid;
3669beabfa5SChristian Schoenebeck     /* high-level variant of directory where symlink shall be created */
3679beabfa5SChristian Schoenebeck     const char *atPath;
3689beabfa5SChristian Schoenebeck     /* name of symlink (required) */
3699beabfa5SChristian Schoenebeck     const char *name;
3709beabfa5SChristian Schoenebeck     /* where symlink will point to (required) */
3719beabfa5SChristian Schoenebeck     const char *symtgt;
3729beabfa5SChristian Schoenebeck     /* effective group ID of caller */
3739beabfa5SChristian Schoenebeck     uint32_t gid;
3749beabfa5SChristian Schoenebeck     /* data being received from 9p server as 'Rsymlink' response (optional) */
3759beabfa5SChristian Schoenebeck     struct {
3769beabfa5SChristian Schoenebeck         v9fs_qid *qid;
3779beabfa5SChristian Schoenebeck     } rsymlink;
3789beabfa5SChristian Schoenebeck     /* only send Tsymlink request but not wait for a reply? (optional) */
3799beabfa5SChristian Schoenebeck     bool requestOnly;
3809beabfa5SChristian Schoenebeck     /* do we expect an Rlerror response, if yes which error code? (optional) */
3819beabfa5SChristian Schoenebeck     uint32_t expectErr;
3829beabfa5SChristian Schoenebeck } TsymlinkOpt;
3839beabfa5SChristian Schoenebeck 
3849beabfa5SChristian Schoenebeck /* result of 'Tsymlink' 9p request */
3859beabfa5SChristian Schoenebeck typedef struct TsymlinkRes {
3869beabfa5SChristian Schoenebeck     /* if requestOnly was set: request object for further processing */
3879beabfa5SChristian Schoenebeck     P9Req *req;
3889beabfa5SChristian Schoenebeck } TsymlinkRes;
3899beabfa5SChristian Schoenebeck 
390d41a9462SChristian Schoenebeck /* options for 'Tlink' 9p request */
391d41a9462SChristian Schoenebeck typedef struct TlinkOpt {
392d41a9462SChristian Schoenebeck     /* 9P client being used (mandatory) */
393d41a9462SChristian Schoenebeck     QVirtio9P *client;
394d41a9462SChristian Schoenebeck     /* user supplied tag number being returned with response (optional) */
395d41a9462SChristian Schoenebeck     uint16_t tag;
396d41a9462SChristian Schoenebeck     /* low-level variant of directory where hard link shall be created */
397d41a9462SChristian Schoenebeck     uint32_t dfid;
398d41a9462SChristian Schoenebeck     /* high-level variant of directory where hard link shall be created */
399d41a9462SChristian Schoenebeck     const char *atPath;
400d41a9462SChristian Schoenebeck     /* low-level variant of target referenced by new hard link */
401d41a9462SChristian Schoenebeck     uint32_t fid;
402d41a9462SChristian Schoenebeck     /* high-level variant of target referenced by new hard link */
403d41a9462SChristian Schoenebeck     const char *toPath;
404d41a9462SChristian Schoenebeck     /* name of hard link (required) */
405d41a9462SChristian Schoenebeck     const char *name;
406d41a9462SChristian Schoenebeck     /* only send Tlink request but not wait for a reply? (optional) */
407d41a9462SChristian Schoenebeck     bool requestOnly;
408d41a9462SChristian Schoenebeck     /* do we expect an Rlerror response, if yes which error code? (optional) */
409d41a9462SChristian Schoenebeck     uint32_t expectErr;
410d41a9462SChristian Schoenebeck } TlinkOpt;
411d41a9462SChristian Schoenebeck 
412d41a9462SChristian Schoenebeck /* result of 'Tlink' 9p request */
413d41a9462SChristian Schoenebeck typedef struct TlinkRes {
414d41a9462SChristian Schoenebeck     /* if requestOnly was set: request object for further processing */
415d41a9462SChristian Schoenebeck     P9Req *req;
416d41a9462SChristian Schoenebeck } TlinkRes;
417d41a9462SChristian Schoenebeck 
41843e0d9fbSChristian Schoenebeck /* options for 'Tunlinkat' 9p request */
41943e0d9fbSChristian Schoenebeck typedef struct TunlinkatOpt {
42043e0d9fbSChristian Schoenebeck     /* 9P client being used (mandatory) */
42143e0d9fbSChristian Schoenebeck     QVirtio9P *client;
42243e0d9fbSChristian Schoenebeck     /* user supplied tag number being returned with response (optional) */
42343e0d9fbSChristian Schoenebeck     uint16_t tag;
42443e0d9fbSChristian Schoenebeck     /* low-level variant of directory where name shall be unlinked */
42543e0d9fbSChristian Schoenebeck     uint32_t dirfd;
42643e0d9fbSChristian Schoenebeck     /* high-level variant of directory where name shall be unlinked */
42743e0d9fbSChristian Schoenebeck     const char *atPath;
42843e0d9fbSChristian Schoenebeck     /* name of directory entry to be unlinked (required) */
42943e0d9fbSChristian Schoenebeck     const char *name;
43043e0d9fbSChristian Schoenebeck     /* Linux unlinkat(2) flags */
43143e0d9fbSChristian Schoenebeck     uint32_t flags;
43243e0d9fbSChristian Schoenebeck     /* only send Tunlinkat request but not wait for a reply? (optional) */
43343e0d9fbSChristian Schoenebeck     bool requestOnly;
43443e0d9fbSChristian Schoenebeck     /* do we expect an Rlerror response, if yes which error code? (optional) */
43543e0d9fbSChristian Schoenebeck     uint32_t expectErr;
43643e0d9fbSChristian Schoenebeck } TunlinkatOpt;
43743e0d9fbSChristian Schoenebeck 
43843e0d9fbSChristian Schoenebeck /* result of 'Tunlinkat' 9p request */
43943e0d9fbSChristian Schoenebeck typedef struct TunlinkatRes {
44043e0d9fbSChristian Schoenebeck     /* if requestOnly was set: request object for further processing */
44143e0d9fbSChristian Schoenebeck     P9Req *req;
44243e0d9fbSChristian Schoenebeck } TunlinkatRes;
44343e0d9fbSChristian Schoenebeck 
444684f9120SChristian Schoenebeck void v9fs_set_allocator(QGuestAllocator *t_alloc);
445684f9120SChristian Schoenebeck void v9fs_memwrite(P9Req *req, const void *addr, size_t len);
446684f9120SChristian Schoenebeck void v9fs_memskip(P9Req *req, size_t len);
447684f9120SChristian Schoenebeck void v9fs_memread(P9Req *req, void *addr, size_t len);
448684f9120SChristian Schoenebeck void v9fs_uint8_read(P9Req *req, uint8_t *val);
449684f9120SChristian Schoenebeck void v9fs_uint16_write(P9Req *req, uint16_t val);
450684f9120SChristian Schoenebeck void v9fs_uint16_read(P9Req *req, uint16_t *val);
451684f9120SChristian Schoenebeck void v9fs_uint32_write(P9Req *req, uint32_t val);
452684f9120SChristian Schoenebeck void v9fs_uint64_write(P9Req *req, uint64_t val);
453684f9120SChristian Schoenebeck void v9fs_uint32_read(P9Req *req, uint32_t *val);
454684f9120SChristian Schoenebeck void v9fs_uint64_read(P9Req *req, uint64_t *val);
455684f9120SChristian Schoenebeck uint16_t v9fs_string_size(const char *string);
456684f9120SChristian Schoenebeck void v9fs_string_write(P9Req *req, const char *string);
457684f9120SChristian Schoenebeck void v9fs_string_read(P9Req *req, uint16_t *len, char **string);
458684f9120SChristian Schoenebeck P9Req *v9fs_req_init(QVirtio9P *v9p, uint32_t size, uint8_t id,
459684f9120SChristian Schoenebeck                      uint16_t tag);
460684f9120SChristian Schoenebeck void v9fs_req_send(P9Req *req);
461684f9120SChristian Schoenebeck void v9fs_req_wait_for_reply(P9Req *req, uint32_t *len);
462684f9120SChristian Schoenebeck void v9fs_req_recv(P9Req *req, uint8_t id);
463684f9120SChristian Schoenebeck void v9fs_req_free(P9Req *req);
464684f9120SChristian Schoenebeck void v9fs_rlerror(P9Req *req, uint32_t *err);
465bee8fda2SChristian Schoenebeck TVersionRes v9fs_tversion(TVersionOpt);
466684f9120SChristian Schoenebeck void v9fs_rversion(P9Req *req, uint16_t *len, char **version);
46774a160abSChristian Schoenebeck TAttachRes v9fs_tattach(TAttachOpt);
468684f9120SChristian Schoenebeck void v9fs_rattach(P9Req *req, v9fs_qid *qid);
469569f3b63SChristian Schoenebeck TWalkRes v9fs_twalk(TWalkOpt opt);
470684f9120SChristian Schoenebeck void v9fs_rwalk(P9Req *req, uint16_t *nwqid, v9fs_qid **wqid);
4712af5be47SChristian Schoenebeck TGetAttrRes v9fs_tgetattr(TGetAttrOpt);
472684f9120SChristian Schoenebeck void v9fs_rgetattr(P9Req *req, v9fs_attr *attr);
4731ebacc40SChristian Schoenebeck TReadDirRes v9fs_treaddir(TReadDirOpt);
474684f9120SChristian Schoenebeck void v9fs_rreaddir(P9Req *req, uint32_t *count, uint32_t *nentries,
475684f9120SChristian Schoenebeck                    struct V9fsDirent **entries);
476684f9120SChristian Schoenebeck void v9fs_free_dirents(struct V9fsDirent *e);
4773878ce4cSChristian Schoenebeck TLOpenRes v9fs_tlopen(TLOpenOpt);
478684f9120SChristian Schoenebeck void v9fs_rlopen(P9Req *req, v9fs_qid *qid, uint32_t *iounit);
479ac9e4e61SChristian Schoenebeck TWriteRes v9fs_twrite(TWriteOpt);
480684f9120SChristian Schoenebeck void v9fs_rwrite(P9Req *req, uint32_t *count);
481d89146fdSChristian Schoenebeck TFlushRes v9fs_tflush(TFlushOpt);
482684f9120SChristian Schoenebeck void v9fs_rflush(P9Req *req);
483e1168010SChristian Schoenebeck TMkdirRes v9fs_tmkdir(TMkdirOpt);
484684f9120SChristian Schoenebeck void v9fs_rmkdir(P9Req *req, v9fs_qid *qid);
485bd4660d4SChristian Schoenebeck TlcreateRes v9fs_tlcreate(TlcreateOpt);
486684f9120SChristian Schoenebeck void v9fs_rlcreate(P9Req *req, v9fs_qid *qid, uint32_t *iounit);
4879beabfa5SChristian Schoenebeck TsymlinkRes v9fs_tsymlink(TsymlinkOpt);
488684f9120SChristian Schoenebeck void v9fs_rsymlink(P9Req *req, v9fs_qid *qid);
489d41a9462SChristian Schoenebeck TlinkRes v9fs_tlink(TlinkOpt);
490684f9120SChristian Schoenebeck void v9fs_rlink(P9Req *req);
49143e0d9fbSChristian Schoenebeck TunlinkatRes v9fs_tunlinkat(TunlinkatOpt);
492684f9120SChristian Schoenebeck void v9fs_runlinkat(P9Req *req);
493684f9120SChristian Schoenebeck 
494684f9120SChristian Schoenebeck #endif
495