Blame


1 f3a795ae 2021-08-03 op => taking-about-9p-intro.gmi Taking ’bout 9P: intro
2 f3a795ae 2021-08-03 op
3 f3a795ae 2021-08-03 op The Topen request at first looks weird. Here’s its signature
4 f3a795ae 2021-08-03 op
5 f3a795ae 2021-08-03 op ```bytewise description of a Topen request
6 f3a795ae 2021-08-03 op size[4] Topen tag[2] fid[4] mode[1]
7 f3a795ae 2021-08-03 op ```
8 f3a795ae 2021-08-03 op
9 f3a795ae 2021-08-03 op It’s strange, isn’t it? For comparison, here’s the C signature for the open(2) system call:
10 f3a795ae 2021-08-03 op
11 f3a795ae 2021-08-03 op ```C prototype of the open(2) system call
12 f3a795ae 2021-08-03 op int open(const char *path, int flags, ...);
13 f3a795ae 2021-08-03 op ```
14 f3a795ae 2021-08-03 op
15 f3a795ae 2021-08-03 op Where is the path in the Topen call?
16 f3a795ae 2021-08-03 op
17 f3a795ae 2021-08-03 op The description for the Topen request says:
18 f3a795ae 2021-08-03 op
19 f3a795ae 2021-08-03 op > The open request asks the file server to check permissions and prepare a fid for I/O with subsequent read and write messages.
20 f3a795ae 2021-08-03 op
21 f3a795ae 2021-08-03 op Which implies that to write or read a fid you must open… an existing fid?
22 f3a795ae 2021-08-03 op
23 f3a795ae 2021-08-03 op This morning (well, actually some days ago since this entry got published later) cage explained the mystery to me: Twalk.
24 f3a795ae 2021-08-03 op
25 f3a795ae 2021-08-03 op When I first skimmed through the 9P documentation I thought that the walk request was basically a chdir(2), which it is, but also is not!
26 f3a795ae 2021-08-03 op
27 f3a795ae 2021-08-03 op The Twalk requests allows one to navigate from a fid (usually representing the starting directory) through some path components and reach a destination file that will be associated with a new fid.
28 f3a795ae 2021-08-03 op
29 f3a795ae 2021-08-03 op So, if I connect to a 9P file server and write something to ~/notes.txt (supposing that my home is on that file server) the 9P session could look like this:
30 f3a795ae 2021-08-03 op
31 f3a795ae 2021-08-03 op ```
32 f3a795ae 2021-08-03 op # establish a connection and negotiate the version
33 f3a795ae 2021-08-03 op → Tversion <msize> 9P2000
34 f3a795ae 2021-08-03 op ← Rversion <msize> 9P2000
35 f3a795ae 2021-08-03 op
36 f3a795ae 2021-08-03 op # mount the home
37 f3a795ae 2021-08-03 op → Tattach 1 "op" "/home/op"
38 f3a795ae 2021-08-03 op ← Rattach <qid>
39 f3a795ae 2021-08-03 op
40 f3a795ae 2021-08-03 op # walk from fid #1 (/home/op) to “notes.txt” (a file!)
41 f3a795ae 2021-08-03 op # and associate to it fid #2
42 f3a795ae 2021-08-03 op → Twalk 1 2 "notes.txt"
43 f3a795ae 2021-08-03 op ← Rwalk <qid...>
44 f3a795ae 2021-08-03 op
45 f3a795ae 2021-08-03 op # prepare fid 2 (/home/op/notes.txt) for
46 f3a795ae 2021-08-03 op # reading and writing
47 f3a795ae 2021-08-03 op → Topen 2 OWRITE|OREAD
48 f3a795ae 2021-08-03 op ← Ropen <qid> <iounit>
49 f3a795ae 2021-08-03 op
50 f3a795ae 2021-08-03 op # read/write fid 2…
51 f3a795ae 2021-08-03 op
52 f3a795ae 2021-08-03 op # close the fid 2 since it’s no longer used
53 f3a795ae 2021-08-03 op → Tclunk 2
54 f3a795ae 2021-08-03 op ← Rclunk
55 f3a795ae 2021-08-03 op ```
56 f3a795ae 2021-08-03 op
57 f3a795ae 2021-08-03 op (note that as always this is entirely my speculation from reading the documentation. I never used — sigh! — plan9 nor 9p)
58 f3a795ae 2021-08-03 op
59 f3a795ae 2021-08-03 op So it actually makes sense for Topen to accept a fid and not a path, and Twalk is a general purpose request that can be used to implement various system calls (dup2, chdir, open…)
60 f3a795ae 2021-08-03 op
61 f3a795ae 2021-08-03 op Then I started to think why it was like this. I mean, everything is finally starting to make sense in my head, but why the 9P people decided to implement Topen and Twalk this way?
62 f3a795ae 2021-08-03 op
63 f3a795ae 2021-08-03 op Well, I can’t say for sure, but I’m starting to noticing that a fid is something more than a UNIX file descriptor: it’s both a file descriptor AND a path.
64 f3a795ae 2021-08-03 op
65 f3a795ae 2021-08-03 op *my mind blows*
66 f3a795ae 2021-08-03 op
67 f3a795ae 2021-08-03 op Which is actually a pretty clever solution. The client can get new fids by mean of Twalk, which then can be passed to Tremove (for removal), or Tstat/Twstat, or being opened and then written/closed. It’s also probably more efficient than passing string around on every request.
68 f3a795ae 2021-08-03 op
69 f3a795ae 2021-08-03 op This has also some drawbacks probably. For one, it’s not clear at glance if a fid was prepared for I/O or not. On UNIX there is a clear distinction between a file descriptor (a number that references an object in the kernel) and a path (a mere sequence of bytes NUL-terminated.) But since this is an underlying mechanism, it seems pretty clever. It shouldn’t be too much difficult to map the usual UNIX syscalls on top of 9p.