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