# HG changeset patch # User Paul Boddie # Date 1626562034 -7200 # Node ID 5dd13dfc437b71b5e9982dba4c9da192c9cb218f # Parent ca21679a1f5cc4176ac9bd11d8e35faa3c5e594c Reorganised the file opening mechanism to permit file creation and more flexibility when attempting to open files. diff -r ca21679a1f5c -r 5dd13dfc437b conf/dstest_file.cfg --- a/conf/dstest_file.cfg Fri Jul 16 00:40:22 2021 +0200 +++ b/conf/dstest_file.cfg Sun Jul 18 00:47:14 2021 +0200 @@ -20,4 +20,4 @@ }, log = { "client", "g" }, }, - "rom/dstest_file_client", "rom/dstest_file.cfg"); + "rom/dstest_file_client", "new file"); diff -r ca21679a1f5c -r 5dd13dfc437b libfsserver/include/fsserver/block_file_accessor.h --- a/libfsserver/include/fsserver/block_file_accessor.h Fri Jul 16 00:40:22 2021 +0200 +++ b/libfsserver/include/fsserver/block_file_accessor.h Sun Jul 18 00:47:14 2021 +0200 @@ -44,6 +44,8 @@ virtual void flush_populated(Flexpage *flexpage); public: + explicit BlockFileAccessor(fileid_t fileid); + explicit BlockFileAccessor(FILE *fp, fileid_t fileid); virtual offset_t get_size(); diff -r ca21679a1f5c -r 5dd13dfc437b libfsserver/include/fsserver/block_file_opener.h --- a/libfsserver/include/fsserver/block_file_opener.h Fri Jul 16 00:40:22 2021 +0200 +++ b/libfsserver/include/fsserver/block_file_opener.h Sun Jul 18 00:47:14 2021 +0200 @@ -32,7 +32,9 @@ protected: /* Configurable methods. */ - virtual Accessor *make_accessor(const char *path, fileid_t fileid); + virtual fileid_t get_fileid(const char *path, flags_t flags); + + virtual long make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor); public: explicit BlockFileOpener(Pages *pages) diff -r ca21679a1f5c -r 5dd13dfc437b libfsserver/include/fsserver/ext2_file_opener.h --- a/libfsserver/include/fsserver/ext2_file_opener.h Fri Jul 16 00:40:22 2021 +0200 +++ b/libfsserver/include/fsserver/ext2_file_opener.h Sun Jul 18 00:47:14 2021 +0200 @@ -36,9 +36,9 @@ /* Configurable methods. */ - virtual fileid_t get_fileid(const char *path); + virtual fileid_t get_fileid(const char *path, flags_t flags); - virtual Accessor *make_accessor(const char *path, fileid_t fileid); + virtual long make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor); public: explicit Ext2FileOpener(ext2_filsys fs, Pages *pages) diff -r ca21679a1f5c -r 5dd13dfc437b libfsserver/include/fsserver/file_paging.h --- a/libfsserver/include/fsserver/file_paging.h Fri Jul 16 00:40:22 2021 +0200 +++ b/libfsserver/include/fsserver/file_paging.h Sun Jul 18 00:47:14 2021 +0200 @@ -50,9 +50,9 @@ /* Pager initialisation methods. */ - PageMapper *get_mapper(const char *path, fileid_t fileid); + long get_mapper(const char *path, flags_t flags, fileid_t fileid, PageMapper **mapper); - Pager *get_pager(const char *path, fileid_t fileid, map_flags_t flags); + long get_pager(const char *path, flags_t flags, Pager **pager); /* Configurable methods. */ @@ -60,9 +60,9 @@ /* Configurable methods requiring implementation. */ - virtual fileid_t get_fileid(const char *path) = 0; + virtual fileid_t get_fileid(const char *path, flags_t flags) = 0; - virtual Accessor *make_accessor(const char *path, fileid_t fileid) = 0; + virtual long make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor) = 0; /* Mapper registry access. */ diff -r ca21679a1f5c -r 5dd13dfc437b libfsserver/include/fsserver/host_file_opener.h --- a/libfsserver/include/fsserver/host_file_opener.h Fri Jul 16 00:40:22 2021 +0200 +++ b/libfsserver/include/fsserver/host_file_opener.h Sun Jul 18 00:47:14 2021 +0200 @@ -46,11 +46,13 @@ HostFileIdentifiers _fileids; + virtual fileid_t _get_fileid(const char *path, bool create); + /* Configurable methods. */ - virtual fileid_t get_fileid(const char *path); + virtual fileid_t get_fileid(const char *path, flags_t flags); - virtual Accessor *make_accessor(const char *path, fileid_t fileid); + virtual long make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor); public: explicit HostFileOpener(Pages *pages) diff -r ca21679a1f5c -r 5dd13dfc437b libfsserver/include/fsserver/test_file_opener.h --- a/libfsserver/include/fsserver/test_file_opener.h Fri Jul 16 00:40:22 2021 +0200 +++ b/libfsserver/include/fsserver/test_file_opener.h Sun Jul 18 00:47:14 2021 +0200 @@ -34,9 +34,9 @@ /* Configurable methods. */ - virtual fileid_t get_fileid(const char *path); + virtual fileid_t get_fileid(const char *path, flags_t flags); - virtual Accessor *make_accessor(const char *path, fileid_t fileid); + virtual long make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor); public: explicit TestFileOpener(Pages *pages, offset_t file_size=0); diff -r ca21679a1f5c -r 5dd13dfc437b libfsserver/lib/files/block_file_accessor.cc --- a/libfsserver/lib/files/block_file_accessor.cc Fri Jul 16 00:40:22 2021 +0200 +++ b/libfsserver/lib/files/block_file_accessor.cc Sun Jul 18 00:47:14 2021 +0200 @@ -30,6 +30,12 @@ +BlockFileAccessor::BlockFileAccessor(fileid_t fileid) +: Accessor(fileid), _fp(NULL) +{ + _size = 0; +} + BlockFileAccessor::BlockFileAccessor(FILE *fp, fileid_t fileid) : Accessor(fileid), _fp(fp) { diff -r ca21679a1f5c -r 5dd13dfc437b libfsserver/lib/files/block_file_opener.cc --- a/libfsserver/lib/files/block_file_opener.cc Fri Jul 16 00:40:22 2021 +0200 +++ b/libfsserver/lib/files/block_file_opener.cc Sun Jul 18 00:47:14 2021 +0200 @@ -19,19 +19,55 @@ * Boston, MA 02110-1301, USA */ +#include + #include "block_file_accessor.h" #include "block_file_opener.h" +/* Return a file identifier for the given 'path'. */ + +fileid_t BlockFileOpener::get_fileid(const char *path, flags_t flags) +{ + /* Obtain any registered identifier for the path. */ + + fileid_t fileid = _get_fileid(path, false); + + if (fileid != FILEID_INVALID) + return fileid; + + /* Test for a valid file or an attempt to create a file. */ + + FILE *fp = fopen(path, "r"); + + if (fp == NULL) + { + if (!(flags & O_CREAT)) + return FILEID_INVALID; + } + else + fclose(fp); + + return _get_fileid(path, true); +} + /* Return a new accessor for 'fileid'. */ -Accessor *BlockFileOpener::make_accessor(const char *path, fileid_t fileid) +long BlockFileOpener::make_accessor(const char *path, flags_t flags, + fileid_t fileid, Accessor **accessor) { FILE *fp = fopen(path, "r"); if (fp == NULL) - return NULL; + { + if (flags & O_CREAT) + *accessor = new BlockFileAccessor(fileid); + else + return -L4_ENOENT; + } + else + *accessor = new BlockFileAccessor(fp, fileid); - return new BlockFileAccessor(fp, fileid); + return L4_EOK; } // vim: tabstop=4 expandtab shiftwidth=4 diff -r ca21679a1f5c -r 5dd13dfc437b libfsserver/lib/files/ext2_file_opener.cc --- a/libfsserver/lib/files/ext2_file_opener.cc Fri Jul 16 00:40:22 2021 +0200 +++ b/libfsserver/lib/files/ext2_file_opener.cc Sun Jul 18 00:47:14 2021 +0200 @@ -26,13 +26,15 @@ /* Return a file identifier for the given 'path'. */ -fileid_t Ext2FileOpener::get_fileid(const char *path) +fileid_t Ext2FileOpener::get_fileid(const char *path, flags_t flags) { /* Obtain the inode number. */ ext2_ino_t ino; errcode_t retval = image_find_path(_fs, &path, &ino); + // NOTE: Support file creation. + if (retval) return FILEID_INVALID; @@ -41,17 +43,20 @@ /* Return a new accessor for 'fileid'. */ -Accessor *Ext2FileOpener::make_accessor(const char *path, fileid_t fileid) +long Ext2FileOpener::make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor) { - (void) path; + (void) path; (void) flags; ext2_file_t file; errcode_t retval = ext2fs_file_open(_fs, (ext2_ino_t) fileid, EXT2_FILE_WRITE, &file); + // NOTE: Map error conditions. + if (retval) - return NULL; + return -L4_EIO; - return new Ext2FileAccessor(file, fileid); + *accessor = new Ext2FileAccessor(file, fileid); + return L4_EOK; } // vim: tabstop=4 expandtab shiftwidth=4 diff -r ca21679a1f5c -r 5dd13dfc437b libfsserver/lib/files/file_paging.cc --- a/libfsserver/lib/files/file_paging.cc Fri Jul 16 00:40:22 2021 +0200 +++ b/libfsserver/lib/files/file_paging.cc Sun Jul 18 00:47:14 2021 +0200 @@ -82,46 +82,59 @@ /* Obtain a page mapper for the 'fileid' or register a new one in the paging object. */ -PageMapper *FilePaging::get_mapper(const char *path, fileid_t fileid) +long FilePaging::get_mapper(const char *path, flags_t flags, fileid_t fileid, PageMapper **mapper) { /* Obtain any registered page mapper. */ - PageMapper *mapper = get(fileid); + *mapper = get(fileid); - if (mapper != NULL) - return mapper; + if (*mapper != NULL) + return L4_EOK; /* Make an accessor and page mapper, registering the mapper. */ - Accessor *accessor = make_accessor(path, fileid); + Accessor *accessor; + long err = make_accessor(path, flags, fileid, &accessor); - if (accessor == NULL) - return NULL; + if (err) + return err; - mapper = new PageMapper(accessor, _pages); + *mapper = new PageMapper(accessor, _pages); - set(fileid, mapper); + set(fileid, *mapper); - return mapper; + return L4_EOK; } /* Return a pager initialised with a page mapper. */ -Pager *FilePaging::get_pager(const char *path, fileid_t fileid, map_flags_t flags) +long FilePaging::get_pager(const char *path, flags_t flags, Pager **pager) { std::lock_guard guard(_lock); + /* Obtain an identifier for the file, even for new files. */ + + fileid_t fileid = get_fileid(path, flags); + + if (fileid == FILEID_INVALID) + return -L4_ENOENT; + + /* Obtain any existing page mapper registered for the file, or make a new + page mapper. */ + + PageMapper *mapper; + long err = get_mapper(path, flags, fileid, &mapper); + + if (err) + return err; + /* Initialise the pager with the mapper and a reference to this object for closing the mapper and accessor. */ - PageMapper *mapper = get_mapper(path, fileid); - - if (mapper == NULL) - return NULL; - - return new FilePager(fileid, mapper, flags, this); + *pager = new FilePager(fileid, mapper, get_flags(flags), this); + return L4_EOK; } /* Detach a pager, potentially removing its resources. */ diff -r ca21679a1f5c -r 5dd13dfc437b libfsserver/lib/files/host_file_opener.cc --- a/libfsserver/lib/files/host_file_opener.cc Fri Jul 16 00:40:22 2021 +0200 +++ b/libfsserver/lib/files/host_file_opener.cc Sun Jul 18 00:47:14 2021 +0200 @@ -24,7 +24,23 @@ /* Return a file identifier for the given 'path'. */ -fileid_t HostFileOpener::get_fileid(const char *path) +fileid_t HostFileOpener::get_fileid(const char *path, flags_t flags) +{ + (void) flags; + + /* Test for a valid file or an attempt to create a file. */ + + FILE *fp = fopen(path, "r"); + + if (fp == NULL) + return FILEID_INVALID; + + fclose(fp); + + return _get_fileid(path, true); +} + +fileid_t HostFileOpener::_get_fileid(const char *path, bool create) { std::lock_guard guard(_lock); @@ -40,6 +56,9 @@ if (it != _fileids.end()) return it->second; + if (!create) + return FILEID_INVALID; + fileid_t fileid = _fileids.size(); _fileids[s] = fileid; @@ -49,14 +68,19 @@ /* Return a new accessor for 'fileid'. */ -Accessor *HostFileOpener::make_accessor(const char *path, fileid_t fileid) +long HostFileOpener::make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor) { + // NOTE: Not testing for create or write flags. + + (void) flags; + FILE *fp = fopen(path, "r"); if (fp == NULL) - return NULL; + return -L4_ENOENT; - return new HostFileAccessor(fp, fileid); + *accessor = new HostFileAccessor(fp, fileid); + return L4_EOK; } // vim: tabstop=4 expandtab shiftwidth=4 diff -r ca21679a1f5c -r 5dd13dfc437b libfsserver/lib/files/opener_resource.cc --- a/libfsserver/lib/files/opener_resource.cc Fri Jul 16 00:40:22 2021 +0200 +++ b/libfsserver/lib/files/opener_resource.cc Sun Jul 18 00:47:14 2021 +0200 @@ -46,15 +46,7 @@ long OpenerResource::open(const char *path, flags_t flags, Pager **pager) { - fileid_t fileid = get_fileid(path); - - /* Handle non-existent files. */ - - if (fileid == FILEID_INVALID) - return -L4_ENOENT; - - *pager = get_pager(path, fileid, get_flags(flags)); - return L4_EOK; + return get_pager(path, flags, pager); } diff -r ca21679a1f5c -r 5dd13dfc437b libfsserver/lib/files/test_file_opener.cc --- a/libfsserver/lib/files/test_file_opener.cc Fri Jul 16 00:40:22 2021 +0200 +++ b/libfsserver/lib/files/test_file_opener.cc Sun Jul 18 00:47:14 2021 +0200 @@ -33,8 +33,10 @@ /* Return a file identifier for the given 'path'. */ -fileid_t TestFileOpener::get_fileid(const char *path) +fileid_t TestFileOpener::get_fileid(const char *path, flags_t flags) { + (void) flags; + /* NOTE: Just convert the path to a number. */ return atol(path); @@ -42,10 +44,11 @@ /* Return a new accessor for 'fileid'. */ -Accessor *TestFileOpener::make_accessor(const char *path, fileid_t fileid) +long TestFileOpener::make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor) { - (void) path; - return new TestFileAccessor(fileid, _file_size); + (void) flags; (void) path; + *accessor = new TestFileAccessor(fileid, _file_size); + return L4_EOK; } // vim: tabstop=4 expandtab shiftwidth=4 diff -r ca21679a1f5c -r 5dd13dfc437b tests/dstest_file_client.cc --- a/tests/dstest_file_client.cc Fri Jul 16 00:40:22 2021 +0200 +++ b/tests/dstest_file_client.cc Sun Jul 18 00:47:14 2021 +0200 @@ -145,7 +145,7 @@ /* Invoke the open function to receive each file reference. */ - file_t *file1 = client_open(filename, O_RDWR); // | O_CREAT + file_t *file1 = client_open(filename, O_RDWR | O_CREAT); file_t *file2 = client_open(filename, O_RDWR); if ((file1 == NULL) || (file2 == NULL))