Merge remote-tracking branch 'aneesh/for-upstream-3' into staging
[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 #include <sys/resource.h>
9 #include "hw/virtio.h"
10 #include "fsdev/file-op-9p.h"
11
12 /* The feature bitmap for virtio 9P */
13 /* The mount point is specified in a config variable */
14 #define VIRTIO_9P_MOUNT_TAG 0
15
16 enum {
17     P9_TLERROR = 6,
18     P9_RLERROR,
19     P9_TSTATFS = 8,
20     P9_RSTATFS,
21     P9_TLOPEN = 12,
22     P9_RLOPEN,
23     P9_TLCREATE = 14,
24     P9_RLCREATE,
25     P9_TSYMLINK = 16,
26     P9_RSYMLINK,
27     P9_TMKNOD = 18,
28     P9_RMKNOD,
29     P9_TRENAME = 20,
30     P9_RRENAME,
31     P9_TREADLINK = 22,
32     P9_RREADLINK,
33     P9_TGETATTR = 24,
34     P9_RGETATTR,
35     P9_TSETATTR = 26,
36     P9_RSETATTR,
37     P9_TXATTRWALK = 30,
38     P9_RXATTRWALK,
39     P9_TXATTRCREATE = 32,
40     P9_RXATTRCREATE,
41     P9_TREADDIR = 40,
42     P9_RREADDIR,
43     P9_TFSYNC = 50,
44     P9_RFSYNC,
45     P9_TLOCK = 52,
46     P9_RLOCK,
47     P9_TGETLOCK = 54,
48     P9_RGETLOCK,
49     P9_TLINK = 70,
50     P9_RLINK,
51     P9_TMKDIR = 72,
52     P9_RMKDIR,
53     P9_TVERSION = 100,
54     P9_RVERSION,
55     P9_TAUTH = 102,
56     P9_RAUTH,
57     P9_TATTACH = 104,
58     P9_RATTACH,
59     P9_TERROR = 106,
60     P9_RERROR,
61     P9_TFLUSH = 108,
62     P9_RFLUSH,
63     P9_TWALK = 110,
64     P9_RWALK,
65     P9_TOPEN = 112,
66     P9_ROPEN,
67     P9_TCREATE = 114,
68     P9_RCREATE,
69     P9_TREAD = 116,
70     P9_RREAD,
71     P9_TWRITE = 118,
72     P9_RWRITE,
73     P9_TCLUNK = 120,
74     P9_RCLUNK,
75     P9_TREMOVE = 122,
76     P9_RREMOVE,
77     P9_TSTAT = 124,
78     P9_RSTAT,
79     P9_TWSTAT = 126,
80     P9_RWSTAT,
81 };
82
83
84 /* qid.types */
85 enum {
86     P9_QTDIR = 0x80,
87     P9_QTAPPEND = 0x40,
88     P9_QTEXCL = 0x20,
89     P9_QTMOUNT = 0x10,
90     P9_QTAUTH = 0x08,
91     P9_QTTMP = 0x04,
92     P9_QTSYMLINK = 0x02,
93     P9_QTLINK = 0x01,
94     P9_QTFILE = 0x00,
95 };
96
97 enum p9_proto_version {
98     V9FS_PROTO_2000U = 0x01,
99     V9FS_PROTO_2000L = 0x02,
100 };
101
102 #define P9_NOTAG    (u16)(~0)
103 #define P9_NOFID    (u32)(~0)
104 #define P9_MAXWELEM 16
105
106 #define FID_REFERENCED          0x1
107 #define FID_NON_RECLAIMABLE     0x2
108 static inline const char *rpath(FsContext *ctx, const char *path, char *buffer)
109 {
110     snprintf(buffer, PATH_MAX, "%s/%s", ctx->fs_root, path);
111     return buffer;
112 }
113
114 /*
115  * ample room for Twrite/Rread header
116  * size[4] Tread/Twrite tag[2] fid[4] offset[8] count[4]
117  */
118 #define P9_IOHDRSZ 24
119
120 typedef struct V9fsPDU V9fsPDU;
121 struct V9fsState;
122
123 struct V9fsPDU
124 {
125     uint32_t size;
126     uint16_t tag;
127     uint8_t id;
128     VirtQueueElement elem;
129     struct V9fsState *s;
130     QLIST_ENTRY(V9fsPDU) next;
131 };
132
133
134 /* FIXME
135  * 1) change user needs to set groups and stuff
136  */
137
138 /* from Linux's linux/virtio_9p.h */
139
140 /* The ID for virtio console */
141 #define VIRTIO_ID_9P    9
142 #define MAX_REQ         128
143 #define MAX_TAG_LEN     32
144
145 #define BUG_ON(cond) assert(!(cond))
146
147 typedef struct V9fsFidState V9fsFidState;
148
149 typedef struct V9fsString
150 {
151     int16_t size;
152     char *data;
153 } V9fsString;
154
155 typedef struct V9fsQID
156 {
157     int8_t type;
158     int32_t version;
159     int64_t path;
160 } V9fsQID;
161
162 typedef struct V9fsStat
163 {
164     int16_t size;
165     int16_t type;
166     int32_t dev;
167     V9fsQID qid;
168     int32_t mode;
169     int32_t atime;
170     int32_t mtime;
171     int64_t length;
172     V9fsString name;
173     V9fsString uid;
174     V9fsString gid;
175     V9fsString muid;
176     /* 9p2000.u */
177     V9fsString extension;
178    int32_t n_uid;
179     int32_t n_gid;
180     int32_t n_muid;
181 } V9fsStat;
182
183 enum {
184     P9_FID_NONE = 0,
185     P9_FID_FILE,
186     P9_FID_DIR,
187     P9_FID_XATTR,
188 };
189
190 typedef struct V9fsXattr
191 {
192     int64_t copied_len;
193     int64_t len;
194     void *value;
195     V9fsString name;
196     int flags;
197 } V9fsXattr;
198
199 struct V9fsFidState
200 {
201     int fid_type;
202     int32_t fid;
203     V9fsString path;
204     union {
205         int fd;
206         DIR *dir;
207         V9fsXattr xattr;
208     } fs;
209     union {
210         int fd;
211         DIR *dir;
212     } fs_reclaim;
213     int flags;
214     int open_flags;
215     uid_t uid;
216     int ref;
217     int clunked;
218     V9fsFidState *next;
219     V9fsFidState *rclm_lst;
220 };
221
222 typedef struct V9fsState
223 {
224     VirtIODevice vdev;
225     VirtQueue *vq;
226     V9fsPDU pdus[MAX_REQ];
227     QLIST_HEAD(, V9fsPDU) free_list;
228     V9fsFidState *fid_list;
229     FileOperations *ops;
230     FsContext ctx;
231     uint16_t tag_len;
232     uint8_t *tag;
233     size_t config_size;
234     enum p9_proto_version proto_version;
235     int32_t msize;
236 } V9fsState;
237
238 typedef struct V9fsStatState {
239     V9fsPDU *pdu;
240     size_t offset;
241     V9fsStat v9stat;
242     V9fsFidState *fidp;
243     struct stat stbuf;
244 } V9fsStatState;
245
246 typedef struct V9fsStatDotl {
247     uint64_t st_result_mask;
248     V9fsQID qid;
249     uint32_t st_mode;
250     uint32_t st_uid;
251     uint32_t st_gid;
252     uint64_t st_nlink;
253     uint64_t st_rdev;
254     uint64_t st_size;
255     uint64_t st_blksize;
256     uint64_t st_blocks;
257     uint64_t st_atime_sec;
258     uint64_t st_atime_nsec;
259     uint64_t st_mtime_sec;
260     uint64_t st_mtime_nsec;
261     uint64_t st_ctime_sec;
262     uint64_t st_ctime_nsec;
263     uint64_t st_btime_sec;
264     uint64_t st_btime_nsec;
265     uint64_t st_gen;
266     uint64_t st_data_version;
267 } V9fsStatDotl;
268
269 typedef struct V9fsOpenState {
270     V9fsPDU *pdu;
271     size_t offset;
272     int32_t mode;
273     V9fsFidState *fidp;
274     V9fsQID qid;
275     struct stat stbuf;
276     int iounit;
277 } V9fsOpenState;
278
279 typedef struct V9fsReadState {
280     V9fsPDU *pdu;
281     size_t offset;
282     int32_t count;
283     int32_t total;
284     int64_t off;
285     V9fsFidState *fidp;
286     struct iovec iov[128]; /* FIXME: bad, bad, bad */
287     struct iovec *sg;
288     off_t dir_pos;
289     struct dirent *dent;
290     struct stat stbuf;
291     V9fsString name;
292     V9fsStat v9stat;
293     int32_t len;
294     int32_t cnt;
295     int32_t max_count;
296 } V9fsReadState;
297
298 typedef struct V9fsWriteState {
299     V9fsPDU *pdu;
300     size_t offset;
301     int32_t len;
302     int32_t count;
303     int32_t total;
304     int64_t off;
305     V9fsFidState *fidp;
306     struct iovec iov[128]; /* FIXME: bad, bad, bad */
307     struct iovec *sg;
308     int cnt;
309 } V9fsWriteState;
310
311 typedef struct V9fsIattr
312 {
313     int32_t valid;
314     int32_t mode;
315     int32_t uid;
316     int32_t gid;
317     int64_t size;
318     int64_t atime_sec;
319     int64_t atime_nsec;
320     int64_t mtime_sec;
321     int64_t mtime_nsec;
322 } V9fsIattr;
323
324 struct virtio_9p_config
325 {
326     /* number of characters in tag */
327     uint16_t tag_len;
328     /* Variable size tag name */
329     uint8_t tag[0];
330 } QEMU_PACKED;
331
332 typedef struct V9fsMkState {
333     V9fsPDU *pdu;
334     size_t offset;
335     V9fsQID qid;
336     struct stat stbuf;
337     V9fsString name;
338     V9fsString fullname;
339 } V9fsMkState;
340
341 #define P9_LOCK_SUCCESS 0
342 #define P9_LOCK_BLOCKED 1
343 #define P9_LOCK_ERROR 2
344 #define P9_LOCK_GRACE 3
345
346 #define P9_LOCK_FLAGS_BLOCK 1
347 #define P9_LOCK_FLAGS_RECLAIM 2
348
349 typedef struct V9fsFlock
350 {
351     uint8_t type;
352     uint32_t flags;
353     uint64_t start; /* absolute offset */
354     uint64_t length;
355     uint32_t proc_id;
356     V9fsString client_id;
357 } V9fsFlock;
358
359 typedef struct V9fsGetlock
360 {
361     uint8_t type;
362     uint64_t start; /* absolute offset */
363     uint64_t length;
364     uint32_t proc_id;
365     V9fsString client_id;
366 } V9fsGetlock;
367
368 extern int open_fd_hw;
369 extern int total_open_fd;
370
371 size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
372                       size_t offset, size_t size, int pack);
373
374 static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count,
375                         size_t offset, size_t size)
376 {
377     return pdu_packunpack(dst, sg, sg_count, offset, size, 0);
378 }
379
380 extern void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq);
381 extern void virtio_9p_set_fd_limit(void);
382 extern void v9fs_reclaim_fd(V9fsState *s);
383 #endif