Blob


1 .\" Copyright (c) 2021 Omar Polo <op@omarpolo.com>
2 .\"
3 .\" Permission to use, copy, modify, and distribute this software for any
4 .\" purpose with or without fee is hereby granted, provided that the above
5 .\" copyright notice and this permission notice appear in all copies.
6 .\"
7 .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 .\"
15 .Dd $Mdocdate: July 30 2021 $
16 .Dt 9P 7
17 .Os
18 .Sh NAME
19 .Nm 9P
20 .Nd Simple Distributed File System
21 .Sh DESCRIPTION
22 .Nm
23 is a protocol that implements a distributed file systems.
24 It provides primitives to manage
25 .Pq create, read, write and delete
26 sets of files remotely.
27 These files don't necessarily need to be actually stored on a disk,
28 they may be, for example, synthesise on demand from external sources.
29 .Pp
30 A client transmits requests
31 .Pq T-messages
32 to a server, which returns replies
33 .Pq R-messages
34 to the client.
35 The combined acts of transmitting a request of a particular type and
36 receiving a reply is called a transaction of that type.
37 .Pp
38 Each message consists of a sequence of bytes mostly grouped in one,
39 two or four integer fields transmitted in little-endian order
40 .Pq least significant byte first .
41 Data items of larger or variable lengths are represented by a two-byte
42 field specifying the length followed by the actual data.
43 The only exception to this rule are QIDs, thirteen byte long
44 objects, that are sent as-is.
45 .Pp
46 Text strings are represented with a two-byte count and the sequence of
47 UNICODE codepoints encoded in UTF-8.
48 Text strings in 9p are not NUL-terminated.
49 The NUL-terminator is illegal in all text strings and thus excluded
50 from paths, user names and so on.
51 .Pp
52 Fields are hereafter denoted as
53 .Bd -literal -offset indent
54 type[1] tag[2] fid[4]
55 .Ed
56 .Pp
57 to indicate that type is one byte long, tag two and fid four.
58 Strings are denoted as name[s] and are sent on the wire as
59 .Bd -literal -offset indent
60 length[2] string[length]
61 .Ed
62 .Pp
63 A qid, described later, is a 13-byte value that is sent on the wire as
64 .Bd -literal -offset indent
65 type[1] version[4] path[8]
66 .Ed
67 .Sh MESSAGE STRUCTURE
68 Every message has a header with the following fields:
69 .Bd -literal -offset indent
70 len[4] type[1] tag[2]
71 .Ed
72 .Pp
73 where len indicates the overall length of the message, including
74 itself; type is one byte indicating the type of the message and the
75 tag is a number choosen by the client that indicate uniquely the
76 request.
77 Then follows an optional body whose structure depends on the type of
78 the message.
79 .Pp
80 The message types are as follows:
81 .Pq the header is omitted for brevity
82 .Bl -tag -width versionxx
83 .It Ic version
84 Negotiate the version and maximum message size.
85 .Bd -literal
86 msize[4] version[s]
87 msize[4] version[s]
88 .Ed
89 .Pp
90 The
91 .Ic version
92 request must be the first message sent, and the client cannot issue
93 further requests until receiving the Rversion reply.
94 .Ar tag
95 should be
96 .Dv NOTAG
97 .Pq \-1 or 255 .
98 The client suggest a
99 .Ar msize
100 .Pq the maximum size for packets
101 and the protocol version used, the server replies with a
102 .Ar msize
103 smaller or equal to the one proposed by the client.
104 The version string must always begin with the two character
105 .Dq 9P .
106 If the server don't understand the client required version, should
107 reply with a Rversion using the version string
108 .Dq unknown
109 and not use a Rerror.
110 .It Ic attach
111 Populate the namespace
112 .Bd -literal
113 fid[4] afid[4] uname[s] aname[s]
114 qid[13]
115 .Ed
116 .Pp
117 The
118 .Ic attach
119 message binds the given
120 .Ar fid
121 to the root of the file tree identified by
122 .Ar aname .
123 .Ar uname
124 identifies the user and
125 .Ar afid
126 specifies a fid previously established by an auth message, or the
127 special
128 .Dv NOFID
129 value
130 .Pq defined as (u32int_t)~0
131 if the authentication is not required.
132 .It Ic clunk
133 Close fids.
134 .Bd -literal
135 fid[4]
136 .Aq empty response
137 .Ed
138 .Pp
139 Once a fid has been clunked
140 .Pq closed
141 it becomes
142 .Dq free
143 and the same value can be used for subsequential
144 .Ic walk
145 or
146 .Ic attach
147 requests.
148 .Pp
149 The actual file on the disk is not removed unless it was opened with the
150 .Dv ORCLOSE
151 flag.
152 .It Ic error
153 Return an error string.
154 .Bd -literal
155 .Aq no request
156 ename[s]
157 .Ed
158 .Pp
159 The Rerror message is used to return an error string describing the
160 failure of a request.
161 The
162 .Ar tag
163 indicates the failed request.
164 .Pp
165 Note that there isn't a
166 .Ic Terror
167 request for obvious reason and it's not possible for a server to reply to
169 .Ic Tversion
170 or
171 .Ic Tflush
172 using
173 .Ic Rerror .
174 .It Ic flush
175 Abort an ongoing operation.
176 .Bd -literal
177 oldtag[2]
178 .Aq empty response
179 .Ed
180 .Pp
181 Given the asynchronous nature of the protocol, the server may respond to
182 the pending request before responding to the
183 .Ic Tflush
184 and is possible for a client to send multiple
185 .Ic Tflush
186 for the same operation.
187 The client must wait to receive a corresponding
188 .Ic Rflush
189 before reusing
190 .Ar oldtag
191 for subsequent messages.
192 .Pp
193 If a response for
194 .Ar oldtag
195 is received before the
196 .Ic Rflush
197 reply, the client must assume that the operation was completed with success
198 .Pq fid allocated, files created, ...
199 If no response is received before the
200 .Ic Rflush
201 then the transaction is considered to have been successfully cancelled.
202 .Pp
203 Note that the tag of this request and the corresponding reply is NOT
204 .Ar oldtag
205 but a new tag value.
206 .It Ic walk
207 Traverse a file tree.
208 .Bd -literal
209 fid[4] newfid[4] nwname[2] nwname*(wname[s])
210 nwqid[2] nwqid*(qid[13])
211 .Ed
212 .Pp
213 The
214 .Ar nwname
215 components are walked in order starting from
216 .Ar fid
217 .Pq which must point to a directory
218 and, if successful,
219 .Ar newfid
220 is associated to the reached file.
221 .Pp
222 It is possible for
223 .Ar fid
224 and
225 .Ar newfid
226 to be equal, in this case the fid is
227 .Dq mutated ,
228 otherwise
229 .Ar newfid
230 must be unused.
231 As a special case, a walk of zero components duplicates the fid.
232 .Pp
233 If the first element cannot be walked for any reason an
234 .Ic Rerror
235 is returned.
236 Otherwise,
237 .Ic Rwalk
238 is returned with a number of qids equal to the file viside by the walk.
239 A client can thus detect a walk when that the replied
240 .Ar nwqid
241 number is not equal to the
242 .Ar nwname
243 field in the request.
244 Only when walk return successfully
245 .Ar newfid
246 will be affected.
247 .Pp
248 A maximum of 16 component can be used per walk request.
249 .It Ic open
250 Prepare a fid for I/O.
251 .Bd -literal
252 fid[4] mode[1]
253 qid[13] iounit[4]
254 .Ed
255 .Pp
256 .Ar mode
257 determines the type of I/O:
258 .Bl -tag -width Ds -offset indent -compact
259 .It 0x00 Pq Dv OREAD
260 Open the file for reading.
261 .It 0x01 Pq Dv OWRITE
262 Open the file for writing.
263 .It 0x02 Pq Dv ORDWD
264 Open the file for both reading and writing.
265 .It 0x03 Pq Dv OEXEC
266 Open for exec.
267 .El
268 .Pp
269 Additionally, the following flags can be or'ed to
270 .Ar mode :
271 .Bl -tag -width Ds -offset indent -compact
272 .It 0x10 Pq Dv OTRUNC
273 Truncate the file before opening
274 .It 0x40 Pq Dv ORCLOSE
275 Remove the file upon
276 .Ic clunk .
277 .El
278 .Pp
279 The returned
280 .Ar iounit
281 is the optimal blocksize for I/O.
282 .It Ic create
283 Create a file
284 .Bd -literal
285 fid[4] name[s] perm[4] mode[1]
286 qid[13] iounit[4]
287 .Ed
288 .Pp
289 The call attempts to create a file named
290 .Ar name
291 in the directory identified by
292 .Ar fid
293 according to
294 .Ar perm
295 and then to open it with
296 .Ar mode
297 into the given
298 .Ar fid .
299 .Pp
300 It is illegal to use an already opened
301 .Ar fid
302 or to attempt to create the
303 .Dq \&.
304 or
305 .Dq ..
306 entries.
307 .It Ic read
308 Read data at offset
309 .Bd -literal
310 fid[4] offset[8] count[4]
311 count[4] data[count]
312 .Ed
313 .Pp
314 .Ar fid
315 must have been prepared for I/O with a previous
316 .Ic open
317 call.
318 The returned
319 .Ar count
320 is zero when reaching end-of-file and may be lesser than what requested.
321 .Pp
322 Directories are a stream of stat structures, as described in
323 .Ic stat ,
324 and for them the read request message must have offset equal to zero or
325 the value of
326 .Ar offset
327 in the previous read on the directory plus the number of bytes returned
328 in the previous read.
329 Thus, is not possible to seek into directories except for rewinding.
330 .It Ic write
331 Write data at offset
332 .Bd -literal
333 fid[4] offset[8] count[4] data[count]
334 count[4]
335 .Ed
336 .Pp
337 .Ar fid
338 must have been prepared for I/O with a previous
339 .Ic open
340 or
341 .Ic create
342 call.
343 The returned
344 .Ar count
345 is the amount of data actually written and may differ from the one in
346 the request.
347 .It Ic stat
348 Get file status
349 .Bd -literal
350 fid[4]
351 stat[n]
352 .Ed
353 .Pp
354 The stat structure is made by the following fields:
355 .Bl -tag -width tenletters -compact
356 .It size[2]
357 total byte count of the following data
358 .It type[2]
359 for kernel use
360 .It dev[4]
361 for kernel use
362 .It qid[13]
363 server unique identifier of the file
364 .It mode[4]
365 permissions and flags
366 .It atime[4]
367 last access time
368 .It mtime[4]
369 last modification time
370 .It length[8]
371 length of file in bytes
372 .It name[s]
373 file name
374 (must be
375 .Dq /
376 if the file is the root directory of the server)
377 .It uid[s]
378 owner name
379 .It gid[s]
380 group name
381 .It muid[s]
382 name of the user who last modified the file.
383 .El
384 .Pp
385 Note that the
386 .Ar size
387 is always present, even in the
388 .Ic wstat
389 call.
390 While it may be considered redundant, it's kept to simplify the
391 parsing of the stat entries in a directory.
392 .It Ic wstat
393 Change file attributes
394 .Bd -literal
395 fid[4] stat[n]
396 .Aq empty response
397 .Ed
398 .Pp
399 .Ar fid
400 must have been prepared for writing with a previous
401 .Ic open
402 or
403 .Ic create
404 call.
405 .Pp
406 The
407 .Ar stat
408 structure is the same described in
409 .Ic stat .
410 .Pp
411 The
412 .Ar stat
413 structure sent reflect what changes the client wishes to make to the
414 given fid.
415 To leave some fields as unchanged, use empty string or the maximum
416 allowed value for integral fields.
417 For example, to avoid changing the permission of the fid use
418 0xFFFFFFFF, or (uint32_t)-1.
419 .It Ic remove
420 Remove and clunk fid
421 .Bd -literal
422 fid[4]
423 .Aq empty response
424 .Ed
425 .Pp
426 After a
427 .Ic remove
428 call, even if an error is returned, the
429 .Ar fid
430 is closed.
431 .El
432 .\" .Sh 9P2000.L EXTENSIONS
433 .\" .Xr kamid 8
434 .\" supports also a subset of the
435 .\" .Sq 9P2000.L
436 .\" dialect.
437 .\" The supported messages are
438 .\" .Bl -tag -width readdir
439 .\" .It Ic readdir
440 .\" Read directory entries
441 .\" .Bd -literal
442 .\" fid[4] offset[8] count[4]
443 .\" count[4] data[count]
444 .\" .Ed
445 .\" .Pp
446 .\" Each directory entry is described by a variable-length record:
447 .\" .Ql qid[13] offset[8] type[1] name[s] .
448 .\" Offset is zero upon the first call.
449 .\" If the
450 .\" .Ar count
451 .\" field in the
452 .\" .Ic Rreaddir
453 .\" response is not zero then more data is available.
454 .\" .Pp
455 .\" .Ar count
456 .\" is allowed to be zero in the request.
457 .\" .El
458 .Sh SEE ALSO
459 .Xr utf8 7 ,
460 .Xr kamid 8