1.1 --- a/docs/wiki/Components Mon Nov 21 01:19:48 2022 +0100
1.2 +++ b/docs/wiki/Components Thu Dec 01 17:55:12 2022 +0100
1.3 @@ -6,8 +6,9 @@
1.4 mechanisms for opening, reading, writing, and closing files, together with
1.5 various other operations.
1.6
1.7 -Components are provided by functionality in `libfsserver` used by programs
1.8 -found in the `servers` directory within the `departure` package.
1.9 +Components are provided by functionality in [[Libraries#libfsserver|
1.10 +`libfsserver`]] used by programs found in the `servers` directory within the
1.11 +`departure` package.
1.12
1.13 <<TableOfContents(2,3)>>
1.14
1.15 @@ -16,145 +17,6 @@
1.16 document are described using excerpts from the appropriate interface
1.17 descriptions.
1.18
1.19 -== Overview ==
1.20 -
1.21 -An overview of the component interactions involved in opening a file or
1.22 -directory is provided by the diagram below.
1.23 -
1.24 -######## A graph showing the interactions between components
1.25 -
1.26 -{{{#!graphviz
1.27 -#format svg
1.28 -#transform notugly
1.29 -digraph components {
1.30 - node [fontsize="12.0",fontname="sans-serif",shape=box];
1.31 - edge [fontsize="12.0",fontname="sans-serif"];
1.32 - rankdir=LR;
1.33 -
1.34 - subgraph {
1.35 - node [label="Client"];
1.36 - rank=min;
1.37 -
1.38 - Client1; Client2; Client3; Client4; Client5; Client6; Client7;
1.39 - }
1.40 -
1.41 - subgraph {
1.42 - rank=same;
1.43 -
1.44 - Memory [label="filename",shape=note];
1.45 - }
1.46 -
1.47 - subgraph {
1.48 - rank=max;
1.49 -
1.50 - Filesystem;
1.51 -
1.52 - subgraph {
1.53 - node [label="Opener\n(user)"];
1.54 - Opener1; Opener2;
1.55 - }
1.56 -
1.57 - subgraph {
1.58 - node [label="OpenerContext"];
1.59 - OpenerContext1; OpenerContext2; OpenerContext3;
1.60 - }
1.61 -
1.62 - Object [label="MappedFile\nor\nDirectory"];
1.63 - }
1.64 -
1.65 - Client1 -> Client2 -> Client3 -> Client4 -> Client5 -> Client6 -> Client7 [dir=none,style=dotted];
1.66 - Opener1 -> Opener2 [dir=none,style=dotted];
1.67 - OpenerContext1 -> OpenerContext2 -> OpenerContext3 [dir=none,style=dotted];
1.68 -
1.69 - Client1 -> Filesystem [label="open_for_user(user)"];
1.70 - Filesystem -> Opener1;
1.71 - Opener1 -> Client2;
1.72 -
1.73 - Client3 -> Opener2 [label="context()"];
1.74 - Opener2 -> OpenerContext1;
1.75 - OpenerContext1 -> Client4;
1.76 -
1.77 - Client5 -> Memory -> OpenerContext2;
1.78 -
1.79 - Client6 -> OpenerContext3 [label="open(flags, ...)"];
1.80 - OpenerContext3 -> Object;
1.81 - Object -> Client7;
1.82 -}
1.83 -}}}
1.84 -
1.85 -########
1.86 -
1.87 -In pseudocode, the operations as conducted by the client program are as
1.88 -follows:
1.89 -
1.90 -{{{
1.91 -opener = filesystem.open_for_user(user)
1.92 -context = opener.context()
1.93 -context.write("filename") # this being a memory access operation
1.94 -file = context.open(flags, ...)
1.95 -}}}
1.96 -
1.97 -Reading from an opened directory is achieved as shown in the following
1.98 -diagram.
1.99 -
1.100 -######## A graph showing the interactions between components
1.101 -
1.102 -{{{#!graphviz
1.103 -#format svg
1.104 -#transform notugly
1.105 -digraph components {
1.106 - node [fontsize="12.0",fontname="sans-serif",shape=box];
1.107 - edge [fontsize="12.0",fontname="sans-serif"];
1.108 - rankdir=LR;
1.109 -
1.110 - subgraph {
1.111 - node [label="Client"];
1.112 - rank=min;
1.113 -
1.114 - Client1; Client2; Client3; Client4;
1.115 - }
1.116 -
1.117 - subgraph {
1.118 - rank=same;
1.119 -
1.120 - Memory [label="entries",shape=note];
1.121 - }
1.122 -
1.123 - subgraph {
1.124 - rank=max;
1.125 -
1.126 - Directory;
1.127 -
1.128 - subgraph {
1.129 - node [label="Reader"];
1.130 -
1.131 - Reader1; Reader2; Reader3;
1.132 - }
1.133 - }
1.134 -
1.135 - Client1 -> Client2 -> Client3 -> Client4 [dir=none,style=dotted];
1.136 - Reader1 -> Reader2 -> Reader3 [dir=none,style=dotted];
1.137 -
1.138 - Client1 -> Directory [label="opendir()"];
1.139 - Directory -> Reader1;
1.140 - Reader1 -> Client2;
1.141 -
1.142 - Client3 -> Reader2 [label="current_region()"];
1.143 - Reader3 -> Memory -> Client4;
1.144 -}
1.145 -}}}
1.146 -
1.147 -########
1.148 -
1.149 -In pseudocode, the operations as conducted by the client program are as
1.150 -follows:
1.151 -
1.152 -{{{
1.153 -reader = directory.opendir()
1.154 -reader.current_region()
1.155 -entries = reader.read() # this being a memory access operation
1.156 -}}}
1.157 -
1.158 == Filesystems ==
1.159
1.160 Filesystems implement the `Filesystem` interface which provides the
1.161 @@ -167,6 +29,52 @@
1.162 The operation yields a file opener appropriate for the given [[Users|user]]
1.163 credentials.
1.164
1.165 +######## A graph showing the interactions between components
1.166 +
1.167 +{{{#!graphviz
1.168 +#format svg
1.169 +#transform notugly
1.170 +digraph open_for_user {
1.171 + node [fontsize="12.0",fontname="sans-serif",shape=box];
1.172 + edge [fontsize="12.0",fontname="sans-serif"];
1.173 + rankdir=LR;
1.174 +
1.175 + subgraph {
1.176 + node [label="Client"];
1.177 + rank=min;
1.178 +
1.179 + Client1; Client2;
1.180 + }
1.181 +
1.182 + subgraph {
1.183 + rank=max;
1.184 +
1.185 + Filesystem;
1.186 +
1.187 + subgraph {
1.188 + node [label="Opener\n(user)"];
1.189 + Opener;
1.190 + }
1.191 + }
1.192 +
1.193 + Client1 -> Client2 [dir=none,style=dotted];
1.194 +
1.195 + Client1 -> Filesystem [label="open_for_user(user)"];
1.196 + Filesystem -> Opener;
1.197 + Opener -> Client2;
1.198 +
1.199 +}
1.200 +}}}
1.201 +
1.202 +########
1.203 +
1.204 +In pseudocode, the operations as conducted by the client program are as
1.205 +follows:
1.206 +
1.207 +{{{
1.208 +opener = filesystem.open_for_user(user)
1.209 +}}}
1.210 +
1.211 ((Openers))
1.212 == File and Directory Openers ==
1.213
1.214 @@ -180,6 +88,54 @@
1.215 Each client program, task or thread obtains its own context because it will
1.216 need its own dedicated channel for communication with the filesystem.
1.217
1.218 +######## A graph showing the interactions between components
1.219 +
1.220 +{{{#!graphviz
1.221 +#format svg
1.222 +#transform notugly
1.223 +digraph context {
1.224 + node [fontsize="12.0",fontname="sans-serif",shape=box];
1.225 + edge [fontsize="12.0",fontname="sans-serif"];
1.226 + rankdir=LR;
1.227 +
1.228 + subgraph {
1.229 + node [label="Client"];
1.230 + rank=min;
1.231 +
1.232 + Client1; Client2;
1.233 + }
1.234 +
1.235 + subgraph {
1.236 + rank=max;
1.237 +
1.238 + subgraph {
1.239 + node [label="Opener\n(user)"];
1.240 + Opener;
1.241 + }
1.242 +
1.243 + subgraph {
1.244 + node [label="OpenerContext"];
1.245 + OpenerContext;
1.246 + }
1.247 + }
1.248 +
1.249 + Client1 -> Client2 [dir=none,style=dotted];
1.250 +
1.251 + Client1 -> Opener [label="context()"];
1.252 + Opener -> OpenerContext;
1.253 + OpenerContext -> Client2;
1.254 +}
1.255 +}}}
1.256 +
1.257 +########
1.258 +
1.259 +In pseudocode, the operations as conducted by the client program are as
1.260 +follows:
1.261 +
1.262 +{{{
1.263 +context = opener.context()
1.264 +}}}
1.265 +
1.266 == Opener Contexts ==
1.267
1.268 An opener context acts as a dataspace, meaning that it can be attached to a
1.269 @@ -205,6 +161,61 @@
1.270 Alongside regular files, directories may also be opened. Reading from them
1.271 yields a listing of directory entries.
1.272
1.273 +######## A graph showing the interactions between components
1.274 +
1.275 +{{{#!graphviz
1.276 +#format svg
1.277 +#transform notugly
1.278 +digraph open {
1.279 + node [fontsize="12.0",fontname="sans-serif",shape=box];
1.280 + edge [fontsize="12.0",fontname="sans-serif"];
1.281 + rankdir=LR;
1.282 +
1.283 + subgraph {
1.284 + node [label="Client"];
1.285 + rank=min;
1.286 +
1.287 + Client1; Client2; Client3;
1.288 + }
1.289 +
1.290 + subgraph {
1.291 + rank=same;
1.292 +
1.293 + Memory [label="filename",shape=note];
1.294 + }
1.295 +
1.296 + subgraph {
1.297 + rank=max;
1.298 +
1.299 + subgraph {
1.300 + node [label="OpenerContext"];
1.301 + OpenerContext1; OpenerContext2;
1.302 + }
1.303 +
1.304 + Object [label="MappedFile\nor\nDirectory"];
1.305 + }
1.306 +
1.307 + Client1 -> Client2 -> Client3 [dir=none,style=dotted];
1.308 + OpenerContext1 -> OpenerContext2 [dir=none,style=dotted];
1.309 +
1.310 + Client1 -> Memory -> OpenerContext1;
1.311 +
1.312 + Client2 -> OpenerContext2 [label="open(flags, ...)"];
1.313 + OpenerContext2 -> Object;
1.314 + Object -> Client3;
1.315 +}
1.316 +}}}
1.317 +
1.318 +########
1.319 +
1.320 +In pseudocode, the operations as conducted by the client program are as
1.321 +follows:
1.322 +
1.323 +{{{
1.324 +context.write("filename") # this being a memory access operation
1.325 +file = context.open(flags, ...)
1.326 +}}}
1.327 +
1.328 === Removing ===
1.329
1.330 Filesystem objects are removed by invoking the `remove` operation on an opener
1.331 @@ -292,6 +303,67 @@
1.332 supporting precisely the same navigation mechanisms as those supported by
1.333 files.
1.334
1.335 +Reading from an opened directory is achieved as shown in the following
1.336 +diagram.
1.337 +
1.338 +######## A graph showing the interactions between components
1.339 +
1.340 +{{{#!graphviz
1.341 +#format svg
1.342 +#transform notugly
1.343 +digraph components {
1.344 + node [fontsize="12.0",fontname="sans-serif",shape=box];
1.345 + edge [fontsize="12.0",fontname="sans-serif"];
1.346 + rankdir=LR;
1.347 +
1.348 + subgraph {
1.349 + node [label="Client"];
1.350 + rank=min;
1.351 +
1.352 + Client1; Client2; Client3; Client4;
1.353 + }
1.354 +
1.355 + subgraph {
1.356 + rank=same;
1.357 +
1.358 + Memory [label="entries",shape=note];
1.359 + }
1.360 +
1.361 + subgraph {
1.362 + rank=max;
1.363 +
1.364 + Directory;
1.365 +
1.366 + subgraph {
1.367 + node [label="Reader"];
1.368 +
1.369 + Reader1; Reader2; Reader3;
1.370 + }
1.371 + }
1.372 +
1.373 + Client1 -> Client2 -> Client3 -> Client4 [dir=none,style=dotted];
1.374 + Reader1 -> Reader2 -> Reader3 [dir=none,style=dotted];
1.375 +
1.376 + Client1 -> Directory [label="opendir()"];
1.377 + Directory -> Reader1;
1.378 + Reader1 -> Client2;
1.379 +
1.380 + Client3 -> Reader2 [label="current_region()"];
1.381 + Reader3 -> Memory -> Client4;
1.382 +}
1.383 +}}}
1.384 +
1.385 +########
1.386 +
1.387 +In pseudocode, the operations as conducted by the client program are as
1.388 +follows:
1.389 +
1.390 +{{{
1.391 +reader = directory.opendir()
1.392 +reader.current_region()
1.393 +entries = reader.read() # this being a memory access operation
1.394 +}}}
1.395 +
1.396 == Pipe Openers ==
1.397
1.398 Distinct from filesystems but potentially used by them, pipe openers provide a