Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/lib9p/fcall.h
39475 views
1
/*
2
* Copyright 2016 Jakub Klama <[email protected]>
3
* All rights reserved
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted providing that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24
* POSSIBILITY OF SUCH DAMAGE.
25
*
26
*/
27
28
/*
29
* Based on libixp code: ©2007-2010 Kris Maglione <maglione.k at Gmail>
30
*/
31
32
#ifndef LIB9P_FCALL_H
33
#define LIB9P_FCALL_H
34
35
#include <stdint.h>
36
37
#define L9P_MAX_WELEM 256
38
39
/*
40
* Function call/reply (Tfoo/Rfoo) numbers.
41
*
42
* These are protocol code numbers, so the exact values
43
* matter. However, __FIRST and __LAST_PLUS_ONE are for
44
* debug code, and just need to encompass the entire range.
45
*
46
* Note that we rely (in the debug code) on Rfoo == Tfoo+1.
47
*/
48
enum l9p_ftype {
49
L9P__FIRST = 6, /* NB: must be <= all legal values */
50
L9P_TLERROR = 6, /* illegal; exists for parity with Rlerror */
51
L9P_RLERROR,
52
L9P_TSTATFS = 8,
53
L9P_RSTATFS,
54
L9P_TLOPEN = 12,
55
L9P_RLOPEN,
56
L9P_TLCREATE = 14,
57
L9P_RLCREATE,
58
L9P_TSYMLINK = 16,
59
L9P_RSYMLINK,
60
L9P_TMKNOD = 18,
61
L9P_RMKNOD,
62
L9P_TRENAME = 20,
63
L9P_RRENAME,
64
L9P_TREADLINK = 22,
65
L9P_RREADLINK,
66
L9P_TGETATTR = 24,
67
L9P_RGETATTR,
68
L9P_TSETATTR = 26,
69
L9P_RSETATTR,
70
L9P_TXATTRWALK = 30,
71
L9P_RXATTRWALK,
72
L9P_TXATTRCREATE = 32,
73
L9P_RXATTRCREATE,
74
L9P_TREADDIR = 40,
75
L9P_RREADDIR,
76
L9P_TFSYNC = 50,
77
L9P_RFSYNC,
78
L9P_TLOCK = 52,
79
L9P_RLOCK,
80
L9P_TGETLOCK = 54,
81
L9P_RGETLOCK,
82
L9P_TLINK = 70,
83
L9P_RLINK,
84
L9P_TMKDIR = 72,
85
L9P_RMKDIR,
86
L9P_TRENAMEAT = 74,
87
L9P_RRENAMEAT,
88
L9P_TUNLINKAT = 76,
89
L9P_RUNLINKAT,
90
L9P_TVERSION = 100,
91
L9P_RVERSION,
92
L9P_TAUTH = 102,
93
L9P_RAUTH,
94
L9P_TATTACH = 104,
95
L9P_RATTACH,
96
L9P_TERROR = 106, /* illegal */
97
L9P_RERROR,
98
L9P_TFLUSH = 108,
99
L9P_RFLUSH,
100
L9P_TWALK = 110,
101
L9P_RWALK,
102
L9P_TOPEN = 112,
103
L9P_ROPEN,
104
L9P_TCREATE = 114,
105
L9P_RCREATE,
106
L9P_TREAD = 116,
107
L9P_RREAD,
108
L9P_TWRITE = 118,
109
L9P_RWRITE,
110
L9P_TCLUNK = 120,
111
L9P_RCLUNK,
112
L9P_TREMOVE = 122,
113
L9P_RREMOVE,
114
L9P_TSTAT = 124,
115
L9P_RSTAT,
116
L9P_TWSTAT = 126,
117
L9P_RWSTAT,
118
L9P__LAST_PLUS_1, /* NB: must be last */
119
};
120
121
/*
122
* When a Tfoo request comes over the wire, we decode it
123
* (pack.c) from wire format into a request laid out in
124
* a "union l9p_fcall" object. This object is not in wire
125
* format, but rather in something more convenient for us
126
* to operate on.
127
*
128
* We then dispatch the request (request.c, backend/fs.c) and
129
* use another "union l9p_fcall" object to build a reply.
130
* The reply is converted to wire format on the way back out
131
* (pack.c again).
132
*
133
* All sub-objects start with a header containing the request
134
* or reply type code and two-byte tag, and whether or not it
135
* is needed, a four-byte fid.
136
*
137
* What this means here is that the data structures within
138
* the union can be shared across various requests and replies.
139
* For instance, replies to OPEN, CREATE, LCREATE, LOPEN, MKDIR, and
140
* SYMLINK are all fairly similar (providing a qid and sometimes
141
* an iounit) and hence can all use the l9p_f_ropen structure.
142
* Which structures are used for which operations is somewhat
143
* arbitrary; for programming ease, if an operation shares a
144
* data structure, it still has its own name: there are union
145
* members named ropen, rcreate, rlcreate, rlopen, rmkdir, and
146
* rsymlink, even though all use struct l9p_f_ropen.
147
*
148
* The big exception to the above rule is struct l9p_f_io, which
149
* is used as both request and reply for all of READ, WRITE, and
150
* READDIR. Moreover, the READDIR reply must be pre-packed into
151
* wire format (it is handled like raw data a la READ).
152
*
153
* Some request messages (e.g., TREADLINK) fit in a header, having
154
* just type code, tag, and fid. These have no separate data
155
* structure, nor union member name. Similarly, some reply
156
* messages (e.g., RCLUNK, RREMOVE, RRENAME) have just the type
157
* code and tag.
158
*/
159
160
/*
161
* Type code bits in (the first byte of) a qid.
162
*/
163
enum l9p_qid_type {
164
L9P_QTDIR = 0x80, /* type bit for directories */
165
L9P_QTAPPEND = 0x40, /* type bit for append only files */
166
L9P_QTEXCL = 0x20, /* type bit for exclusive use files */
167
L9P_QTMOUNT = 0x10, /* type bit for mounted channel */
168
L9P_QTAUTH = 0x08, /* type bit for authentication file */
169
L9P_QTTMP = 0x04, /* type bit for non-backed-up file */
170
L9P_QTSYMLINK = 0x02, /* type bit for symbolic link */
171
L9P_QTFILE = 0x00 /* type bits for plain file */
172
};
173
174
/*
175
* Extra permission bits in create and file modes (stat).
176
*/
177
#define L9P_DMDIR 0x80000000
178
enum {
179
L9P_DMAPPEND = 0x40000000,
180
L9P_DMEXCL = 0x20000000,
181
L9P_DMMOUNT = 0x10000000,
182
L9P_DMAUTH = 0x08000000,
183
L9P_DMTMP = 0x04000000,
184
L9P_DMSYMLINK = 0x02000000,
185
/* 9P2000.u extensions */
186
L9P_DMDEVICE = 0x00800000,
187
L9P_DMNAMEDPIPE = 0x00200000,
188
L9P_DMSOCKET = 0x00100000,
189
L9P_DMSETUID = 0x00080000,
190
L9P_DMSETGID = 0x00040000,
191
};
192
193
/*
194
* Open/create mode bits in 9P2000 and 9P2000.u operations
195
* (not Linux lopen and lcreate flags, which are different).
196
* Note that the mode field is only one byte wide.
197
*/
198
enum l9p_omode {
199
L9P_OREAD = 0, /* open for read */
200
L9P_OWRITE = 1, /* write */
201
L9P_ORDWR = 2, /* read and write */
202
L9P_OEXEC = 3, /* execute, == read but check execute permission */
203
L9P_OACCMODE = 3, /* mask for the above access-mode bits */
204
L9P_OTRUNC = 16, /* or'ed in (except for exec), truncate file first */
205
L9P_OCEXEC = 32, /* or'ed in, close on exec */
206
L9P_ORCLOSE = 64, /* or'ed in, remove on close */
207
L9P_ODIRECT = 128, /* or'ed in, direct access */
208
};
209
210
/*
211
* Flag bits in 9P2000.L operations (Tlopen, Tlcreate). These are
212
* basically just the Linux L_* flags. The bottom 3 bits are the
213
* same as for l9p_omode, although open-for-exec is not used:
214
* instead, the client does a Tgetattr and checks the mode for
215
* execute bits, then just opens for reading.
216
*
217
* Each L_O_xxx is just value O_xxx has on Linux in <fcntl.h>;
218
* not all are necessarily used. From observation, we do get
219
* L_O_CREAT and L_O_EXCL when creating with exclusive, and always
220
* get L_O_LARGEFILE. We do get L_O_APPEND when opening for
221
* append. We also get both L_O_DIRECT and L_O_DIRECTORY set
222
* when opening directories.
223
*
224
* We probably never get L_O_NOCTTY which makes no sense, and
225
* some of the other options may need to be handled on the client.
226
*/
227
enum l9p_l_o_flags {
228
L9P_L_O_CREAT = 000000100U,
229
L9P_L_O_EXCL = 000000200U,
230
L9P_L_O_NOCTTY = 000000400U,
231
L9P_L_O_TRUNC = 000001000U,
232
L9P_L_O_APPEND = 000002000U,
233
L9P_L_O_NONBLOCK = 000004000U,
234
L9P_L_O_DSYNC = 000010000U,
235
L9P_L_O_FASYNC = 000020000U,
236
L9P_L_O_DIRECT = 000040000U,
237
L9P_L_O_LARGEFILE = 000100000U,
238
L9P_L_O_DIRECTORY = 000200000U,
239
L9P_L_O_NOFOLLOW = 000400000U,
240
L9P_L_O_NOATIME = 001000000U,
241
L9P_L_O_CLOEXEC = 002000000U,
242
L9P_L_O_SYNC = 004000000U,
243
L9P_L_O_PATH = 010000000U,
244
L9P_L_O_TMPFILE = 020000000U,
245
};
246
247
struct l9p_hdr {
248
uint8_t type;
249
uint16_t tag;
250
uint32_t fid;
251
};
252
253
struct l9p_qid {
254
uint8_t type;
255
uint32_t version;
256
uint64_t path;
257
};
258
259
struct l9p_stat {
260
uint16_t type;
261
uint32_t dev;
262
struct l9p_qid qid;
263
uint32_t mode;
264
uint32_t atime;
265
uint32_t mtime;
266
uint64_t length;
267
char *name;
268
char *uid;
269
char *gid;
270
char *muid;
271
char *extension;
272
uint32_t n_uid;
273
uint32_t n_gid;
274
uint32_t n_muid;
275
};
276
277
#define L9P_FSTYPE 0x01021997
278
279
struct l9p_statfs {
280
uint32_t type; /* file system type */
281
uint32_t bsize; /* block size for I/O */
282
uint64_t blocks; /* file system size (bsize-byte blocks) */
283
uint64_t bfree; /* free blocks in fs */
284
uint64_t bavail; /* free blocks avail to non-superuser*/
285
uint64_t files; /* file nodes in file system (# inodes) */
286
uint64_t ffree; /* free file nodes in fs */
287
uint64_t fsid; /* file system identifier */
288
uint32_t namelen; /* maximum length of filenames */
289
};
290
291
struct l9p_f_version {
292
struct l9p_hdr hdr;
293
uint32_t msize;
294
char *version;
295
};
296
297
struct l9p_f_tflush {
298
struct l9p_hdr hdr;
299
uint16_t oldtag;
300
};
301
302
struct l9p_f_error {
303
struct l9p_hdr hdr;
304
char *ename;
305
uint32_t errnum;
306
};
307
308
struct l9p_f_ropen {
309
struct l9p_hdr hdr;
310
struct l9p_qid qid;
311
uint32_t iounit;
312
};
313
314
struct l9p_f_rauth {
315
struct l9p_hdr hdr;
316
struct l9p_qid aqid;
317
};
318
319
struct l9p_f_attach {
320
struct l9p_hdr hdr;
321
uint32_t afid;
322
char *uname;
323
char *aname;
324
uint32_t n_uname;
325
};
326
#define L9P_NOFID ((uint32_t)-1) /* in Tattach, no auth fid */
327
#define L9P_NONUNAME ((uint32_t)-1) /* in Tattach, no n_uname */
328
329
struct l9p_f_tcreate {
330
struct l9p_hdr hdr;
331
uint32_t perm;
332
char *name;
333
uint8_t mode; /* +Topen */
334
char *extension;
335
};
336
337
struct l9p_f_twalk {
338
struct l9p_hdr hdr;
339
uint32_t newfid;
340
uint16_t nwname;
341
char *wname[L9P_MAX_WELEM];
342
};
343
344
struct l9p_f_rwalk {
345
struct l9p_hdr hdr;
346
uint16_t nwqid;
347
struct l9p_qid wqid[L9P_MAX_WELEM];
348
};
349
350
struct l9p_f_io {
351
struct l9p_hdr hdr;
352
uint64_t offset; /* Tread, Twrite, Treaddir */
353
uint32_t count; /* Tread, Twrite, Rread, Treaddir, Rreaddir */
354
};
355
356
struct l9p_f_rstat {
357
struct l9p_hdr hdr;
358
struct l9p_stat stat;
359
};
360
361
struct l9p_f_twstat {
362
struct l9p_hdr hdr;
363
struct l9p_stat stat;
364
};
365
366
struct l9p_f_rstatfs {
367
struct l9p_hdr hdr;
368
struct l9p_statfs statfs;
369
};
370
371
/* Used for Tlcreate, Tlopen, Tmkdir, Tunlinkat. */
372
struct l9p_f_tlcreate {
373
struct l9p_hdr hdr;
374
char *name; /* Tlcreate, Tmkdir, Tunlinkat */
375
uint32_t flags; /* Tlcreate, Tlopen, Tmkdir, Tunlinkat */
376
uint32_t mode; /* Tlcreate, Tmkdir */
377
uint32_t gid; /* Tlcreate, Tmkdir */
378
};
379
380
struct l9p_f_tsymlink {
381
struct l9p_hdr hdr;
382
char *name;
383
char *symtgt;
384
uint32_t gid;
385
};
386
387
struct l9p_f_tmknod {
388
struct l9p_hdr hdr;
389
char *name;
390
uint32_t mode;
391
uint32_t major;
392
uint32_t minor;
393
uint32_t gid;
394
};
395
396
struct l9p_f_trename {
397
struct l9p_hdr hdr;
398
uint32_t dfid;
399
char *name;
400
};
401
402
struct l9p_f_rreadlink {
403
struct l9p_hdr hdr;
404
char *target;
405
};
406
407
struct l9p_f_tgetattr {
408
struct l9p_hdr hdr;
409
uint64_t request_mask;
410
};
411
412
struct l9p_f_rgetattr {
413
struct l9p_hdr hdr;
414
uint64_t valid;
415
struct l9p_qid qid;
416
uint32_t mode;
417
uint32_t uid;
418
uint32_t gid;
419
uint64_t nlink;
420
uint64_t rdev;
421
uint64_t size;
422
uint64_t blksize;
423
uint64_t blocks;
424
uint64_t atime_sec;
425
uint64_t atime_nsec;
426
uint64_t mtime_sec;
427
uint64_t mtime_nsec;
428
uint64_t ctime_sec;
429
uint64_t ctime_nsec;
430
uint64_t btime_sec;
431
uint64_t btime_nsec;
432
uint64_t gen;
433
uint64_t data_version;
434
};
435
436
/* Fields in req->request_mask and reply->valid for Tgetattr, Rgetattr. */
437
enum l9pl_getattr_flags {
438
L9PL_GETATTR_MODE = 0x00000001,
439
L9PL_GETATTR_NLINK = 0x00000002,
440
L9PL_GETATTR_UID = 0x00000004,
441
L9PL_GETATTR_GID = 0x00000008,
442
L9PL_GETATTR_RDEV = 0x00000010,
443
L9PL_GETATTR_ATIME = 0x00000020,
444
L9PL_GETATTR_MTIME = 0x00000040,
445
L9PL_GETATTR_CTIME = 0x00000080,
446
L9PL_GETATTR_INO = 0x00000100,
447
L9PL_GETATTR_SIZE = 0x00000200,
448
L9PL_GETATTR_BLOCKS = 0x00000400,
449
/* everything up to and including BLOCKS is BASIC */
450
L9PL_GETATTR_BASIC = L9PL_GETATTR_MODE |
451
L9PL_GETATTR_NLINK |
452
L9PL_GETATTR_UID |
453
L9PL_GETATTR_GID |
454
L9PL_GETATTR_RDEV |
455
L9PL_GETATTR_ATIME |
456
L9PL_GETATTR_MTIME |
457
L9PL_GETATTR_CTIME |
458
L9PL_GETATTR_INO |
459
L9PL_GETATTR_SIZE |
460
L9PL_GETATTR_BLOCKS,
461
L9PL_GETATTR_BTIME = 0x00000800,
462
L9PL_GETATTR_GEN = 0x00001000,
463
L9PL_GETATTR_DATA_VERSION = 0x00002000,
464
/* BASIC + birthtime + gen + data-version = ALL */
465
L9PL_GETATTR_ALL = L9PL_GETATTR_BASIC |
466
L9PL_GETATTR_BTIME |
467
L9PL_GETATTR_GEN |
468
L9PL_GETATTR_DATA_VERSION,
469
};
470
471
struct l9p_f_tsetattr {
472
struct l9p_hdr hdr;
473
uint32_t valid;
474
uint32_t mode;
475
uint32_t uid;
476
uint32_t gid;
477
uint64_t size;
478
uint64_t atime_sec; /* if valid & L9PL_SETATTR_ATIME_SET */
479
uint64_t atime_nsec; /* (else use on-server time) */
480
uint64_t mtime_sec; /* if valid & L9PL_SETATTR_MTIME_SET */
481
uint64_t mtime_nsec; /* (else use on-server time) */
482
};
483
484
/* Fields in req->valid for Tsetattr. */
485
enum l9pl_setattr_flags {
486
L9PL_SETATTR_MODE = 0x00000001,
487
L9PL_SETATTR_UID = 0x00000002,
488
L9PL_SETATTR_GID = 0x00000004,
489
L9PL_SETATTR_SIZE = 0x00000008,
490
L9PL_SETATTR_ATIME = 0x00000010,
491
L9PL_SETATTR_MTIME = 0x00000020,
492
L9PL_SETATTR_CTIME = 0x00000040,
493
L9PL_SETATTR_ATIME_SET = 0x00000080,
494
L9PL_SETATTR_MTIME_SET = 0x00000100,
495
};
496
497
struct l9p_f_txattrwalk {
498
struct l9p_hdr hdr;
499
uint32_t newfid;
500
char *name;
501
};
502
503
struct l9p_f_rxattrwalk {
504
struct l9p_hdr hdr;
505
uint64_t size;
506
};
507
508
struct l9p_f_txattrcreate {
509
struct l9p_hdr hdr;
510
char *name;
511
uint64_t attr_size;
512
uint32_t flags;
513
};
514
515
struct l9p_f_tlock {
516
struct l9p_hdr hdr;
517
uint8_t type; /* from l9pl_lock_type */
518
uint32_t flags; /* from l9pl_lock_flags */
519
uint64_t start;
520
uint64_t length;
521
uint32_t proc_id;
522
char *client_id;
523
};
524
525
enum l9pl_lock_type {
526
L9PL_LOCK_TYPE_RDLOCK = 0,
527
L9PL_LOCK_TYPE_WRLOCK = 1,
528
L9PL_LOCK_TYPE_UNLOCK = 2,
529
};
530
531
enum l9pl_lock_flags {
532
L9PL_LOCK_TYPE_BLOCK = 1,
533
L9PL_LOCK_TYPE_RECLAIM = 2,
534
};
535
536
struct l9p_f_rlock {
537
struct l9p_hdr hdr;
538
uint8_t status; /* from l9pl_lock_status */
539
};
540
541
enum l9pl_lock_status {
542
L9PL_LOCK_SUCCESS = 0,
543
L9PL_LOCK_BLOCKED = 1,
544
L9PL_LOCK_ERROR = 2,
545
L9PL_LOCK_GRACE = 3,
546
};
547
548
struct l9p_f_getlock {
549
struct l9p_hdr hdr;
550
uint8_t type; /* from l9pl_lock_type */
551
uint64_t start;
552
uint64_t length;
553
uint32_t proc_id;
554
char *client_id;
555
};
556
557
struct l9p_f_tlink {
558
struct l9p_hdr hdr;
559
uint32_t dfid;
560
char *name;
561
};
562
563
struct l9p_f_trenameat {
564
struct l9p_hdr hdr;
565
char *oldname;
566
uint32_t newdirfid;
567
char *newname;
568
};
569
570
/*
571
* Flags in Tunlinkat (which re-uses f_tlcreate data structure but
572
* with different meaning).
573
*/
574
enum l9p_l_unlinkat_flags {
575
/* not sure if any other AT_* flags are passed through */
576
L9PL_AT_REMOVEDIR = 0x0200,
577
};
578
579
union l9p_fcall {
580
struct l9p_hdr hdr;
581
struct l9p_f_version version;
582
struct l9p_f_tflush tflush;
583
struct l9p_f_ropen ropen;
584
struct l9p_f_ropen rcreate;
585
struct l9p_f_ropen rattach;
586
struct l9p_f_error error;
587
struct l9p_f_rauth rauth;
588
struct l9p_f_attach tattach;
589
struct l9p_f_attach tauth;
590
struct l9p_f_tcreate tcreate;
591
struct l9p_f_tcreate topen;
592
struct l9p_f_twalk twalk;
593
struct l9p_f_rwalk rwalk;
594
struct l9p_f_twstat twstat;
595
struct l9p_f_rstat rstat;
596
struct l9p_f_rstatfs rstatfs;
597
struct l9p_f_tlcreate tlopen;
598
struct l9p_f_ropen rlopen;
599
struct l9p_f_tlcreate tlcreate;
600
struct l9p_f_ropen rlcreate;
601
struct l9p_f_tsymlink tsymlink;
602
struct l9p_f_ropen rsymlink;
603
struct l9p_f_tmknod tmknod;
604
struct l9p_f_ropen rmknod;
605
struct l9p_f_trename trename;
606
struct l9p_f_rreadlink rreadlink;
607
struct l9p_f_tgetattr tgetattr;
608
struct l9p_f_rgetattr rgetattr;
609
struct l9p_f_tsetattr tsetattr;
610
struct l9p_f_txattrwalk txattrwalk;
611
struct l9p_f_rxattrwalk rxattrwalk;
612
struct l9p_f_txattrcreate txattrcreate;
613
struct l9p_f_tlock tlock;
614
struct l9p_f_rlock rlock;
615
struct l9p_f_getlock getlock;
616
struct l9p_f_tlink tlink;
617
struct l9p_f_tlcreate tmkdir;
618
struct l9p_f_ropen rmkdir;
619
struct l9p_f_trenameat trenameat;
620
struct l9p_f_tlcreate tunlinkat;
621
struct l9p_f_io io;
622
};
623
624
#endif /* LIB9P_FCALL_H */
625
626