aboutsummaryrefslogtreecommitdiffstats
path: root/sys/linux/9p.txt
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-07-08 15:08:48 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-07-08 22:52:24 +0200
commiteb5690a56d4a550498e4c0540eb4fa703c9b87e9 (patch)
tree29dda291fab8cbf0bc9d00f30d6a03412de8a779 /sys/linux/9p.txt
parent1c667063a8d344ba09336ad43c69a2de5487f056 (diff)
sys/linux: extend 9p descriptions
Add actual protocol messages.
Diffstat (limited to 'sys/linux/9p.txt')
-rw-r--r--sys/linux/9p.txt288
1 files changed, 258 insertions, 30 deletions
diff --git a/sys/linux/9p.txt b/sys/linux/9p.txt
index 5f2c87a80..3cddaf407 100644
--- a/sys/linux/9p.txt
+++ b/sys/linux/9p.txt
@@ -1,42 +1,274 @@
# Copyright 2018 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+# 9p2000 mount/server descriptions. For protocol description see:
+# http://knusbaum.com/useful/rfc9p2000
+# http://ericvh.github.io/9p-rfc/rfc9p2000.html
+# http://ericvh.github.io/9p-rfc/rfc9p2000.u.html
+# https://github.com/chaos/diod/blob/master/protocol.md
+
include <linux/fs.h>
+include <net/9p/9p.h>
+
+resource rfd9p[fd]
+resource wfd9p[fd]
-mount$9p_fd(src ptr[in, string], dst ptr[in, filename], type ptr[in, string["9p"]], flags flags[mount_flags], opts ptr[in, fs9p_options_trans["fd"]])
-mount$9p_tcp(src ptr[in, string[ipv4_addr_str]], dst ptr[in, filename], type ptr[in, string["9p"]], flags flags[mount_flags], opts ptr[in, fs9p_options_trans["tcp"]])
-mount$9p_rdma(src ptr[in, string[ipv4_addr_str]], dst ptr[in, filename], type ptr[in, string["9p"]], flags flags[mount_flags], opts ptr[in, fs9p_options_trans["rdma"]])
-mount$9p_unix(src ptr[in, filename], dst ptr[in, filename], type ptr[in, string["9p"]], flags flags[mount_flags], opts ptr[in, fs9p_options_trans["unix"]])
+mount$9p_fd(src const[0], dst ptr[in, filename], type ptr[in, string["9p"]], flags flags[mount_flags], opts ptr[in, p9_options_fd])
+mount$9p_tcp(src ptr[in, string["127.0.0.1"]], dst ptr[in, filename], type ptr[in, string["9p"]], flags flags[mount_flags], opts ptr[in, p9_options_tcp])
+mount$9p_unix(src ptr[in, filename], dst ptr[in, filename], type ptr[in, string["9p"]], flags flags[mount_flags], opts ptr[in, p9_options_unix])
+mount$9p_rdma(src ptr[in, string["127.0.0.1"]], dst ptr[in, filename], type ptr[in, string["9p"]], flags flags[mount_flags], opts ptr[in, p9_options_rdma])
# TODO: src is some "virtio chan tag name".
-mount$9p_virtio(src ptr[in, string], dst ptr[in, filename], type ptr[in, string["9p"]], flags flags[mount_flags], opts ptr[in, fs9p_options_trans["virtio"]])
+mount$9p_virtio(src ptr[in, string], dst ptr[in, filename], type ptr[in, string["9p"]], flags flags[mount_flags], opts ptr[in, p9_options_virtio])
# TODO: src is some "xen dev tag name".
-mount$9p_xen(src ptr[in, string], dst ptr[in, filename], type ptr[in, string["9p"]], flags flags[mount_flags], opts ptr[in, fs9p_options_trans["xen"]])
+mount$9p_xen(src ptr[in, string], dst ptr[in, filename], type ptr[in, string["9p"]], flags flags[mount_flags], opts ptr[in, p9_options_xen])
+
+pipe2$9p(pipefd ptr[out, pipe_9p], flags flags[pipe_flags])
+
+pipe_9p {
+ rfd rfd9p
+ wfd wfd9p
+}
+
+write$9p(fd wfd9p, data ptr[in, array[int8]], size bytesize[data])
+
+write$P9_RLERROR(fd wfd9p, data ptr[in, p9_msg[P9_RLERROR, p9_rerror]], size bytesize[data])
+write$P9_RLERRORu(fd wfd9p, data ptr[in, p9_msg[P9_RLERROR, p9_rerroru]], size bytesize[data])
+write$P9_RVERSION(fd wfd9p, data ptr[in, p9_msg[P9_RVERSION, p9_rversion]], size bytesize[data])
+write$P9_RAUTH(fd wfd9p, data ptr[in, p9_msg[P9_RAUTH, p9_qid]], size bytesize[data])
+write$P9_RFLUSH(fd wfd9p, data ptr[in, p9_msg[P9_RFLUSH, void]], size bytesize[data])
+write$P9_RATTACH(fd wfd9p, data ptr[in, p9_msg[P9_RATTACH, p9_qid]], size bytesize[data])
+write$P9_RWALK(fd wfd9p, data ptr[in, p9_msg[P9_RWALK, p9_rwalk]], size bytesize[data])
+write$P9_ROPEN(fd wfd9p, data ptr[in, p9_msg[P9_ROPEN, p9_ropen]], size bytesize[data])
+write$P9_RCREATE(fd wfd9p, data ptr[in, p9_msg[P9_RCREATE, p9_ropen]], size bytesize[data])
+write$P9_RREAD(fd wfd9p, data ptr[in, p9_msg[P9_RREAD, p9_rread]], size bytesize[data])
+write$P9_RWRITE(fd wfd9p, data ptr[in, p9_msg[P9_RWRITE, int32]], size bytesize[data])
+write$P9_RCLUNK(fd wfd9p, data ptr[in, p9_msg[P9_RCLUNK, void]], size bytesize[data])
+write$P9_RREMOVE(fd wfd9p, data ptr[in, p9_msg[P9_RREMOVE, void]], size bytesize[data])
+write$P9_RWSTAT(fd wfd9p, data ptr[in, p9_msg[P9_RWSTAT, void]], size bytesize[data])
+write$P9_RSTAT(fd wfd9p, data ptr[in, p9_msg[P9_RSTAT, p9_rstat]], size bytesize[data])
+write$P9_RSTATu(fd wfd9p, data ptr[in, p9_msg[P9_RSTAT, p9_rstatu]], size bytesize[data])
+write$P9_RSTATFS(fd wfd9p, data ptr[in, p9_msg[P9_RSTATFS, p9_rstatfs]], size bytesize[data])
+write$P9_RLOPEN(fd wfd9p, data ptr[in, p9_msg[P9_RLOPEN, p9_ropen]], size bytesize[data])
+write$P9_RLCREATE(fd wfd9p, data ptr[in, p9_msg[P9_RLCREATE, p9_ropen]], size bytesize[data])
+write$P9_RSYMLINK(fd wfd9p, data ptr[in, p9_msg[P9_RSYMLINK, p9_qid]], size bytesize[data])
+write$P9_RMKNOD(fd wfd9p, data ptr[in, p9_msg[P9_RMKNOD, p9_qid]], size bytesize[data])
+write$P9_RRENAME(fd wfd9p, data ptr[in, p9_msg[P9_RRENAME, void]], size bytesize[data])
+write$P9_RREADLINK(fd wfd9p, data ptr[in, p9_msg[P9_RREADLINK, p9_rreadlink]], size bytesize[data])
+write$P9_RGETATTR(fd wfd9p, data ptr[in, p9_msg[P9_RGETATTR, p9_rgetattr]], size bytesize[data])
+write$P9_RSETATTR(fd wfd9p, data ptr[in, p9_msg[P9_RSETATTR, void]], size bytesize[data])
+write$P9_RXATTRWALK(fd wfd9p, data ptr[in, p9_msg[P9_RXATTRWALK, int64]], size bytesize[data])
+write$P9_RXATTRCREATE(fd wfd9p, data ptr[in, p9_msg[P9_RXATTRCREATE, void]], size bytesize[data])
+write$P9_RREADDIR(fd wfd9p, data ptr[in, p9_msg[P9_RREADDIR, p9_rreaddir]], size bytesize[data])
+write$P9_RFSYNC(fd wfd9p, data ptr[in, p9_msg[P9_RFSYNC, void]], size bytesize[data])
+write$P9_RLOCK(fd wfd9p, data ptr[in, p9_msg[P9_RLOCK, flags[p9_lock_status, int8]]], size bytesize[data])
+write$P9_RGETLOCK(fd wfd9p, data ptr[in, p9_msg[P9_RGETLOCK, p9_rgetlock]], size bytesize[data])
+write$P9_RLINK(fd wfd9p, data ptr[in, p9_msg[P9_RLINK, void]], size bytesize[data])
+write$P9_RMKDIR(fd wfd9p, data ptr[in, p9_msg[P9_RMKDIR, p9_qid]], size bytesize[data])
+write$P9_RRENAMEAT(fd wfd9p, data ptr[in, p9_msg[P9_RRENAMEAT, void]], size bytesize[data])
+write$P9_RUNLINKAT(fd wfd9p, data ptr[in, p9_msg[P9_RUNLINKAT, void]], size bytesize[data])
+
+type p9_msg[MSG, PAYLOAD] {
+ size bytesize[parent, int32]
+ type const[MSG, int8]
+ tag int16[1:4]
+ payload PAYLOAD
+} [packed]
+
+p9_rerror {
+ ename_len len[ename, int16]
+ ename stringnoz
+} [packed]
+
+p9_rerroru {
+ error p9_rerror
+ errno int32
+} [packed]
+
+p9_rversion {
+ msize int32
+ version_len len[version, int16]
+ version stringnoz[p9_versions]
+} [packed]
+
+p9_versions = "9P2000", "9P2000.u", "9P2000.L"
+
+p9_qid {
+ type flags[p9_qid_types, int8]
+ version int32[0:4]
+ path int64[0:8]
+} [packed]
+
+p9_qid_types = P9_QTDIR, P9_QTAPPEND, P9_QTEXCL, P9_QTMOUNT, P9_QTAUTH, P9_QTTMP, P9_QTSYMLINK, P9_QTLINK, P9_QTFILE
+
+p9_rwalk {
+ nwqid len[wqid, int16]
+ wqid array[p9_qid]
+} [packed]
+
+p9_ropen {
+ qid p9_qid
+ iounit int32
+} [packed]
+
+p9_rread {
+ count bytesize[data, int32]
+ data array[int8]
+} [packed]
+
+p9_rstat {
+# I can't find this in any protocol descriptions, but linux seems to expect another int16 field here.
+ ignored const[0, int16]
+ size bytesize[parent, int16]
+ type int16
+ dev int32
+ qid p9_qid
+ mode flags[p9_perm_t, int32]
+ atime int32
+ mtime int32
+ length int64
+ name_len len[name, int16]
+ name stringnoz
+ uid_len len[uid, int16]
+ uid stringnoz
+ gid_len len[gid, int16]
+ gid stringnoz
+ muid_len len[muid, int16]
+ muid stringnoz
+} [packed]
+
+p9_rstatu {
+ rstat p9_rstat
+ extension_len len[extension, int16]
+ extension stringnoz
+ n_uid uid
+ n_gid gid
+ n_muid uid
+} [packed]
-# TODO: need to convert ip addresses to string.
-ipv4_addr_str = "0.0.0.0", "127.0.0.1", "224.0.0.1", "224.0.0.2", "225.225.225.225", "224.20.20.170", "224.20.20.187", "224.20.20.0", "224.20.20.10", "224.20.20.11", "224.20.20.12", "224.20.20.13", "224.20.20.14", "224.20.20.14", "224.20.20.16", "224.20.20.17", "224.20.20.18", "224.20.20.19", "224.20.20.20", "224.20.20.21", "224.20.20.22", "224.20.20.23", "224.20.20.24", "224.20.20.25", "224.20.20.26", "224.20.20.27", "224.20.20.28", "224.20.20.29", "224.20.20.30", "224.20.20.31", "224.20.20.32", "224.20.20.33"
+p9_perm_t = P9_DMDIR, P9_DMAPPEND, P9_DMEXCL, P9_DMMOUNT, P9_DMAUTH, P9_DMTMP, P9_DMSYMLINK, P9_DMLINK, P9_DMDEVICE, P9_DMNAMEDPIPE, P9_DMSOCKET, P9_DMSETUID, P9_DMSETGID, P9_DMSETVTX
-type fs9p_options_trans[TRANSPORT] {
- name stringnoz["trans="]
- trans stringnoz[TRANSPORT]
+p9_rreadlink {
+ target_len len[target, int16]
+ target stringnoz[filename]
+} [packed]
+
+p9_rstatfs {
+ type int32
+ bsize int32
+ blocks int64
+ bfree int64
+ bavail int64
+ files int64
+ ffree int64
+ fsid int64
+ namelen int32
+} [packed]
+
+p9_rgetattr {
+ valid flags[p8_stats_valid, int64]
+ qid p9_qid
+ mode flags[open_mode, int32]
+ uid uid
+ gid gid
+ nlink int64
+ rdev int64
+ size int64
+ blksize int64
+ blocks int64
+ atime_sec int64
+ atime_nsec int64
+ mtime_sec int64
+ mtime_nsec int64
+ ctime_sec int64
+ ctime_nsec int64
+ btime_sec int64
+ btime_nsec int64
+ gen int64
+ data_version int64
+} [packed]
+
+p8_stats_valid = P9_STATS_MODE, P9_STATS_NLINK, P9_STATS_UID, P9_STATS_GID, P9_STATS_RDEV, P9_STATS_ATIME, P9_STATS_MTIME, P9_STATS_CTIME, P9_STATS_INO, P9_STATS_SIZE, P9_STATS_BLOCKS, P9_STATS_BTIME, P9_STATS_GEN, P9_STATS_DATA_VERSION
+
+p9_lock_status = P9_LOCK_SUCCESS, P9_LOCK_BLOCKED, P9_LOCK_ERROR, P9_LOCK_GRACE
+p9_lock_type = P9_LOCK_TYPE_RDLCK, P9_LOCK_TYPE_WRLCK, P9_LOCK_TYPE_UNLCK
+
+p9_rreaddir {
+ count int32
+ entries array[p9_dir]
+} [packed]
+
+p9_dir {
+ qid p9_qid
+ offset int64
+ type int8
+ name_len len[name, int16]
+ name stringnoz[filename]
+} [packed]
+
+p9_rgetlock {
+ type flags[p9_lock_type, int8]
+ start int64
+ length int64
+ proc_id pid
+ client_id_len len[client_id, int16]
+ client_id stringnoz
+} [packed]
+
+# Mount options.
+
+p9_options_fd {
+ trans stringnoz["trans=fd,"]
+ rfdno fs_opt_hex["rfdno", rfd9p]
+ comma0 const[',', int8]
+ wfdno fs_opt_hex["wfdno", fd]
comma1 const[',', int8]
-# TODO: we give all transport-required options, perhaps need something better.
- port fs_opt_dec["port"]
- comma2 const[',', int8]
- rfdno fs_opt_dec["rfdno"]
- comma3 const[',', int8]
- wfdno fs_opt_dec["wfdno"]
- comma4 const[',', int8]
- opts fs_options[fs9p_options]
+ opts fs_options[p9_options]
+} [packed]
+
+p9_options_tcp {
+ trans stringnoz["trans=tcp,"]
+ port fs_opt_hex["port", sock_port]
+ comma0 const[',', int8]
+ opts fs_options[p9_options]
+} [packed]
+
+p9_options_unix {
+ name stringnoz["trans=unix,"]
+ opts fs_options[p9_options]
+} [packed]
+
+p9_options_rdma {
+ trans stringnoz["trans=rdma,"]
+ port fs_opt_hex["port", sock_port]
+ comma0 const[',', int8]
+ opts fs_options[p9_options_rdma_opt]
+} [packed]
+
+p9_options_rdma_opt [
+ common p9_options
+ timeout fs_opt_dec1["timeout", intptr]
+ sq fs_opt_dec1["sq", intptr]
+ rq fs_opt_dec1["rq", intptr]
+] [varlen]
+
+p9_options_virtio {
+ trans stringnoz["trans=virtio,"]
+ opts fs_options[p9_options]
+} [packed]
+
+p9_options_xen {
+ trans stringnoz["trans=xen,"]
+ opts fs_options[p9_options]
} [packed]
-fs9p_options [
+p9_options [
uname fs_opt_str["uname"]
aname fs_opt_str["aname"]
cache_none stringnoz["cache=none"]
cache_loose stringnoz["cache=loose"]
cache_fscache stringnoz["cache=fscache"]
cache_mmap stringnoz["cache=mmap"]
- debug fs_opt_dec["debug"]
+ debug fs_opt_hex["debug", int64]
noextend stringnoz["noextend"]
nodevmap stringnoz["nodevmap"]
version_9p2000 stringnoz["version=9p2000"]
@@ -48,16 +280,12 @@ fs9p_options [
mmap stringnoz["mmap"]
posixacl stringnoz["posixacl"]
privport stringnoz["privport"]
- msize fs_opt_dec["msize"]
- dfltuid fs_opt_dec["dfltuid"]
- dfltgid fs_opt_dec["dfltgid"]
- afid fs_opt_dec["afid"]
+ msize fs_opt_hex["msize", int32]
+ dfltuid fs_opt_hex["dfltuid", uid]
+ dfltgid fs_opt_hex["dfltgid", gid]
+ afid fs_opt_hex["afid", int32]
access_user stringnoz["access=user"]
access_any stringnoz["access=any"]
access_client stringnoz["access=client"]
- access_uid fs_opt_dec["access"]
-# There are rdma-specific:
- timeout fs_opt_dec["timeout"]
- sq fs_opt_dec["sq"]
- rq fs_opt_dec["rq"]
+ access_uid fs_opt_dec1["access", uid]
] [varlen]