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