summaryrefslogtreecommitdiff
path: root/usr/src/lib/lib9p/common/fcall.h
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/lib9p/common/fcall.h')
-rw-r--r--usr/src/lib/lib9p/common/fcall.h624
1 files changed, 624 insertions, 0 deletions
diff --git a/usr/src/lib/lib9p/common/fcall.h b/usr/src/lib/lib9p/common/fcall.h
new file mode 100644
index 0000000000..f779ea6ad5
--- /dev/null
+++ b/usr/src/lib/lib9p/common/fcall.h
@@ -0,0 +1,624 @@
+/*
+ * Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted providing that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * Based on libixp code: ©2007-2010 Kris Maglione <maglione.k at Gmail>
+ */
+
+#ifndef LIB9P_FCALL_H
+#define LIB9P_FCALL_H
+
+#include <stdint.h>
+
+#define L9P_MAX_WELEM 256
+
+/*
+ * Function call/reply (Tfoo/Rfoo) numbers.
+ *
+ * These are protocol code numbers, so the exact values
+ * matter. However, __FIRST and __LAST_PLUS_ONE are for
+ * debug code, and just need to encompass the entire range.
+ *
+ * Note that we rely (in the debug code) on Rfoo == Tfoo+1.
+ */
+enum l9p_ftype {
+ L9P__FIRST = 6, /* NB: must be <= all legal values */
+ L9P_TLERROR = 6, /* illegal; exists for parity with Rlerror */
+ L9P_RLERROR,
+ L9P_TSTATFS = 8,
+ L9P_RSTATFS,
+ L9P_TLOPEN = 12,
+ L9P_RLOPEN,
+ L9P_TLCREATE = 14,
+ L9P_RLCREATE,
+ L9P_TSYMLINK = 16,
+ L9P_RSYMLINK,
+ L9P_TMKNOD = 18,
+ L9P_RMKNOD,
+ L9P_TRENAME = 20,
+ L9P_RRENAME,
+ L9P_TREADLINK = 22,
+ L9P_RREADLINK,
+ L9P_TGETATTR = 24,
+ L9P_RGETATTR,
+ L9P_TSETATTR = 26,
+ L9P_RSETATTR,
+ L9P_TXATTRWALK = 30,
+ L9P_RXATTRWALK,
+ L9P_TXATTRCREATE = 32,
+ L9P_RXATTRCREATE,
+ L9P_TREADDIR = 40,
+ L9P_RREADDIR,
+ L9P_TFSYNC = 50,
+ L9P_RFSYNC,
+ L9P_TLOCK = 52,
+ L9P_RLOCK,
+ L9P_TGETLOCK = 54,
+ L9P_RGETLOCK,
+ L9P_TLINK = 70,
+ L9P_RLINK,
+ L9P_TMKDIR = 72,
+ L9P_RMKDIR,
+ L9P_TRENAMEAT = 74,
+ L9P_RRENAMEAT,
+ L9P_TUNLINKAT = 76,
+ L9P_RUNLINKAT,
+ L9P_TVERSION = 100,
+ L9P_RVERSION,
+ L9P_TAUTH = 102,
+ L9P_RAUTH,
+ L9P_TATTACH = 104,
+ L9P_RATTACH,
+ L9P_TERROR = 106, /* illegal */
+ L9P_RERROR,
+ L9P_TFLUSH = 108,
+ L9P_RFLUSH,
+ L9P_TWALK = 110,
+ L9P_RWALK,
+ L9P_TOPEN = 112,
+ L9P_ROPEN,
+ L9P_TCREATE = 114,
+ L9P_RCREATE,
+ L9P_TREAD = 116,
+ L9P_RREAD,
+ L9P_TWRITE = 118,
+ L9P_RWRITE,
+ L9P_TCLUNK = 120,
+ L9P_RCLUNK,
+ L9P_TREMOVE = 122,
+ L9P_RREMOVE,
+ L9P_TSTAT = 124,
+ L9P_RSTAT,
+ L9P_TWSTAT = 126,
+ L9P_RWSTAT,
+ L9P__LAST_PLUS_1, /* NB: must be last */
+};
+
+/*
+ * When a Tfoo request comes over the wire, we decode it
+ * (pack.c) from wire format into a request laid out in
+ * a "union l9p_fcall" object. This object is not in wire
+ * format, but rather in something more convenient for us
+ * to operate on.
+ *
+ * We then dispatch the request (request.c, backend/fs.c) and
+ * use another "union l9p_fcall" object to build a reply.
+ * The reply is converted to wire format on the way back out
+ * (pack.c again).
+ *
+ * All sub-objects start with a header containing the request
+ * or reply type code and two-byte tag, and whether or not it
+ * is needed, a four-byte fid.
+ *
+ * What this means here is that the data structures within
+ * the union can be shared across various requests and replies.
+ * For instance, replies to OPEN, CREATE, LCREATE, LOPEN, MKDIR, and
+ * SYMLINK are all fairly similar (providing a qid and sometimes
+ * an iounit) and hence can all use the l9p_f_ropen structure.
+ * Which structures are used for which operations is somewhat
+ * arbitrary; for programming ease, if an operation shares a
+ * data structure, it still has its own name: there are union
+ * members named ropen, rcreate, rlcreate, rlopen, rmkdir, and
+ * rsymlink, even though all use struct l9p_f_ropen.
+ *
+ * The big exception to the above rule is struct l9p_f_io, which
+ * is used as both request and reply for all of READ, WRITE, and
+ * READDIR. Moreover, the READDIR reply must be pre-packed into
+ * wire format (it is handled like raw data a la READ).
+ *
+ * Some request messages (e.g., TREADLINK) fit in a header, having
+ * just type code, tag, and fid. These have no separate data
+ * structure, nor union member name. Similarly, some reply
+ * messages (e.g., RCLUNK, RREMOVE, RRENAME) have just the type
+ * code and tag.
+ */
+
+/*
+ * Type code bits in (the first byte of) a qid.
+ */
+enum l9p_qid_type {
+ L9P_QTDIR = 0x80, /* type bit for directories */
+ L9P_QTAPPEND = 0x40, /* type bit for append only files */
+ L9P_QTEXCL = 0x20, /* type bit for exclusive use files */
+ L9P_QTMOUNT = 0x10, /* type bit for mounted channel */
+ L9P_QTAUTH = 0x08, /* type bit for authentication file */
+ L9P_QTTMP = 0x04, /* type bit for non-backed-up file */
+ L9P_QTSYMLINK = 0x02, /* type bit for symbolic link */
+ L9P_QTFILE = 0x00 /* type bits for plain file */
+};
+
+/*
+ * Extra permission bits in create and file modes (stat).
+ */
+#define L9P_DMDIR 0x80000000
+enum {
+ L9P_DMAPPEND = 0x40000000,
+ L9P_DMEXCL = 0x20000000,
+ L9P_DMMOUNT = 0x10000000,
+ L9P_DMAUTH = 0x08000000,
+ L9P_DMTMP = 0x04000000,
+ L9P_DMSYMLINK = 0x02000000,
+ /* 9P2000.u extensions */
+ L9P_DMDEVICE = 0x00800000,
+ L9P_DMNAMEDPIPE = 0x00200000,
+ L9P_DMSOCKET = 0x00100000,
+ L9P_DMSETUID = 0x00080000,
+ L9P_DMSETGID = 0x00040000,
+};
+
+/*
+ * Open/create mode bits in 9P2000 and 9P2000.u operations
+ * (not Linux lopen and lcreate flags, which are different).
+ * Note that the mode field is only one byte wide.
+ */
+enum l9p_omode {
+ L9P_OREAD = 0, /* open for read */
+ L9P_OWRITE = 1, /* write */
+ L9P_ORDWR = 2, /* read and write */
+ L9P_OEXEC = 3, /* execute, == read but check execute permission */
+ L9P_OACCMODE = 3, /* mask for the above access-mode bits */
+ L9P_OTRUNC = 16, /* or'ed in (except for exec), truncate file first */
+ L9P_OCEXEC = 32, /* or'ed in, close on exec */
+ L9P_ORCLOSE = 64, /* or'ed in, remove on close */
+ L9P_ODIRECT = 128, /* or'ed in, direct access */
+};
+
+/*
+ * Flag bits in 9P2000.L operations (Tlopen, Tlcreate). These are
+ * basically just the Linux L_* flags. The bottom 3 bits are the
+ * same as for l9p_omode, although open-for-exec is not used:
+ * instead, the client does a Tgetattr and checks the mode for
+ * execute bits, then just opens for reading.
+ *
+ * Each L_O_xxx is just value O_xxx has on Linux in <fcntl.h>;
+ * not all are necessarily used. From observation, we do get
+ * L_O_CREAT and L_O_EXCL when creating with exclusive, and always
+ * get L_O_LARGEFILE. We do get L_O_APPEND when opening for
+ * append. We also get both L_O_DIRECT and L_O_DIRECTORY set
+ * when opening directories.
+ *
+ * We probably never get L_O_NOCTTY which makes no sense, and
+ * some of the other options may need to be handled on the client.
+ */
+enum l9p_l_o_flags {
+ L9P_L_O_CREAT = 000000100U,
+ L9P_L_O_EXCL = 000000200U,
+ L9P_L_O_NOCTTY = 000000400U,
+ L9P_L_O_TRUNC = 000001000U,
+ L9P_L_O_APPEND = 000002000U,
+ L9P_L_O_NONBLOCK = 000004000U,
+ L9P_L_O_DSYNC = 000010000U,
+ L9P_L_O_FASYNC = 000020000U,
+ L9P_L_O_DIRECT = 000040000U,
+ L9P_L_O_LARGEFILE = 000100000U,
+ L9P_L_O_DIRECTORY = 000200000U,
+ L9P_L_O_NOFOLLOW = 000400000U,
+ L9P_L_O_NOATIME = 001000000U,
+ L9P_L_O_CLOEXEC = 002000000U,
+ L9P_L_O_SYNC = 004000000U,
+ L9P_L_O_PATH = 010000000U,
+ L9P_L_O_TMPFILE = 020000000U,
+};
+
+struct l9p_hdr {
+ uint8_t type;
+ uint16_t tag;
+ uint32_t fid;
+};
+
+struct l9p_qid {
+ uint8_t type;
+ uint32_t version;
+ uint64_t path;
+};
+
+struct l9p_stat {
+ uint16_t type;
+ uint32_t dev;
+ struct l9p_qid qid;
+ uint32_t mode;
+ uint32_t atime;
+ uint32_t mtime;
+ uint64_t length;
+ char *name;
+ char *uid;
+ char *gid;
+ char *muid;
+ char *extension;
+ uint32_t n_uid;
+ uint32_t n_gid;
+ uint32_t n_muid;
+};
+
+#define L9P_FSTYPE 0x01021997
+
+struct l9p_statfs {
+ uint32_t type; /* file system type */
+ uint32_t bsize; /* block size for I/O */
+ uint64_t blocks; /* file system size (bsize-byte blocks) */
+ uint64_t bfree; /* free blocks in fs */
+ uint64_t bavail; /* free blocks avail to non-superuser*/
+ uint64_t files; /* file nodes in file system (# inodes) */
+ uint64_t ffree; /* free file nodes in fs */
+ uint64_t fsid; /* file system identifier */
+ uint32_t namelen; /* maximum length of filenames */
+};
+
+struct l9p_f_version {
+ struct l9p_hdr hdr;
+ uint32_t msize;
+ char *version;
+};
+
+struct l9p_f_tflush {
+ struct l9p_hdr hdr;
+ uint16_t oldtag;
+};
+
+struct l9p_f_error {
+ struct l9p_hdr hdr;
+ char *ename;
+ uint32_t errnum;
+};
+
+struct l9p_f_ropen {
+ struct l9p_hdr hdr;
+ struct l9p_qid qid;
+ uint32_t iounit;
+};
+
+struct l9p_f_rauth {
+ struct l9p_hdr hdr;
+ struct l9p_qid aqid;
+};
+
+struct l9p_f_attach {
+ struct l9p_hdr hdr;
+ uint32_t afid;
+ char *uname;
+ char *aname;
+ uint32_t n_uname;
+};
+#define L9P_NOFID ((uint32_t)-1) /* in Tattach, no auth fid */
+#define L9P_NONUNAME ((uint32_t)-1) /* in Tattach, no n_uname */
+
+struct l9p_f_tcreate {
+ struct l9p_hdr hdr;
+ uint32_t perm;
+ char *name;
+ uint8_t mode; /* +Topen */
+ char *extension;
+};
+
+struct l9p_f_twalk {
+ struct l9p_hdr hdr;
+ uint32_t newfid;
+ uint16_t nwname;
+ char *wname[L9P_MAX_WELEM];
+};
+
+struct l9p_f_rwalk {
+ struct l9p_hdr hdr;
+ uint16_t nwqid;
+ struct l9p_qid wqid[L9P_MAX_WELEM];
+};
+
+struct l9p_f_io {
+ struct l9p_hdr hdr;
+ uint64_t offset; /* Tread, Twrite, Treaddir */
+ uint32_t count; /* Tread, Twrite, Rread, Treaddir, Rreaddir */
+};
+
+struct l9p_f_rstat {
+ struct l9p_hdr hdr;
+ struct l9p_stat stat;
+};
+
+struct l9p_f_twstat {
+ struct l9p_hdr hdr;
+ struct l9p_stat stat;
+};
+
+struct l9p_f_rstatfs {
+ struct l9p_hdr hdr;
+ struct l9p_statfs statfs;
+};
+
+/* Used for Tlcreate, Tlopen, Tmkdir, Tunlinkat. */
+struct l9p_f_tlcreate {
+ struct l9p_hdr hdr;
+ char *name; /* Tlcreate, Tmkdir, Tunlinkat */
+ uint32_t flags; /* Tlcreate, Tlopen, Tmkdir, Tunlinkat */
+ uint32_t mode; /* Tlcreate, Tmkdir */
+ uint32_t gid; /* Tlcreate, Tmkdir */
+};
+
+struct l9p_f_tsymlink {
+ struct l9p_hdr hdr;
+ char *name;
+ char *symtgt;
+ uint32_t gid;
+};
+
+struct l9p_f_tmknod {
+ struct l9p_hdr hdr;
+ char *name;
+ uint32_t mode;
+ uint32_t major;
+ uint32_t minor;
+ uint32_t gid;
+};
+
+struct l9p_f_trename {
+ struct l9p_hdr hdr;
+ uint32_t dfid;
+ char *name;
+};
+
+struct l9p_f_rreadlink {
+ struct l9p_hdr hdr;
+ char *target;
+};
+
+struct l9p_f_tgetattr {
+ struct l9p_hdr hdr;
+ uint64_t request_mask;
+};
+
+struct l9p_f_rgetattr {
+ struct l9p_hdr hdr;
+ uint64_t valid;
+ struct l9p_qid qid;
+ uint32_t mode;
+ uint32_t uid;
+ uint32_t gid;
+ uint64_t nlink;
+ uint64_t rdev;
+ uint64_t size;
+ uint64_t blksize;
+ uint64_t blocks;
+ uint64_t atime_sec;
+ uint64_t atime_nsec;
+ uint64_t mtime_sec;
+ uint64_t mtime_nsec;
+ uint64_t ctime_sec;
+ uint64_t ctime_nsec;
+ uint64_t btime_sec;
+ uint64_t btime_nsec;
+ uint64_t gen;
+ uint64_t data_version;
+};
+
+/* Fields in req->request_mask and reply->valid for Tgetattr, Rgetattr. */
+enum l9pl_getattr_flags {
+ L9PL_GETATTR_MODE = 0x00000001,
+ L9PL_GETATTR_NLINK = 0x00000002,
+ L9PL_GETATTR_UID = 0x00000004,
+ L9PL_GETATTR_GID = 0x00000008,
+ L9PL_GETATTR_RDEV = 0x00000010,
+ L9PL_GETATTR_ATIME = 0x00000020,
+ L9PL_GETATTR_MTIME = 0x00000040,
+ L9PL_GETATTR_CTIME = 0x00000080,
+ L9PL_GETATTR_INO = 0x00000100,
+ L9PL_GETATTR_SIZE = 0x00000200,
+ L9PL_GETATTR_BLOCKS = 0x00000400,
+ /* everything up to and including BLOCKS is BASIC */
+ L9PL_GETATTR_BASIC = L9PL_GETATTR_MODE |
+ L9PL_GETATTR_NLINK |
+ L9PL_GETATTR_UID |
+ L9PL_GETATTR_GID |
+ L9PL_GETATTR_RDEV |
+ L9PL_GETATTR_ATIME |
+ L9PL_GETATTR_MTIME |
+ L9PL_GETATTR_CTIME |
+ L9PL_GETATTR_INO |
+ L9PL_GETATTR_SIZE |
+ L9PL_GETATTR_BLOCKS,
+ L9PL_GETATTR_BTIME = 0x00000800,
+ L9PL_GETATTR_GEN = 0x00001000,
+ L9PL_GETATTR_DATA_VERSION = 0x00002000,
+ /* BASIC + birthtime + gen + data-version = ALL */
+ L9PL_GETATTR_ALL = L9PL_GETATTR_BASIC |
+ L9PL_GETATTR_BTIME |
+ L9PL_GETATTR_GEN |
+ L9PL_GETATTR_DATA_VERSION,
+};
+
+struct l9p_f_tsetattr {
+ struct l9p_hdr hdr;
+ uint32_t valid;
+ uint32_t mode;
+ uint32_t uid;
+ uint32_t gid;
+ uint64_t size;
+ uint64_t atime_sec; /* if valid & L9PL_SETATTR_ATIME_SET */
+ uint64_t atime_nsec; /* (else use on-server time) */
+ uint64_t mtime_sec; /* if valid & L9PL_SETATTR_MTIME_SET */
+ uint64_t mtime_nsec; /* (else use on-server time) */
+};
+
+/* Fields in req->valid for Tsetattr. */
+enum l9pl_setattr_flags {
+ L9PL_SETATTR_MODE = 0x00000001,
+ L9PL_SETATTR_UID = 0x00000002,
+ L9PL_SETATTR_GID = 0x00000004,
+ L9PL_SETATTR_SIZE = 0x00000008,
+ L9PL_SETATTR_ATIME = 0x00000010,
+ L9PL_SETATTR_MTIME = 0x00000020,
+ L9PL_SETATTR_CTIME = 0x00000040,
+ L9PL_SETATTR_ATIME_SET = 0x00000080,
+ L9PL_SETATTR_MTIME_SET = 0x00000100,
+};
+
+struct l9p_f_txattrwalk {
+ struct l9p_hdr hdr;
+ uint32_t newfid;
+ char *name;
+};
+
+struct l9p_f_rxattrwalk {
+ struct l9p_hdr hdr;
+ uint64_t size;
+};
+
+struct l9p_f_txattrcreate {
+ struct l9p_hdr hdr;
+ char *name;
+ uint64_t attr_size;
+ uint32_t flags;
+};
+
+struct l9p_f_tlock {
+ struct l9p_hdr hdr;
+ uint8_t type; /* from l9pl_lock_type */
+ uint32_t flags; /* from l9pl_lock_flags */
+ uint64_t start;
+ uint64_t length;
+ uint32_t proc_id;
+ char *client_id;
+};
+
+enum l9pl_lock_type {
+ L9PL_LOCK_TYPE_RDLOCK = 0,
+ L9PL_LOCK_TYPE_WRLOCK = 1,
+ L9PL_LOCK_TYPE_UNLOCK = 2,
+};
+
+enum l9pl_lock_flags {
+ L9PL_LOCK_TYPE_BLOCK = 1,
+ L9PL_LOCK_TYPE_RECLAIM = 2,
+};
+
+struct l9p_f_rlock {
+ struct l9p_hdr hdr;
+ uint8_t status; /* from l9pl_lock_status */
+};
+
+enum l9pl_lock_status {
+ L9PL_LOCK_SUCCESS = 0,
+ L9PL_LOCK_BLOCKED = 1,
+ L9PL_LOCK_ERROR = 2,
+ L9PL_LOCK_GRACE = 3,
+};
+
+struct l9p_f_getlock {
+ struct l9p_hdr hdr;
+ uint8_t type; /* from l9pl_lock_type */
+ uint64_t start;
+ uint64_t length;
+ uint32_t proc_id;
+ char *client_id;
+};
+
+struct l9p_f_tlink {
+ struct l9p_hdr hdr;
+ uint32_t dfid;
+ char *name;
+};
+
+struct l9p_f_trenameat {
+ struct l9p_hdr hdr;
+ char *oldname;
+ uint32_t newdirfid;
+ char *newname;
+};
+
+/*
+ * Flags in Tunlinkat (which re-uses f_tlcreate data structure but
+ * with different meaning).
+ */
+enum l9p_l_unlinkat_flags {
+ /* not sure if any other AT_* flags are passed through */
+ L9PL_AT_REMOVEDIR = 0x0200,
+};
+
+union l9p_fcall {
+ struct l9p_hdr hdr;
+ struct l9p_f_version version;
+ struct l9p_f_tflush tflush;
+ struct l9p_f_ropen ropen;
+ struct l9p_f_ropen rcreate;
+ struct l9p_f_ropen rattach;
+ struct l9p_f_error error;
+ struct l9p_f_rauth rauth;
+ struct l9p_f_attach tattach;
+ struct l9p_f_attach tauth;
+ struct l9p_f_tcreate tcreate;
+ struct l9p_f_tcreate topen;
+ struct l9p_f_twalk twalk;
+ struct l9p_f_rwalk rwalk;
+ struct l9p_f_twstat twstat;
+ struct l9p_f_rstat rstat;
+ struct l9p_f_rstatfs rstatfs;
+ struct l9p_f_tlcreate tlopen;
+ struct l9p_f_ropen rlopen;
+ struct l9p_f_tlcreate tlcreate;
+ struct l9p_f_ropen rlcreate;
+ struct l9p_f_tsymlink tsymlink;
+ struct l9p_f_ropen rsymlink;
+ struct l9p_f_tmknod tmknod;
+ struct l9p_f_ropen rmknod;
+ struct l9p_f_trename trename;
+ struct l9p_f_rreadlink rreadlink;
+ struct l9p_f_tgetattr tgetattr;
+ struct l9p_f_rgetattr rgetattr;
+ struct l9p_f_tsetattr tsetattr;
+ struct l9p_f_txattrwalk txattrwalk;
+ struct l9p_f_rxattrwalk rxattrwalk;
+ struct l9p_f_txattrcreate txattrcreate;
+ struct l9p_f_tlock tlock;
+ struct l9p_f_rlock rlock;
+ struct l9p_f_getlock getlock;
+ struct l9p_f_tlink tlink;
+ struct l9p_f_tlcreate tmkdir;
+ struct l9p_f_ropen rmkdir;
+ struct l9p_f_trenameat trenameat;
+ struct l9p_f_tlcreate tunlinkat;
+ struct l9p_f_io io;
+};
+
+#endif /* LIB9P_FCALL_H */