2 * Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted providing that the following conditions
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.
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.
29 * Based on libixp code: ©2007-2010 Kris Maglione <maglione.k at Gmail>
37 #define L9P_MAX_WELEM 256
40 * Function call/reply (Tfoo/Rfoo) numbers.
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.
46 * Note that we rely (in the debug code) on Rfoo == Tfoo+1.
49 L9P__FIRST = 6, /* NB: must be <= all legal values */
50 L9P_TLERROR = 6, /* illegal; exists for parity with Rlerror */
72 L9P_TXATTRCREATE = 32,
96 L9P_TERROR = 106, /* illegal */
118 L9P__LAST_PLUS_1, /* NB: must be last */
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
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
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.
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.
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).
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
161 * Type code bits in (the first byte of) a qid.
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 */
175 * Extra permission bits in create and file modes (stat).
177 #define L9P_DMDIR 0x80000000
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,
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.
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 */
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.
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.
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.
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,
277 #define L9P_FSTYPE 0x01021997
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 */
291 struct l9p_f_version {
297 struct l9p_f_tflush {
319 struct l9p_f_attach {
326 #define L9P_NOFID ((uint32_t)-1) /* in Tattach, no auth fid */
327 #define L9P_NONUNAME ((uint32_t)-1) /* in Tattach, no n_uname */
329 struct l9p_f_tcreate {
333 uint8_t mode; /* +Topen */
341 char *wname[L9P_MAX_WELEM];
347 struct l9p_qid wqid[L9P_MAX_WELEM];
352 uint64_t offset; /* Tread, Twrite, Treaddir */
353 uint32_t count; /* Tread, Twrite, Rread, Treaddir, Rreaddir */
358 struct l9p_stat stat;
361 struct l9p_f_twstat {
363 struct l9p_stat stat;
366 struct l9p_f_rstatfs {
368 struct l9p_statfs statfs;
371 /* Used for Tlcreate, Tlopen, Tmkdir, Tunlinkat. */
372 struct l9p_f_tlcreate {
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 */
380 struct l9p_f_tsymlink {
387 struct l9p_f_tmknod {
396 struct l9p_f_trename {
402 struct l9p_f_rreadlink {
407 struct l9p_f_tgetattr {
409 uint64_t request_mask;
412 struct l9p_f_rgetattr {
433 uint64_t data_version;
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 |
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 |
468 L9PL_GETATTR_DATA_VERSION,
471 struct l9p_f_tsetattr {
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) */
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,
497 struct l9p_f_txattrwalk {
503 struct l9p_f_rxattrwalk {
508 struct l9p_f_txattrcreate {
517 uint8_t type; /* from l9pl_lock_type */
518 uint32_t flags; /* from l9pl_lock_flags */
525 enum l9pl_lock_type {
526 L9PL_LOCK_TYPE_RDLOCK = 0,
527 L9PL_LOCK_TYPE_WRLOCK = 1,
528 L9PL_LOCK_TYPE_UNLOCK = 2,
531 enum l9pl_lock_flags {
532 L9PL_LOCK_TYPE_BLOCK = 1,
533 L9PL_LOCK_TYPE_RECLAIM = 2,
538 uint8_t status; /* from l9pl_lock_status */
541 enum l9pl_lock_status {
542 L9PL_LOCK_SUCCESS = 0,
543 L9PL_LOCK_BLOCKED = 1,
548 struct l9p_f_getlock {
550 uint8_t type; /* from l9pl_lock_type */
563 struct l9p_f_trenameat {
571 * Flags in Tunlinkat (which re-uses f_tlcreate data structure but
572 * with different meaning).
574 enum l9p_l_unlinkat_flags {
575 /* not sure if any other AT_* flags are passed through */
576 L9PL_AT_REMOVEDIR = 0x0200,
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;
624 #endif /* LIB9P_FCALL_H */