1# Copyright 2018 syzkaller project authors. All rights reserved.
2# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
3
4# 9p2000 mount/server descriptions. For protocol description see:
5# http://knusbaum.com/useful/rfc9p2000
6# http://ericvh.github.io/9p-rfc/rfc9p2000.html
7# http://ericvh.github.io/9p-rfc/rfc9p2000.u.html
8# https://github.com/chaos/diod/blob/master/protocol.md
9
10include <linux/fs.h>
11include <net/9p/9p.h>
12
13resource rfd9p[fd]
14resource wfd9p[fd]
15
16mount$9p_fd(src const[0], dst ptr[in, filename], type ptr[in, string["9p"]], flags flags[mount_flags], opts ptr[in, p9_options_fd])
17mount$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])
18mount$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])
19mount$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])
20# TODO: src is some "virtio chan tag name".
21mount$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])
22# TODO: src is some "xen dev tag name".
23mount$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])
24
25pipe2$9p(pipefd ptr[out, pipe_9p], flags flags[pipe_flags])
26
27pipe_9p {
28	rfd	rfd9p
29	wfd	wfd9p
30}
31
32write$9p(fd wfd9p, data ptr[in, array[int8]], size bytesize[data])
33
34write$P9_RLERROR(fd wfd9p, data ptr[in, p9_msg[P9_RLERROR, p9_rerror]], size bytesize[data])
35write$P9_RLERRORu(fd wfd9p, data ptr[in, p9_msg[P9_RLERROR, p9_rerroru]], size bytesize[data])
36write$P9_RVERSION(fd wfd9p, data ptr[in, p9_rversion], size bytesize[data])
37write$P9_RAUTH(fd wfd9p, data ptr[in, p9_msg[P9_RAUTH, p9_qid]], size bytesize[data])
38write$P9_RFLUSH(fd wfd9p, data ptr[in, p9_msg[P9_RFLUSH, void]], size bytesize[data])
39write$P9_RATTACH(fd wfd9p, data ptr[in, p9_msg[P9_RATTACH, p9_qid]], size bytesize[data])
40write$P9_RWALK(fd wfd9p, data ptr[in, p9_msg[P9_RWALK, p9_rwalk]], size bytesize[data])
41write$P9_ROPEN(fd wfd9p, data ptr[in, p9_msg[P9_ROPEN, p9_ropen]], size bytesize[data])
42write$P9_RCREATE(fd wfd9p, data ptr[in, p9_msg[P9_RCREATE, p9_ropen]], size bytesize[data])
43write$P9_RREAD(fd wfd9p, data ptr[in, p9_msg[P9_RREAD, p9_rread]], size bytesize[data])
44write$P9_RWRITE(fd wfd9p, data ptr[in, p9_msg[P9_RWRITE, int32]], size bytesize[data])
45write$P9_RCLUNK(fd wfd9p, data ptr[in, p9_msg[P9_RCLUNK, void]], size bytesize[data])
46write$P9_RREMOVE(fd wfd9p, data ptr[in, p9_msg[P9_RREMOVE, void]], size bytesize[data])
47write$P9_RWSTAT(fd wfd9p, data ptr[in, p9_msg[P9_RWSTAT, void]], size bytesize[data])
48write$P9_RSTAT(fd wfd9p, data ptr[in, p9_msg[P9_RSTAT, p9_rstat]], size bytesize[data])
49write$P9_RSTATu(fd wfd9p, data ptr[in, p9_msg[P9_RSTAT, p9_rstatu]], size bytesize[data])
50write$P9_RSTATFS(fd wfd9p, data ptr[in, p9_msg[P9_RSTATFS, p9_rstatfs]], size bytesize[data])
51write$P9_RLOPEN(fd wfd9p, data ptr[in, p9_msg[P9_RLOPEN, p9_ropen]], size bytesize[data])
52write$P9_RLCREATE(fd wfd9p, data ptr[in, p9_msg[P9_RLCREATE, p9_ropen]], size bytesize[data])
53write$P9_RSYMLINK(fd wfd9p, data ptr[in, p9_msg[P9_RSYMLINK, p9_qid]], size bytesize[data])
54write$P9_RMKNOD(fd wfd9p, data ptr[in, p9_msg[P9_RMKNOD, p9_qid]], size bytesize[data])
55write$P9_RRENAME(fd wfd9p, data ptr[in, p9_msg[P9_RRENAME, void]], size bytesize[data])
56write$P9_RREADLINK(fd wfd9p, data ptr[in, p9_msg[P9_RREADLINK, p9_rreadlink]], size bytesize[data])
57write$P9_RGETATTR(fd wfd9p, data ptr[in, p9_msg[P9_RGETATTR, p9_rgetattr]], size bytesize[data])
58write$P9_RSETATTR(fd wfd9p, data ptr[in, p9_msg[P9_RSETATTR, void]], size bytesize[data])
59write$P9_RXATTRWALK(fd wfd9p, data ptr[in, p9_msg[P9_RXATTRWALK, int64]], size bytesize[data])
60write$P9_RXATTRCREATE(fd wfd9p, data ptr[in, p9_msg[P9_RXATTRCREATE, void]], size bytesize[data])
61write$P9_RREADDIR(fd wfd9p, data ptr[in, p9_msg[P9_RREADDIR, p9_rreaddir]], size bytesize[data])
62write$P9_RFSYNC(fd wfd9p, data ptr[in, p9_msg[P9_RFSYNC, void]], size bytesize[data])
63write$P9_RLOCK(fd wfd9p, data ptr[in, p9_msg[P9_RLOCK, flags[p9_lock_status, int8]]], size bytesize[data])
64write$P9_RGETLOCK(fd wfd9p, data ptr[in, p9_msg[P9_RGETLOCK, p9_rgetlock]], size bytesize[data])
65write$P9_RLINK(fd wfd9p, data ptr[in, p9_msg[P9_RLINK, void]], size bytesize[data])
66write$P9_RMKDIR(fd wfd9p, data ptr[in, p9_msg[P9_RMKDIR, p9_qid]], size bytesize[data])
67write$P9_RRENAMEAT(fd wfd9p, data ptr[in, p9_msg[P9_RRENAMEAT, void]], size bytesize[data])
68write$P9_RUNLINKAT(fd wfd9p, data ptr[in, p9_msg[P9_RUNLINKAT, void]], size bytesize[data])
69
70type p9_msg[MSG, PAYLOAD] {
71	size	bytesize[parent, int32]
72	type	const[MSG, int8]
73	tag	int16[1:2]
74	payload	PAYLOAD
75} [packed]
76
77p9_rerror {
78	ename_len	len[ename, int16]
79	ename		stringnoz
80} [packed]
81
82p9_rerroru {
83	error	p9_rerror
84	errno	int32
85} [packed]
86
87p9_rversion {
88	size		bytesize[parent, int32]
89	type		const[P9_RVERSION, int8]
90	tag		const[0xffff, int16]
91	msize		int32
92	version_len	len[version, int16]
93	version		stringnoz[p9_versions]
94} [packed]
95
96p9_versions = "9P2000", "9P2000.u", "9P2000.L"
97
98p9_qid {
99	type	flags[p9_qid_types, int8]
100	version	int32[0:4]
101	path	int64[0:8]
102} [packed]
103
104p9_qid_types = P9_QTDIR, P9_QTAPPEND, P9_QTEXCL, P9_QTMOUNT, P9_QTAUTH, P9_QTTMP, P9_QTSYMLINK, P9_QTLINK, P9_QTFILE
105
106p9_rwalk {
107	nwqid	len[wqid, int16]
108	wqid	array[p9_qid]
109} [packed]
110
111p9_ropen {
112	qid	p9_qid
113	iounit	int32
114} [packed]
115
116p9_rread {
117	count	bytesize[data, int32]
118	data	array[int8]
119} [packed]
120
121p9_rstat {
122# I can't find this in any protocol descriptions, but linux seems to expect another int16 field here.
123	ignored		const[0, int16]
124	size		bytesize[parent, int16]
125	type		int16
126	dev		int32
127	qid		p9_qid
128	mode		flags[p9_perm_t, int32]
129	atime		int32
130	mtime		int32
131	length		int64
132	name_len	len[name, int16]
133	name		stringnoz
134	uid_len		len[uid, int16]
135	uid		stringnoz
136	gid_len		len[gid, int16]
137	gid		stringnoz
138	muid_len	len[muid, int16]
139	muid		stringnoz
140} [packed]
141
142p9_rstatu {
143	rstat		p9_rstat
144	extension_len	len[extension, int16]
145	extension	stringnoz
146	n_uid		uid
147	n_gid		gid
148	n_muid		uid
149} [packed]
150
151p9_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
152
153p9_rreadlink {
154	target_len	len[target, int16]
155	target		stringnoz[filename]
156} [packed]
157
158p9_rstatfs {
159	type	int32
160	bsize	int32
161	blocks	int64
162	bfree	int64
163	bavail	int64
164	files	int64
165	ffree	int64
166	fsid	int64
167	namelen	int32
168} [packed]
169
170p9_rgetattr {
171	valid		flags[p8_stats_valid, int64]
172	qid		p9_qid
173	mode		flags[open_mode, int32]
174	uid		uid
175	gid		gid
176	nlink		int64
177	rdev		int64
178	size		int64
179	blksize		int64
180	blocks		int64
181	atime_sec	int64
182	atime_nsec	int64
183	mtime_sec	int64
184	mtime_nsec	int64
185	ctime_sec	int64
186	ctime_nsec	int64
187	btime_sec	int64
188	btime_nsec	int64
189	gen		int64
190	data_version	int64
191} [packed]
192
193p8_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
194
195p9_lock_status = P9_LOCK_SUCCESS, P9_LOCK_BLOCKED, P9_LOCK_ERROR, P9_LOCK_GRACE
196p9_lock_type = P9_LOCK_TYPE_RDLCK, P9_LOCK_TYPE_WRLCK, P9_LOCK_TYPE_UNLCK
197
198p9_rreaddir {
199	count	int32
200	entries	array[p9_dir]
201} [packed]
202
203p9_dir {
204	qid		p9_qid
205	offset		int64
206	type		int8
207	name_len	len[name, int16]
208	name		stringnoz[filename]
209} [packed]
210
211p9_rgetlock {
212	type		flags[p9_lock_type, int8]
213	start		int64
214	length		int64
215	proc_id		pid
216	client_id_len	len[client_id, int16]
217	client_id	stringnoz
218} [packed]
219
220# Mount options.
221
222p9_options_fd {
223	trans	stringnoz["trans=fd,"]
224	rfdno	fs_opt_hex["rfdno", rfd9p]
225	comma0	const[',', int8]
226	wfdno	fs_opt_hex["wfdno", fd]
227	comma1	const[',', int8]
228	opts	fs_options[p9_options]
229} [packed]
230
231p9_options_tcp {
232	trans	stringnoz["trans=tcp,"]
233	port	fs_opt_hex["port", sock_port]
234	comma0	const[',', int8]
235	opts	fs_options[p9_options]
236} [packed]
237
238p9_options_unix {
239	name	stringnoz["trans=unix,"]
240	opts	fs_options[p9_options]
241} [packed]
242
243p9_options_rdma {
244	trans	stringnoz["trans=rdma,"]
245	port	fs_opt_hex["port", sock_port]
246	comma0	const[',', int8]
247	opts	fs_options[p9_options_rdma_opt]
248} [packed]
249
250p9_options_rdma_opt [
251	common	p9_options
252	timeout	fs_opt_hex["timeout", intptr]
253	sq	fs_opt_hex["sq", intptr]
254	rq	fs_opt_hex["rq", intptr]
255] [varlen]
256
257p9_options_virtio {
258	trans	stringnoz["trans=virtio,"]
259	opts	fs_options[p9_options]
260} [packed]
261
262p9_options_xen {
263	trans	stringnoz["trans=xen,"]
264	opts	fs_options[p9_options]
265} [packed]
266
267p9_options [
268	uname		fs_opt_str["uname"]
269	aname		fs_opt_str["aname"]
270	cache_none	stringnoz["cache=none"]
271	cache_loose	stringnoz["cache=loose"]
272	cache_fscache	stringnoz["cache=fscache"]
273	cache_mmap	stringnoz["cache=mmap"]
274	debug		fs_opt_hex["debug", int64]
275	noextend	stringnoz["noextend"]
276	nodevmap	stringnoz["nodevmap"]
277	version_9p2000	stringnoz["version=9p2000"]
278	version_u	stringnoz["version=9p2000.u"]
279	version_L	stringnoz["version=9p2000.L"]
280	cachetag	fs_opt_str["cachetag"]
281	loose		stringnoz["loose"]
282	fscache		stringnoz["fscache"]
283	mmap		stringnoz["mmap"]
284	posixacl	stringnoz["posixacl"]
285	privport	stringnoz["privport"]
286	msize		fs_opt_hex["msize", int32]
287	dfltuid		fs_opt_hex["dfltuid", uid]
288	dfltgid		fs_opt_hex["dfltgid", gid]
289	afid		fs_opt_hex["afid", int32]
290	access_user	stringnoz["access=user"]
291	access_any	stringnoz["access=any"]
292	access_client	stringnoz["access=client"]
293	access_uid	fs_opt_dec["access", uid]
294] [varlen]
295