Statistics
| Branch: | Revision:

root / hw / 9pfs / virtio-9p.h @ 737e150e

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 "block/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