1.1 --- a/docs/wiki/ServerLibrary Wed Aug 10 23:58:38 2022 +0200
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,245 +0,0 @@
1.4 -= Server Library =
1.5 -
1.6 -Within the filesystem server library, a number of different abstractions and
1.7 -mechanisms are employed to provide access to filesystem objects.
1.8 -
1.9 -<<TableOfContents(2,3)>>
1.10 -
1.11 -This document uses C-style interface syntax since the components operating
1.12 -within the described mechanisms will themselves be described using such
1.13 -syntax.
1.14 -
1.15 -== Accountable ==
1.16 -
1.17 -This interface provides the following operations:
1.18 -
1.19 -{{{
1.20 -void attach();
1.21 -unsigned int detach();
1.22 -}}}
1.23 -
1.24 -Its purpose is to provide reference counting for components, with the `attach`
1.25 -operation incrementing the number of users of a component, and with the
1.26 -`detach` operation decrementing the number of users and returning the
1.27 -resulting number of users. When components no longer have any attached users,
1.28 -they may perform operations to tidy up after themselves and permit their
1.29 -deallocation.
1.30 -
1.31 -== Accessors ==
1.32 -
1.33 -Accessors provide the means of accessing filesystem object data and metadata.
1.34 -Conceptually, files and directories are both exposed by accessors, although
1.35 -the interfaces and mechanisms may differ between these types of objects.
1.36 -
1.37 -=== Directory Accessors ===
1.38 -
1.39 -Currently, directory accessors provide support for traversing directory
1.40 -listings, obtaining the relevant filesystem metadata using the underlying
1.41 -filesystem access library.
1.42 -
1.43 -=== File Accessors ===
1.44 -
1.45 -File content is accessed through an interface with the following operations:
1.46 -
1.47 -{{{
1.48 -void close();
1.49 -void fill(Flexpage *flexpage);
1.50 -void flush(Flexpage *flexpage);
1.51 -offset_t get_size();
1.52 -void set_size(offset_t size);
1.53 -}}}
1.54 -
1.55 -The operations need to be supported with actual filesystem operations. For
1.56 -example, ext2-based filesystems employ a specific abstraction which invokes
1.57 -library functions provided by the `libext2fs` package.
1.58 -
1.59 -== Providers ==
1.60 -
1.61 -Providers encapsulate the essential functionality for accessing filesystem
1.62 -objects. Implementing the `Accountable` interface, they are shared by
1.63 -resources and discarded when no resources are using them.
1.64 -
1.65 -The following operations are supported by providers:
1.66 -
1.67 -{{{
1.68 -ProviderRegistry *registry();
1.69 -long make_resource(offset_t *size, object_flags_t *object_flags, Resource **resource);
1.70 -bool removal_pending();
1.71 -void remove();
1.72 -void remove_pending(bool remove);
1.73 -}}}
1.74 -
1.75 -Providers are associated with filesystem objects in a registry which can be
1.76 -obtained from each provider using the `registry` operation.
1.77 -
1.78 -Providers also support the creation of resources through which each user of a
1.79 -provider exercises its use of that provider. The `make_resource` operation
1.80 -performs the creation and returns size, flags and resource instance details.
1.81 -
1.82 -The removal of providers can be directed using the `remove_pending` and
1.83 -`remove` operations. Where `remove_pending` has been called with a true value
1.84 -as its parameter, the `removal_pending` operation will also return a true
1.85 -value, and upon the provider being discarded, the `remove` operation will be
1.86 -invoked. The `remove` operation performs the appropriate underlying operation
1.87 -to remove the object being provided.
1.88 -
1.89 -Typically, removal of providers is managed by the provider registry when
1.90 -resources are closed and detached from providers.
1.91 -
1.92 -######## A graph showing the removal mechanism
1.93 -
1.94 -{{{#!graphviz
1.95 -#format svg
1.96 -#transform notugly
1.97 -digraph provider_removal {
1.98 - node [fontsize="12.0",fontname="sans-serif",shape=box];
1.99 - edge [fontsize="12.0",fontname="sans-serif"];
1.100 - rankdir=LR;
1.101 -
1.102 - ResourceServer -> Resource [label="close"];
1.103 - Resource -> ProviderRegistry [label="detach"];
1.104 - ProviderRegistry -> Provider [label="remove"];
1.105 -}
1.106 -}}}
1.107 -
1.108 -########
1.109 -
1.110 -== Resources ==
1.111 -
1.112 -Resources are objects accessed by clients that support a basic level of
1.113 -accounting and management.
1.114 -
1.115 -The base interface of a resource is as follows:
1.116 -
1.117 -{{{
1.118 -void activate();
1.119 -void close();
1.120 -}}}
1.121 -
1.122 -Activation of a resource is an optional operation that performs any
1.123 -initialisation before a resource is made available to its user.
1.124 -
1.125 -In practice, other operations are required to make resources useful.
1.126 -
1.127 -In some cases, resources provide the mechanism by which each user of a
1.128 -filesystem object may access that object independently. They would then
1.129 -effectively provide a session in which accesses can occur.
1.130 -
1.131 -=== Directory Resources ===
1.132 -
1.133 -Directory resources primarily expose the contents of directories in the
1.134 -filesystem to a user. They employ directory accessors which concern themselves
1.135 -with the actual filesystem content.
1.136 -
1.137 -[[Components#Directories|Directory components]] are provided using directory
1.138 -resources.
1.139 -
1.140 -<<Anchor(Pager)>>
1.141 -=== Pagers or File Resources ===
1.142 -
1.143 -Pagers are resources that support dataspace access operations, thus allowing
1.144 -the resources to expose filesystem content in mapped memory regions to a
1.145 -particular user of the object providing the content.
1.146 -
1.147 -[[Components#Files|File components]] and [[Components#Pipes|pipe components]]
1.148 -are provided using pagers.
1.149 -
1.150 -=== Filesystem Resources ===
1.151 -
1.152 -Filesystem resources provide the entry point for access to a filesystem by
1.153 -other components or programs. Since filesystems often enforce identity-based
1.154 -access controls, a filesystem resource will typically support the
1.155 -`open_for_user` operation in various forms, with the result of this operation
1.156 -being the instantiation of an `OpenerResource` configured for the indicated
1.157 -user identity.
1.158 -
1.159 -== Registries ==
1.160 -
1.161 -The basic mechanism for obtaining a resource involves a registry, as
1.162 -illustrated by the following diagram.
1.163 -
1.164 -######## A graph showing the use of a registry in obtaining resources
1.165 -
1.166 -{{{#!graphviz
1.167 -#format svg
1.168 -#transform notugly
1.169 -digraph registry {
1.170 - node [fontsize="12.0",fontname="sans-serif",shape=box];
1.171 - edge [fontsize="12.0",fontname="sans-serif"];
1.172 - rankdir=LR;
1.173 -
1.174 - subgraph {
1.175 - node [label="OpenerContextResource"];
1.176 - rank=same;
1.177 -
1.178 - OpenerContextResource1 -> OpenerContextResource2 [dir=none,style=dotted];
1.179 - }
1.180 -
1.181 - subgraph {
1.182 - node [label="OpenerResource"];
1.183 - rank=same;
1.184 -
1.185 - OpenerResource1 -> OpenerResource2 [dir=none,style=dotted];
1.186 - }
1.187 -
1.188 - subgraph {
1.189 - rank=same;
1.190 -
1.191 - ResourceRegistry -> Resource;
1.192 - }
1.193 -
1.194 - subgraph {
1.195 - rank=same;
1.196 -
1.197 - ProviderRegistry -> Provider;
1.198 - }
1.199 -
1.200 - OpenerContextResource1 -> OpenerResource1 [label="open"];
1.201 - OpenerResource1 -> ResourceRegistry [label="get_resource"];
1.202 - ResourceRegistry -> ProviderRegistry [label="get/set"];
1.203 -
1.204 - Provider -> Resource -> OpenerResource2 -> OpenerContextResource2;
1.205 -}
1.206 -}}}
1.207 -
1.208 -########
1.209 -
1.210 -The `ResourceRegistry` coordinates access to filesystem resources and, through
1.211 -synchronisation, prevents conflicting operations from occurring concurrently.
1.212 -For example, a removal operation on a file may not be allowed to occur while
1.213 -an opening operation is in progress.
1.214 -
1.215 -To achieve this, a common lock is employed to serialise access, with any
1.216 -underlying filesystem operations being initiated from the registry while the
1.217 -lock is held. An object providing the `FileOpening` interface for a filesystem
1.218 -provides such operations, and the following interaction pattern is thereby
1.219 -employed:
1.220 -
1.221 -######## A graph showing the registry coordinating filesystem operations
1.222 -
1.223 -{{{#!graphviz
1.224 -#format svg
1.225 -#transform notugly
1.226 -digraph registry_operations {
1.227 - node [fontsize="12.0",fontname="sans-serif",shape=box];
1.228 - edge [fontsize="12.0",fontname="sans-serif"];
1.229 - rankdir=LR;
1.230 -
1.231 - OpenerContextResource -> OpenerResource -> ResourceRegistry -> FileOpening;
1.232 -}
1.233 -}}}
1.234 -
1.235 -########
1.236 -
1.237 -Since the `ResourceRegistry` functionality is generic, it could be specialised
1.238 -for each filesystem or be configured with an appropriate reference to a
1.239 -`FileOpening` object. The `OpenerResource` would then be generic, invoking the
1.240 -registry which would, in turn, invoke the opening object.
1.241 -
1.242 -However, the chosen approach is to permit `OpenerResource` objects to
1.243 -implement the `FileOpening` interface for each filesystem, meaning that the
1.244 -`ResourceRegistry` will end up being called by the opener and then invoking
1.245 -the opener in return. This is slightly more convenient than the alternative
1.246 -since the opener can be configured with a given user identity, and such
1.247 -identity details will ultimately be employed when accessing the underlying
1.248 -filesystem itself.