L4Re/departure

docs/wiki/Directories

360:92c5f6aa8c36
2022-06-12 Paul Boddie Reintroduced PagerObject code generation required to initiate servers. mmap-region-flags
     1 = Directories =     2      3 Filesystem directories contain collections of files, other directories, along     4 with other filesystem objects. Directories can be listed, permitting     5 filesystem clients to peruse the contents of each directory. However, the act     6 of listing a directory may impose certain constraints on the operations being     7 conducted on the directory during the listing process.     8      9 Operations that affect directory contents include the following:    10     11  * Creating a new object    12  * Removing an object    13  * Moving an object out of the directory    14  * Moving an object into the directory    15     16 It is conceivable that for some filesystems, these operations will not be able    17 to rely on directly modifying the directory since a listing operation may be    18 in progress. Consequently, a number of rules would be imposed for such    19 filesystems. It appears that Ext2-based filesystems accessed via libext2fs do    20 not require such rules to be applied outside the library due to the design of    21 the filesystem structures and the behaviour of the library itself.    22     23 == Providers ==    24     25 Providers of filesystem objects are created when at least one filesystem    26 client is accessing such an object, with the object regarded as being    27 '''open'''. By definition, a provider will exist until all clients have closed    28 or discarded their means of accessing the object.    29     30 An object is regarded as '''accessible''' if it can still be opened by    31 filesystem clients. Where an object has been removed, it will no longer be    32 accessible since clients should not be able to see the object in the    33 filesystem any more. (The actual filesystem residing in storage may not have    34 been updated for such a removal, this being the eventual outcome of a removal    35 operation.)    36     37 Providers can be regarded as '''accessible''' if they maintain access to    38 objects that are open and accessible. Clients opening objects will only gain    39 access to accessible providers. Providers can become inaccessible if an object    40 is removed even if the object (and its provider) is still open.    41     42 Initially, providers will correspond to objects resident in the stored    43 filesystem. Thus, looking up an object using its path will involve the    44 filesystem, yielding a file identifier that can be used to map to a provider.    45     46 {{{    47 def get_provider_from_filesystem(path):    48     fileid = opening.get_fileid(path)    49     50     if not fileid:    51         return error    52     53     return find_provider(fileid)    54 }}}    55     56 However, providers may not always immediately correspond to objects resident    57 in the stored filesystem. Where an object is created but cannot be immediately    58 registered in the contents of a directory, it must be registered separately    59 and attempts to open this object must consult this separate mapping of    60 filenames to providers.    61     62 {{{    63 def get_provider(path):    64     provider = find_created_provider(path)    65     66     if provider:    67         return provider    68     69     return get_provider_from_filesystem(path)    70 }}}    71     72 Providers that are inaccessible need to be retained until they are closed.    73 However, since they are no longer accessible, they should not be available to    74 the provider lookup operations.    75     76 When providers are closed, they are removed from any mapping in which they    77 could be found. Inaccessible providers that have been retained outside the    78 identifier or filename mappings will represent objects that should be removed    79 from their parent directory. Accessible providers retained by the mappings    80 will represent objects that should be created in their parent directory.    81     82 Whether object removal or creation will occur depends on whether the parent    83 directory is able to safely perform these operations concurrently with other    84 operations (such as servicing a listing operation) or whether such operations    85 will need to be deferred until they can be safely performed.    86     87 == Object Removal ==    88     89 Filesystem object removal involves obtaining any provider of the object. Where    90 a provider can be obtained, it will be made inaccessible and removal will be    91 requested. The actual object will not be removed at least until it is closed    92 because it may still receive and provide data. (Unlinking open files is a    93 feature of Unix systems.)    94     95 Where a provider cannot be obtained, an attempt will be made to obtain the    96 parent directory provider, and if this succeeds, it indicates that the    97 directory is being accessed and must therefore be notified of the intention to    98 eventually remove the object concerned.    99    100 Without any provider of the object, and where no directory provider can be   101 obtained, the object can be immediately removed from the filesystem.   102    103 {{{   104 def remove_object(path):   105     provider = get_provider(path)   106    107     if provider:   108         return make_provider_inaccessible(provider)   109    110     dirname, basename = split(path)   111     directory_provider = get_provider(dirname)   112    113     if directory_provider:   114         return directory_provider.remove_pending(basename)   115    116     return filesystem.remove_object(path)   117 }}}   118    119 It should be noted that with no accessible provider, any attempt to create a   120 file with the same name as a removed file should cause a new "version" of the   121 file to be created.   122    123 == Object Creation ==   124    125 Filesystem object creation occurs when no existing provider can be found for a   126 named object and where creation is requested. Any new object will be   127 accessible and remain so until or unless it is removed.   128    129 Whether an object is created in the filesystem storage depends on whether the   130 parent directory is being used.   131    132 If a parent directory is not being used, the object can be registered in its   133 proper location in the filesystem itself, yielding a file identifier.   134    135 If a parent directory is being used, the object cannot be immediately   136 registered in its proper location, but since data may still need to be written   137 to storage, a temporary location is employed, yielding a file identifier.   138    139 For an object created in a temporary location, a temporary mapping from the   140 path of the object to the provider is established, with the parent directory   141 being notified of the pending object creation.   142    143 {{{   144 def create_object(path):   145     provider = get_provider(path)   146    147     if provider:   148         return error   149    150     dirname, basename = split(path)   151     directory_provider = get_provider(dirname)   152    153     if directory_provider:   154         provider = make_provider(get_temporary_location(path))   155         directory_provider.create_pending(provider)   156         return register_created_provider(path, provider)   157    158     provider = make_provider(path)   159     return register_provider(provider)   160 }}}   161    162 == Created Providers ==   163    164 Created providers are retained by the registry until their files can be   165 committed to the filesystem in the desired location.   166    167 The `register_created_provider` operation establishes a mapping from a path to   168 a provider that can be queried using the `find_created_provider` operation.   169    170 Created providers are deregistered when they are closed. This will occur when   171 the parent directory of the file to be committed is closed. At that time, the   172 created file will be moved from its temporary location to the desired   173 location.   174    175 == Inaccessible Providers ==   176    177 Inaccessible providers are retained by the registry until they are closed.   178    179 Where the provided file resides in a non-temporary location, closure will   180 occur when the parent directory of the provided file is closed, this having   181 obstructed the removal of the file. At that time, the provided file will be   182 removed.   183    184 Where the provided file resides in a temporary location, closure will not be   185 obstructed by any directory and will cause the file to be removed immediately.   186    187 == Directory Provider Closure ==   188    189 A critical event that typically initiates housekeeping work for created and   190 removed files is the closure of the parent directory of those files.   191    192 Directory providers support the `create_pending` and `remove_pending`   193 operations that register the details of affected files. When closure occurs,   194 the provider will contact the registry to initiate the necessary work to   195 relocate created files and to remove files.   196    197    198    199    200   Where an object provider is notified of pending removal, it will initiate   201   removal of the actual object upon closure, checking for an active parent   202   provider.   203    204   Where a parent provider is notified of pending removal, it will initiate   205   removal of the actual object upon closure, checking for an active object   206   provider.   207    208   Object opening logic would need to be adjusted. Consider the case where a   209   file is removed but still open.   210    211     Any attempt to open a file with the same name must ignore the original and   212     open a new file of that name which would be stored elsewhere until such   213     time as the original is actually removed from its location.   214    215     This new file might have a different identifier since the original file   216     would still exist and retain the identifier.   217    218     Any such new, but uncommitted, file must be accessible by other clients   219     attempting to open a file of that name. However, removal operations must   220     also be possible, making this version of the open file also unaccessible   221     to new opening clients.   222    223     Therefore, any providers used by opening clients must only refer to a   224     version of a file that is pending removal if no other version has been   225     created. Once a new version has been created, any provider pending removal   226     must be relegated to a separate collection.   227    228     Storage of new versions of files could be confined to special directories   229     that are hidden from clients.   230    231     The opening logic would be as follows:   232    233       provider = find_provider(path)   234    235       if provider:   236           if provider.pending_removal():   237               relegate(provider)   238               provider = create_provider(path, hidden=True)   239       else:   240           provider = create_provider(path, hidden=False)   241    242       # Have provider.   243    244       return provider.make_resource()   245    246     A provider would normally be obtained by consulting the filesystem   247     implementation. However, new versions of files replacing ones pending   248     removal will reside in locations that are different to the intended   249     location of the file. Consequently, the registry needs to maintain its own   250     mapping of paths to providers for such file versions.   251    252     The opportunity to remove a file definitively arises when the following   253     conditions are satisfied:   254    255       * The parent directory is not open in some way   256       * The original provider for the file is no longer open   257    258     For new versions of a removed file that have themselves been marked as   259     pending removal, their closure is sufficient to remove their filesystem   260     resources.   261    262     However, the registry must maintain a path entry for any active version   263     of a removed file until that version is closed. Thus, the following   264     conditions apply:   265    266       * The parent directory (of the original file) is not open in some way   267       * The provider of the new version is no longer open   268    269     It will not be generally possible to open the hidden directory containing   270     new file versions. Therefore, the transfer of the file to its intended   271     location will not risk interfering with any operations on the hidden   272     directory.   273