Filesystem Access

Within the filesystem server library, a number of different abstractions and mechanisms are employed to provide access to filesystem objects. An overview of these abstractions is presented below.

componentsConfigures openercomponentsFilesystemopen_for_userOpenerExposesfile openoperationResourceRegistryRecordsopen filesessionsResource(Pager)ProviderRegistry...file-nprovider-n...FileOpeningProvidesfilesystemcontentProviderRepresentsopen filePageMapperProvidespopulatedfile pagesExposesfilesystemfunctionalityAccessorPopulatesfile pages

Firstly, an Opener must be obtained from a Filesystem, this configuring the Opener for a particular user identity.

An Opener requests a Resource from a ResourceRegistry, each Resource acting as a Pager and providing the actual access mechanism to file content for a particular program. Since many programs may access the same file simultaneously, a Provider object represents a file opened in the system, retaining a PageMapper that coordinates the collective access to the file (see the paging documentation for more information).

A ProviderRegistry maintains the record of opened files, yielding a new Provider for an unopened file or an existing Provider for a file that is already open. The ProviderRegistry monitors the usage of files, discarding any Provider no longer in use.

Opening Files

Opening a file involves the identification of the filesystem object involved, the acquisition of a Provider representing the file, and the creation of a Resource to deliver file content to the requesting program.

opening_openExposesfile openoperationOpenerResourceRegistryget_resourceRecordsopen filesessionsResource(Pager)FileOpeningget_fileidProviderRegistryget(fileid)Providermake_resourceProvidesfilesystemcontentResource(Pager)ExposesfilesystemfunctionalityProvidesopen filesRepresentsopen file

Where a provider does not already exist, with the file not having been opened already, some extra interactions occur:

opening_unopenedOpenerResourceRegistryProviderFileOpeningmake_accessorCreatedand set inregistryProviderRegistryset(fileid)AccessorPageMapperCreatedfor providerRecordsopen filesExposesfilesystemfunctionality

The Resource obtained to deliver file content to a client will be served by a distinct thread through a dedicated communications endpoint, leaving the Opener available to satisfy other requests. This new thread will remain active while a file remains open, being terminated when the file is closed and the communications endpoint released by the client.

Notifications

Within the filesystem access architecture, users of files may act in ways that may notify other users of the same file. To support such notifications, an interface is provided for filesystem clients to subscribe and unsubscribe to notifications. The notifications themselves occur when files are opened, modified and closed. Pipes also generate notifications when a pipe reader makes more space available for the writer.

notification_subscriptionsClientprogramNotifiersubscribeClientprogramNotifiersubscribeCreated fornotificationsNotifierResourceNotifierResourceCreated toreceivenotificationsResource(Pager)subscribeResource(Pager)subscribeNotifierResourceNotifierResourcePropagated toproviderProvidersubscribesubscribeManages filesubscriptions

An example of a notification scenario is given below:

notificationsClientprogramResource(Pager)resizeClientprogramNotifierwaitPropagatesnotificationsProviderNotifierResourcenotifyReceivesnotificationsnotifyGeneratesnotificationnotify_othersCreated fornotifications

Notifications provide the basis for blocking reading and writing operations, with pipe endpoints depending on such blocking for efficient use of pipes. The interactions involved when transferring data through pipes are depicted below.

pipe_notificationsFill pipethen requestmore spaceClientprogram(writer)Waiting afterfilling pipeResource(PipePager)next_regionClientprogram(writer)NotifierwaitWaiting formore contentbefore readingClientprogram(reader)NotifierwaitEmpty pipethen requestmore contentClientprogram(reader)Resource(PipePager)next_regionProvider(PipePaging)add_regionProvider(PipePaging)next_regionnotifynotify

Closing Files

Files are closed when client programs release their references to the resource capabilities used to access files. The mechanism by which this is done involves the registration of an IRQ object that is bound to the same thread as the one used by resources to service file access requests. This IRQ object is associated with the IPC gate through which such requests occur, and the IRQ object is configured to deliver an interrupt message when the final reference to the IPC gate has been released.

When a client program terminates, its references to capabilities should be released, and this should cause a reference counter associated with the IPC gate to decrement. Upon the loss of the final reference and the delivery of the interrupt, the server framework will call a close method on the Resource object concerned, this implementing the Accountable interface.

closingClientprogramIPC gate(release)ActualendpointIRQResourceServerHandlesrequestsResource(Pager)closeProvidernotify_othersunsubscribeProviderRegistrydetachdetachdelete

As a consequence of closing a file, an unsubscribe operation performed on the Provider should cause any Notifier objects associated with the Resource object to be released. Meanwhile, the ResourceServer will discard the Resource object before the server thread terminates.

Removing Files

Unix filesystem semantics typically allow a file to be "unlinked" while still being accessed by a program, with accesses still being directed to the file, but with the file being removed from a directory and potentially being replaced by another file. To support this, a mechanism is provided to defer any removal of an open file.

removingRemovingopen fileClientprogramClientprogramOpenerremove(via context)Closesopen fileResource(Pager)closeProvidernotify_othersunsubscribeProviderRegistrydetachResourceRegistryremove_providerProviderMaintainsremovalstateAccessorremoveProviderRegistryremoveFileOpeningPerformingfilesystemoperationsremove_pendingget(fileid)get_fileidunlink_object