# HG changeset patch # User Paul Boddie # Date 1634415071 -7200 # Node ID 20d95266049cceea415e3607a1fc99f45afc1b47 # Parent 1f0dc9161667ffd093d5ed22ff6bba93d0157f1d Made the file registry responsible for looking up existing objects and obtaining resources through a single get_resource operation, simplifying the opener resource. diff -r 1f0dc9161667 -r 20d95266049c libfsserver/include/fsserver/file_object_registry.h --- a/libfsserver/include/fsserver/file_object_registry.h Sat Oct 16 22:09:18 2021 +0200 +++ b/libfsserver/include/fsserver/file_object_registry.h Sat Oct 16 22:11:11 2021 +0200 @@ -49,6 +49,16 @@ flags_t flags, fileid_t fileid, FileProvider **file_provider); + /* Resource initialisation methods. */ + + long get_directory(FileOpening *opening, const char *path, flags_t flags, + fileid_t fileid, offset_t *size, object_flags_t *object_flags, + Resource **resource); + + long get_file(FileOpening *opening, const char *path, flags_t flags, + fileid_t fileid, offset_t *size, object_flags_t *object_flags, + Resource **resource); + public: explicit FileObjectRegistry(Pages *pages); @@ -59,11 +69,9 @@ /* Resource initialisation methods. */ - long get_directory(FileOpening *opening, const char *path, flags_t flags, - fileid_t fileid, Resource **resource); - - long get_pager(FileOpening *opening, const char *path, flags_t flags, - fileid_t fileid, Pager **pager); + long get_resource(FileOpening *opening, const char *path, flags_t flags, + offset_t *size, object_flags_t *object_flags, + Resource **resource); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r 1f0dc9161667 -r 20d95266049c libfsserver/include/fsserver/file_opening.h --- a/libfsserver/include/fsserver/file_opening.h Sat Oct 16 22:09:18 2021 +0200 +++ b/libfsserver/include/fsserver/file_opening.h Sat Oct 16 22:11:11 2021 +0200 @@ -31,6 +31,10 @@ class FileOpening { public: + virtual bool accessing_directory(const char *path, flags_t flags, fileid_t fileid) = 0; + + virtual bool accessing_file(const char *path, flags_t flags, fileid_t fileid) = 0; + virtual long get_fileid(const char *path, flags_t flags, fileid_t *fileid) = 0; virtual long make_accessor(const char *path, flags_t flags, fileid_t fileid, diff -r 1f0dc9161667 -r 20d95266049c libfsserver/include/fsserver/opener_resource.h --- a/libfsserver/include/fsserver/opener_resource.h Sat Oct 16 22:09:18 2021 +0200 +++ b/libfsserver/include/fsserver/opener_resource.h Sat Oct 16 22:11:11 2021 +0200 @@ -36,22 +36,6 @@ protected: FileObjectRegistry *_registry; - /* Convenience methods determining different object types. */ - - virtual bool accessing_directory(const char *path, flags_t flags, fileid_t fileid) = 0; - - virtual bool accessing_file(const char *path, flags_t flags, fileid_t fileid) = 0; - - /* Convenience methods obtaining different resource types. */ - - virtual long get_directory(const char *path, flags_t flags, fileid_t fileid, - offset_t *size, l4_cap_idx_t *cap, - object_flags_t *object_flags); - - virtual long get_file(const char *path, flags_t flags, fileid_t fileid, - offset_t *size, l4_cap_idx_t *cap, - object_flags_t *object_flags); - /* Retrieval methods. */ virtual long get_parent(const char *path, fileid_t *fileid); diff -r 1f0dc9161667 -r 20d95266049c libfsserver/lib/files/file_object_registry.cc --- a/libfsserver/lib/files/file_object_registry.cc Sat Oct 16 22:09:18 2021 +0200 +++ b/libfsserver/lib/files/file_object_registry.cc Sat Oct 16 22:11:11 2021 +0200 @@ -140,10 +140,9 @@ long FileObjectRegistry::get_directory(FileOpening *opening, const char *path, flags_t flags, fileid_t fileid, + offset_t *size, object_flags_t *object_flags, Resource **resource) { - std::lock_guard guard(_lock); - /* Obtain any existing provider registered for the object, or make a new provider. */ @@ -153,6 +152,11 @@ if (err) return err; + /* Provide non-file values for certain outputs. */ + + *size = 0; + *object_flags = 0; + /* Initialise the resource with the provider and a reference to this object for detaching from the provider. */ @@ -161,14 +165,13 @@ return L4_EOK; } -/* Return a pager initialised with a provider, page mapper and accessor. */ +/* Return a file pager initialised with a provider, page mapper and accessor. */ -long FileObjectRegistry::get_pager(FileOpening *opening, const char *path, - flags_t flags, fileid_t fileid, - Pager **pager) +long FileObjectRegistry::get_file(FileOpening *opening, const char *path, + flags_t flags, fileid_t fileid, + offset_t *size, object_flags_t *object_flags, + Resource **resource) { - std::lock_guard guard(_lock); - /* Obtain any existing provider registered for the file, or make a new provider. */ @@ -181,9 +184,47 @@ /* Initialise the pager with the provider and a reference to this object for detaching from the provider. */ + FilePager *pager = new FilePager(fileid, provider, get_flags(flags), this); + + /* Obtain the size details from the pager, also providing appropriate + flags. */ + + *size = pager->get_data_size(); + *object_flags = OBJECT_SUPPORTS_MMAP | OBJECT_HAS_SIZE; + provider->attach(); - *pager = new FilePager(fileid, provider, get_flags(flags), this); + *resource = pager; return L4_EOK; } + + +/* Return a resource for a filesystem object. */ + +long FileObjectRegistry::get_resource(FileOpening *opening, const char *path, + flags_t flags, offset_t *size, + object_flags_t *object_flags, + Resource **resource) +{ + std::lock_guard guard(_lock); + + /* Obtain an identifier for the file, even for new files (subject to use of + the appropriate flag). */ + + fileid_t fileid; + long err = opening->get_fileid(path, flags, &fileid); + + if (err) + return err; + + /* Test for file and directory access. */ + + if (opening->accessing_directory(path, flags, fileid)) + return get_directory(opening, path, flags, fileid, size, object_flags, resource); + else if (opening->accessing_file(path, flags, fileid)) + return get_file(opening, path, flags, fileid, size, object_flags, resource); + else + return -L4_EIO; +} + // vim: tabstop=4 expandtab shiftwidth=4 diff -r 1f0dc9161667 -r 20d95266049c libfsserver/lib/files/opener_resource.cc --- a/libfsserver/lib/files/opener_resource.cc Sat Oct 16 22:09:18 2021 +0200 +++ b/libfsserver/lib/files/opener_resource.cc Sat Oct 16 22:11:11 2021 +0200 @@ -109,11 +109,8 @@ long OpenerResource::open(const char *path, flags_t flags, offset_t *size, l4_cap_idx_t *cap, object_flags_t *object_flags) { - /* Obtain an identifier for the file, even for new files (subject to use of - the appropriate flag). */ - - fileid_t fileid; - long err = get_fileid(path, flags, &fileid); + Resource *resource; + long err = _registry->get_resource(this, path, flags, size, object_flags, &resource); if (err) return err; @@ -122,58 +119,9 @@ notify_parent(path); - /* Test for file and directory access. */ - - if (accessing_directory(path, flags, fileid)) - return get_directory(path, flags, fileid, size, cap, object_flags); - else if (accessing_file(path, flags, fileid)) - return get_file(path, flags, fileid, size, cap, object_flags); - else - return -L4_EIO; -} - - - -/* Return a directory object reference for the given file identifier. */ - -long OpenerResource::get_directory(const char *path, flags_t flags, - fileid_t fileid, offset_t *size, - l4_cap_idx_t *cap, - object_flags_t *object_flags) -{ - Resource *directory; - long err = _registry->get_directory(this, path, flags, fileid, &directory); - - if (err) - return err; + /* Start a server for the resource. */ - /* Provide non-file values for certain outputs. */ - - *size = 0; - *object_flags = 0; - - return ResourceServer(directory).start_thread(cap); -} - -/* Return a file pager. */ - -long OpenerResource::get_file(const char *path, flags_t flags, fileid_t fileid, - offset_t *size, l4_cap_idx_t *cap, - object_flags_t *object_flags) -{ - Pager *pager; - long err = _registry->get_pager(this, path, flags, fileid, &pager); - - if (err) - return err; - - /* Obtain the size details from the pager, also providing appropriate - flags. */ - - *size = pager->get_data_size(); - *object_flags = OBJECT_SUPPORTS_MMAP | OBJECT_HAS_SIZE; - - return ResourceServer(pager).start_thread(cap); + return ResourceServer(resource).start_thread(cap); }