build: reduce the configuring count on dibs build
[sdk/emulator/qemu.git] / hw / 9pfs / virtio-9p.h
1 #ifndef _QEMU_VIRTIO_9P_H
2 #define _QEMU_VIRTIO_9P_H
3
4 #include <sys/types.h>
5 #include <dirent.h>
6 #include <sys/time.h>
7 #include <utime.h>
8 #ifdef CONFIG_MARU
9 #ifndef CONFIG_WIN32
10 #include <sys/resource.h>
11 #endif
12 #else
13 #include <sys/resource.h>
14 #endif
15 #include <glib.h>
16 #include "hw/virtio/virtio.h"
17 #include "fsdev/file-op-9p.h"
18 #include "fsdev/virtio-9p-marshal.h"
19 #include "qemu/thread.h"
20 #include "block/coroutine.h"
21
22 /* The feature bitmap for virtio 9P */
23 /* The mount point is specified in a config variable */
24 #define VIRTIO_9P_MOUNT_TAG 0
25
26 enum {
27     P9_TLERROR = 6,
28     P9_RLERROR,
29     P9_TSTATFS = 8,
30     P9_RSTATFS,
31     P9_TLOPEN = 12,
32     P9_RLOPEN,
33     P9_TLCREATE = 14,
34     P9_RLCREATE,
35     P9_TSYMLINK = 16,
36     P9_RSYMLINK,
37     P9_TMKNOD = 18,
38     P9_RMKNOD,
39     P9_TRENAME = 20,
40     P9_RRENAME,
41     P9_TREADLINK = 22,
42     P9_RREADLINK,
43     P9_TGETATTR = 24,
44     P9_RGETATTR,
45     P9_TSETATTR = 26,
46     P9_RSETATTR,
47     P9_TXATTRWALK = 30,
48     P9_RXATTRWALK,
49     P9_TXATTRCREATE = 32,
50     P9_RXATTRCREATE,
51     P9_TREADDIR = 40,
52     P9_RREADDIR,
53     P9_TFSYNC = 50,
54     P9_RFSYNC,
55     P9_TLOCK = 52,
56     P9_RLOCK,
57     P9_TGETLOCK = 54,
58     P9_RGETLOCK,
59     P9_TLINK = 70,
60     P9_RLINK,
61     P9_TMKDIR = 72,
62     P9_RMKDIR,
63     P9_TRENAMEAT = 74,
64     P9_RRENAMEAT,
65     P9_TUNLINKAT = 76,
66     P9_RUNLINKAT,
67     P9_TVERSION = 100,
68     P9_RVERSION,
69     P9_TAUTH = 102,
70     P9_RAUTH,
71     P9_TATTACH = 104,
72     P9_RATTACH,
73     P9_TERROR = 106,
74     P9_RERROR,
75     P9_TFLUSH = 108,
76     P9_RFLUSH,
77     P9_TWALK = 110,
78     P9_RWALK,
79     P9_TOPEN = 112,
80     P9_ROPEN,
81     P9_TCREATE = 114,
82     P9_RCREATE,
83     P9_TREAD = 116,
84     P9_RREAD,
85     P9_TWRITE = 118,
86     P9_RWRITE,
87     P9_TCLUNK = 120,
88     P9_RCLUNK,
89     P9_TREMOVE = 122,
90     P9_RREMOVE,
91     P9_TSTAT = 124,
92     P9_RSTAT,
93     P9_TWSTAT = 126,
94     P9_RWSTAT,
95 };
96
97
98 /* qid.types */
99 enum {
100     P9_QTDIR = 0x80,
101     P9_QTAPPEND = 0x40,
102     P9_QTEXCL = 0x20,
103     P9_QTMOUNT = 0x10,
104     P9_QTAUTH = 0x08,
105     P9_QTTMP = 0x04,
106     P9_QTSYMLINK = 0x02,
107     P9_QTLINK = 0x01,
108     P9_QTFILE = 0x00,
109 };
110
111 enum p9_proto_version {
112     V9FS_PROTO_2000U = 0x01,
113     V9FS_PROTO_2000L = 0x02,
114 };
115
116 #define P9_NOTAG    (u16)(~0)
117 #define P9_NOFID    (u32)(~0)
118 #define P9_MAXWELEM 16
119
120 #define FID_REFERENCED          0x1
121 #define FID_NON_RECLAIMABLE     0x2
122 static inline char *rpath(FsContext *ctx, const char *path)
123 {
124 #ifndef CONFIG_MARU
125     return g_strdup_printf("%s/%s", ctx->fs_root, path);
126 #else
127 #ifndef CONFIG_WIN32
128     return g_strdup_printf("%s/%s", ctx->fs_root, path);
129 #else
130     char *buffer;
131
132     buffer =  g_strdup_printf("%s\\%s", ctx->fs_root, path);
133     while(buffer[strlen(buffer)-1] == '\\'){
134         buffer[strlen(buffer)-1] = '\0';
135     }
136     return buffer;
137 #endif
138 #endif
139 }
140
141 /*
142  * ample room for Twrite/Rread header
143  * size[4] Tread/Twrite tag[2] fid[4] offset[8] count[4]
144  */
145 #define P9_IOHDRSZ 24
146
147 typedef struct V9fsPDU V9fsPDU;
148 struct V9fsState;
149
150 struct V9fsPDU
151 {
152     uint32_t size;
153     uint16_t tag;
154     uint8_t id;
155     uint8_t cancelled;
156     CoQueue complete;
157     VirtQueueElement elem;
158     struct V9fsState *s;
159     QLIST_ENTRY(V9fsPDU) next;
160 };
161
162
163 /* FIXME
164  * 1) change user needs to set groups and stuff
165  */
166
167 /* from Linux's linux/virtio_9p.h */
168
169 /* The ID for virtio console */
170 #define VIRTIO_ID_9P    9
171 #define MAX_REQ         128
172 #define MAX_TAG_LEN     32
173
174 #define BUG_ON(cond) assert(!(cond))
175
176 typedef struct V9fsFidState V9fsFidState;
177
178 enum {
179     P9_FID_NONE = 0,
180     P9_FID_FILE,
181     P9_FID_DIR,
182     P9_FID_XATTR,
183 };
184
185 typedef struct V9fsXattr
186 {
187     int64_t copied_len;
188     int64_t len;
189     void *value;
190     V9fsString name;
191     int flags;
192 } V9fsXattr;
193
194 /*
195  * Filled by fs driver on open and other
196  * calls.
197  */
198 union V9fsFidOpenState {
199     int fd;
200     DIR *dir;
201     V9fsXattr xattr;
202     /*
203      * private pointer for fs drivers, that
204      * have its own internal representation of
205      * open files.
206      */
207     void *private;
208 };
209
210 struct V9fsFidState
211 {
212     int fid_type;
213     int32_t fid;
214     V9fsPath path;
215     V9fsFidOpenState fs;
216     V9fsFidOpenState fs_reclaim;
217     int flags;
218     int open_flags;
219     uid_t uid;
220     int ref;
221     int clunked;
222     V9fsFidState *next;
223     V9fsFidState *rclm_lst;
224 };
225
226 typedef struct V9fsState
227 {
228     VirtIODevice parent_obj;
229     VirtQueue *vq;
230     V9fsPDU pdus[MAX_REQ];
231     QLIST_HEAD(, V9fsPDU) free_list;
232     QLIST_HEAD(, V9fsPDU) active_list;
233     V9fsFidState *fid_list;
234     FileOperations *ops;
235     FsContext ctx;
236     char *tag;
237     size_t config_size;
238     enum p9_proto_version proto_version;
239     int32_t msize;
240     /*
241      * lock ensuring atomic path update
242      * on rename.
243      */
244     CoRwlock rename_lock;
245     int32_t root_fid;
246     Error *migration_blocker;
247     V9fsConf fsconf;
248 } V9fsState;
249
250 typedef struct V9fsStatState {
251     V9fsPDU *pdu;
252     size_t offset;
253     V9fsStat v9stat;
254     V9fsFidState *fidp;
255     struct stat stbuf;
256 } V9fsStatState;
257
258 typedef struct V9fsOpenState {
259     V9fsPDU *pdu;
260     size_t offset;
261     int32_t mode;
262     V9fsFidState *fidp;
263     V9fsQID qid;
264     struct stat stbuf;
265     int iounit;
266 } V9fsOpenState;
267
268 typedef struct V9fsReadState {
269     V9fsPDU *pdu;
270     size_t offset;
271     int32_t count;
272     int32_t total;
273     int64_t off;
274     V9fsFidState *fidp;
275     struct iovec iov[128]; /* FIXME: bad, bad, bad */
276     struct iovec *sg;
277     off_t dir_pos;
278     struct dirent *dent;
279     struct stat stbuf;
280     V9fsString name;
281     V9fsStat v9stat;
282     int32_t len;
283     int32_t cnt;
284     int32_t max_count;
285 } V9fsReadState;
286
287 typedef struct V9fsWriteState {
288     V9fsPDU *pdu;
289     size_t offset;
290     int32_t len;
291     int32_t count;
292     int32_t total;
293     int64_t off;
294     V9fsFidState *fidp;
295     struct iovec iov[128]; /* FIXME: bad, bad, bad */
296     struct iovec *sg;
297     int cnt;
298 } V9fsWriteState;
299
300 struct virtio_9p_config
301 {
302     /* number of characters in tag */
303     uint16_t tag_len;
304     /* Variable size tag name */
305     uint8_t tag[0];
306 } QEMU_PACKED;
307
308 typedef struct V9fsMkState {
309     V9fsPDU *pdu;
310     size_t offset;
311     V9fsQID qid;
312     struct stat stbuf;
313     V9fsString name;
314     V9fsString fullname;
315 } V9fsMkState;
316
317 /* 9p2000.L open flags */
318 #define P9_DOTL_RDONLY        00000000
319 #define P9_DOTL_WRONLY        00000001
320 #define P9_DOTL_RDWR          00000002
321 #define P9_DOTL_NOACCESS      00000003
322 #define P9_DOTL_CREATE        00000100
323 #define P9_DOTL_EXCL          00000200
324 #define P9_DOTL_NOCTTY        00000400
325 #define P9_DOTL_TRUNC         00001000
326 #define P9_DOTL_APPEND        00002000
327 #define P9_DOTL_NONBLOCK      00004000
328 #define P9_DOTL_DSYNC         00010000
329 #define P9_DOTL_FASYNC        00020000
330 #define P9_DOTL_DIRECT        00040000
331 #define P9_DOTL_LARGEFILE     00100000
332 #define P9_DOTL_DIRECTORY     00200000
333 #define P9_DOTL_NOFOLLOW      00400000
334 #define P9_DOTL_NOATIME       01000000
335 #define P9_DOTL_CLOEXEC       02000000
336 #define P9_DOTL_SYNC          04000000
337
338 /* 9p2000.L at flags */
339 #define P9_DOTL_AT_REMOVEDIR         0x200
340
341 /* 9P2000.L lock type */
342 #define P9_LOCK_TYPE_RDLCK 0
343 #define P9_LOCK_TYPE_WRLCK 1
344 #define P9_LOCK_TYPE_UNLCK 2
345
346 #define P9_LOCK_SUCCESS 0
347 #define P9_LOCK_BLOCKED 1
348 #define P9_LOCK_ERROR 2
349 #define P9_LOCK_GRACE 3
350
351 #define P9_LOCK_FLAGS_BLOCK 1
352 #define P9_LOCK_FLAGS_RECLAIM 2
353
354 typedef struct V9fsFlock
355 {
356     uint8_t type;
357     uint32_t flags;
358     uint64_t start; /* absolute offset */
359     uint64_t length;
360     uint32_t proc_id;
361     V9fsString client_id;
362 } V9fsFlock;
363
364 typedef struct V9fsGetlock
365 {
366     uint8_t type;
367     uint64_t start; /* absolute offset */
368     uint64_t length;
369     uint32_t proc_id;
370     V9fsString client_id;
371 } V9fsGetlock;
372
373 extern int open_fd_hw;
374 extern int total_open_fd;
375
376 size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
377                       size_t offset, size_t size, int pack);
378
379 static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count,
380                         size_t offset, size_t size)
381 {
382     return pdu_packunpack(dst, sg, sg_count, offset, size, 0);
383 }
384
385 static inline void v9fs_path_write_lock(V9fsState *s)
386 {
387     if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
388         qemu_co_rwlock_wrlock(&s->rename_lock);
389     }
390 }
391
392 static inline void v9fs_path_read_lock(V9fsState *s)
393 {
394     if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
395         qemu_co_rwlock_rdlock(&s->rename_lock);
396     }
397 }
398
399 static inline void v9fs_path_unlock(V9fsState *s)
400 {
401     if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {
402         qemu_co_rwlock_unlock(&s->rename_lock);
403     }
404 }
405
406 static inline uint8_t v9fs_request_cancelled(V9fsPDU *pdu)
407 {
408     return pdu->cancelled;
409 }
410
411 extern void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq);
412 extern void v9fs_reclaim_fd(V9fsPDU *pdu);
413 extern void v9fs_path_init(V9fsPath *path);
414 extern void v9fs_path_free(V9fsPath *path);
415 extern void v9fs_path_copy(V9fsPath *lhs, V9fsPath *rhs);
416 extern int v9fs_name_to_path(V9fsState *s, V9fsPath *dirpath,
417                              const char *name, V9fsPath *path);
418
419 #define pdu_marshal(pdu, offset, fmt, args...)  \
420     v9fs_marshal(pdu->elem.in_sg, pdu->elem.in_num, offset, 1, fmt, ##args)
421 #define pdu_unmarshal(pdu, offset, fmt, args...)  \
422     v9fs_unmarshal(pdu->elem.out_sg, pdu->elem.out_num, offset, 1, fmt, ##args)
423
424 #define TYPE_VIRTIO_9P "virtio-9p-device"
425 #define VIRTIO_9P(obj) \
426         OBJECT_CHECK(V9fsState, (obj), TYPE_VIRTIO_9P)
427
428 #define DEFINE_VIRTIO_9P_PROPERTIES(_state, _field)             \
429         DEFINE_PROP_STRING("mount_tag", _state, _field.tag),    \
430         DEFINE_PROP_STRING("fsdev", _state, _field.fsdev_id)
431
432 #endif