1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
#ifndef _QEMU_VIRTIO_9P_H
#define _QEMU_VIRTIO_9P_H
#include <sys/types.h>
#include <dirent.h>
#include <sys/time.h>
#include <utime.h>
#include "file-op-9p.h"
/* The feature bitmap for virtio 9P */
/* The mount point is specified in a config variable */
#define VIRTIO_9P_MOUNT_TAG 0
enum {
P9_TVERSION = 100,
P9_RVERSION,
P9_TAUTH = 102,
P9_RAUTH,
P9_TATTACH = 104,
P9_RATTACH,
P9_TERROR = 106,
P9_RERROR,
P9_TFLUSH = 108,
P9_RFLUSH,
P9_TWALK = 110,
P9_RWALK,
P9_TOPEN = 112,
P9_ROPEN,
P9_TCREATE = 114,
P9_RCREATE,
P9_TREAD = 116,
P9_RREAD,
P9_TWRITE = 118,
P9_RWRITE,
P9_TCLUNK = 120,
P9_RCLUNK,
P9_TREMOVE = 122,
P9_RREMOVE,
P9_TSTAT = 124,
P9_RSTAT,
P9_TWSTAT = 126,
P9_RWSTAT,
};
/* qid.types */
enum {
P9_QTDIR = 0x80,
P9_QTAPPEND = 0x40,
P9_QTEXCL = 0x20,
P9_QTMOUNT = 0x10,
P9_QTAUTH = 0x08,
P9_QTTMP = 0x04,
P9_QTSYMLINK = 0x02,
P9_QTLINK = 0x01,
P9_QTFILE = 0x00,
};
#define P9_NOTAG (u16)(~0)
#define P9_NOFID (u32)(~0)
#define P9_MAXWELEM 16
typedef struct V9fsPDU V9fsPDU;
struct V9fsPDU
{
uint32_t size;
uint16_t tag;
uint8_t id;
VirtQueueElement elem;
QLIST_ENTRY(V9fsPDU) next;
};
/* FIXME
* 1) change user needs to set groups and stuff
*/
/* from Linux's linux/virtio_9p.h */
/* The ID for virtio console */
#define VIRTIO_ID_9P 9
#define MAX_REQ 128
#define MAX_TAG_LEN 32
#define BUG_ON(cond) assert(!(cond))
typedef struct V9fsFidState V9fsFidState;
typedef struct V9fsString
{
int16_t size;
char *data;
} V9fsString;
typedef struct V9fsQID
{
int8_t type;
int32_t version;
int64_t path;
} V9fsQID;
typedef struct V9fsStat
{
int16_t size;
int16_t type;
int32_t dev;
V9fsQID qid;
int32_t mode;
int32_t atime;
int32_t mtime;
int64_t length;
V9fsString name;
V9fsString uid;
V9fsString gid;
V9fsString muid;
/* 9p2000.u */
V9fsString extension;
int32_t n_uid;
int32_t n_gid;
int32_t n_muid;
} V9fsStat;
struct V9fsFidState
{
int32_t fid;
V9fsString path;
int fd;
DIR *dir;
uid_t uid;
V9fsFidState *next;
};
typedef struct V9fsState
{
VirtIODevice vdev;
VirtQueue *vq;
V9fsPDU pdus[MAX_REQ];
QLIST_HEAD(, V9fsPDU) free_list;
V9fsFidState *fid_list;
FileOperations *ops;
FsContext ctx;
uint16_t tag_len;
uint8_t *tag;
size_t config_size;
} V9fsState;
struct virtio_9p_config
{
/* number of characters in tag */
uint16_t tag_len;
/* Variable size tag name */
uint8_t tag[0];
} __attribute__((packed));
extern size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
size_t offset, size_t size, int pack);
static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count,
size_t offset, size_t size)
{
return pdu_packunpack(dst, sg, sg_count, offset, size, 0);
}
#endif
|