1.1 --- a/conf/dstest_file.cfg Fri Jul 16 00:40:22 2021 +0200 1.2 +++ b/conf/dstest_file.cfg Sun Jul 18 00:47:14 2021 +0200 1.3 @@ -20,4 +20,4 @@ 1.4 }, 1.5 log = { "client", "g" }, 1.6 }, 1.7 - "rom/dstest_file_client", "rom/dstest_file.cfg"); 1.8 + "rom/dstest_file_client", "new file");
2.1 --- a/libfsserver/include/fsserver/block_file_accessor.h Fri Jul 16 00:40:22 2021 +0200 2.2 +++ b/libfsserver/include/fsserver/block_file_accessor.h Sun Jul 18 00:47:14 2021 +0200 2.3 @@ -44,6 +44,8 @@ 2.4 virtual void flush_populated(Flexpage *flexpage); 2.5 2.6 public: 2.7 + explicit BlockFileAccessor(fileid_t fileid); 2.8 + 2.9 explicit BlockFileAccessor(FILE *fp, fileid_t fileid); 2.10 2.11 virtual offset_t get_size();
3.1 --- a/libfsserver/include/fsserver/block_file_opener.h Fri Jul 16 00:40:22 2021 +0200 3.2 +++ b/libfsserver/include/fsserver/block_file_opener.h Sun Jul 18 00:47:14 2021 +0200 3.3 @@ -32,7 +32,9 @@ 3.4 protected: 3.5 /* Configurable methods. */ 3.6 3.7 - virtual Accessor *make_accessor(const char *path, fileid_t fileid); 3.8 + virtual fileid_t get_fileid(const char *path, flags_t flags); 3.9 + 3.10 + virtual long make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor); 3.11 3.12 public: 3.13 explicit BlockFileOpener(Pages *pages)
4.1 --- a/libfsserver/include/fsserver/ext2_file_opener.h Fri Jul 16 00:40:22 2021 +0200 4.2 +++ b/libfsserver/include/fsserver/ext2_file_opener.h Sun Jul 18 00:47:14 2021 +0200 4.3 @@ -36,9 +36,9 @@ 4.4 4.5 /* Configurable methods. */ 4.6 4.7 - virtual fileid_t get_fileid(const char *path); 4.8 + virtual fileid_t get_fileid(const char *path, flags_t flags); 4.9 4.10 - virtual Accessor *make_accessor(const char *path, fileid_t fileid); 4.11 + virtual long make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor); 4.12 4.13 public: 4.14 explicit Ext2FileOpener(ext2_filsys fs, Pages *pages)
5.1 --- a/libfsserver/include/fsserver/file_paging.h Fri Jul 16 00:40:22 2021 +0200 5.2 +++ b/libfsserver/include/fsserver/file_paging.h Sun Jul 18 00:47:14 2021 +0200 5.3 @@ -50,9 +50,9 @@ 5.4 5.5 /* Pager initialisation methods. */ 5.6 5.7 - PageMapper *get_mapper(const char *path, fileid_t fileid); 5.8 + long get_mapper(const char *path, flags_t flags, fileid_t fileid, PageMapper **mapper); 5.9 5.10 - Pager *get_pager(const char *path, fileid_t fileid, map_flags_t flags); 5.11 + long get_pager(const char *path, flags_t flags, Pager **pager); 5.12 5.13 /* Configurable methods. */ 5.14 5.15 @@ -60,9 +60,9 @@ 5.16 5.17 /* Configurable methods requiring implementation. */ 5.18 5.19 - virtual fileid_t get_fileid(const char *path) = 0; 5.20 + virtual fileid_t get_fileid(const char *path, flags_t flags) = 0; 5.21 5.22 - virtual Accessor *make_accessor(const char *path, fileid_t fileid) = 0; 5.23 + virtual long make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor) = 0; 5.24 5.25 /* Mapper registry access. */ 5.26
6.1 --- a/libfsserver/include/fsserver/host_file_opener.h Fri Jul 16 00:40:22 2021 +0200 6.2 +++ b/libfsserver/include/fsserver/host_file_opener.h Sun Jul 18 00:47:14 2021 +0200 6.3 @@ -46,11 +46,13 @@ 6.4 6.5 HostFileIdentifiers _fileids; 6.6 6.7 + virtual fileid_t _get_fileid(const char *path, bool create); 6.8 + 6.9 /* Configurable methods. */ 6.10 6.11 - virtual fileid_t get_fileid(const char *path); 6.12 + virtual fileid_t get_fileid(const char *path, flags_t flags); 6.13 6.14 - virtual Accessor *make_accessor(const char *path, fileid_t fileid); 6.15 + virtual long make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor); 6.16 6.17 public: 6.18 explicit HostFileOpener(Pages *pages)
7.1 --- a/libfsserver/include/fsserver/test_file_opener.h Fri Jul 16 00:40:22 2021 +0200 7.2 +++ b/libfsserver/include/fsserver/test_file_opener.h Sun Jul 18 00:47:14 2021 +0200 7.3 @@ -34,9 +34,9 @@ 7.4 7.5 /* Configurable methods. */ 7.6 7.7 - virtual fileid_t get_fileid(const char *path); 7.8 + virtual fileid_t get_fileid(const char *path, flags_t flags); 7.9 7.10 - virtual Accessor *make_accessor(const char *path, fileid_t fileid); 7.11 + virtual long make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor); 7.12 7.13 public: 7.14 explicit TestFileOpener(Pages *pages, offset_t file_size=0);
8.1 --- a/libfsserver/lib/files/block_file_accessor.cc Fri Jul 16 00:40:22 2021 +0200 8.2 +++ b/libfsserver/lib/files/block_file_accessor.cc Sun Jul 18 00:47:14 2021 +0200 8.3 @@ -30,6 +30,12 @@ 8.4 8.5 8.6 8.7 +BlockFileAccessor::BlockFileAccessor(fileid_t fileid) 8.8 +: Accessor(fileid), _fp(NULL) 8.9 +{ 8.10 + _size = 0; 8.11 +} 8.12 + 8.13 BlockFileAccessor::BlockFileAccessor(FILE *fp, fileid_t fileid) 8.14 : Accessor(fileid), _fp(fp) 8.15 {
9.1 --- a/libfsserver/lib/files/block_file_opener.cc Fri Jul 16 00:40:22 2021 +0200 9.2 +++ b/libfsserver/lib/files/block_file_opener.cc Sun Jul 18 00:47:14 2021 +0200 9.3 @@ -19,19 +19,55 @@ 9.4 * Boston, MA 02110-1301, USA 9.5 */ 9.6 9.7 +#include <systypes/fcntl.h> 9.8 + 9.9 #include "block_file_accessor.h" 9.10 #include "block_file_opener.h" 9.11 9.12 +/* Return a file identifier for the given 'path'. */ 9.13 + 9.14 +fileid_t BlockFileOpener::get_fileid(const char *path, flags_t flags) 9.15 +{ 9.16 + /* Obtain any registered identifier for the path. */ 9.17 + 9.18 + fileid_t fileid = _get_fileid(path, false); 9.19 + 9.20 + if (fileid != FILEID_INVALID) 9.21 + return fileid; 9.22 + 9.23 + /* Test for a valid file or an attempt to create a file. */ 9.24 + 9.25 + FILE *fp = fopen(path, "r"); 9.26 + 9.27 + if (fp == NULL) 9.28 + { 9.29 + if (!(flags & O_CREAT)) 9.30 + return FILEID_INVALID; 9.31 + } 9.32 + else 9.33 + fclose(fp); 9.34 + 9.35 + return _get_fileid(path, true); 9.36 +} 9.37 + 9.38 /* Return a new accessor for 'fileid'. */ 9.39 9.40 -Accessor *BlockFileOpener::make_accessor(const char *path, fileid_t fileid) 9.41 +long BlockFileOpener::make_accessor(const char *path, flags_t flags, 9.42 + fileid_t fileid, Accessor **accessor) 9.43 { 9.44 FILE *fp = fopen(path, "r"); 9.45 9.46 if (fp == NULL) 9.47 - return NULL; 9.48 + { 9.49 + if (flags & O_CREAT) 9.50 + *accessor = new BlockFileAccessor(fileid); 9.51 + else 9.52 + return -L4_ENOENT; 9.53 + } 9.54 + else 9.55 + *accessor = new BlockFileAccessor(fp, fileid); 9.56 9.57 - return new BlockFileAccessor(fp, fileid); 9.58 + return L4_EOK; 9.59 } 9.60 9.61 // vim: tabstop=4 expandtab shiftwidth=4
10.1 --- a/libfsserver/lib/files/ext2_file_opener.cc Fri Jul 16 00:40:22 2021 +0200 10.2 +++ b/libfsserver/lib/files/ext2_file_opener.cc Sun Jul 18 00:47:14 2021 +0200 10.3 @@ -26,13 +26,15 @@ 10.4 10.5 /* Return a file identifier for the given 'path'. */ 10.6 10.7 -fileid_t Ext2FileOpener::get_fileid(const char *path) 10.8 +fileid_t Ext2FileOpener::get_fileid(const char *path, flags_t flags) 10.9 { 10.10 /* Obtain the inode number. */ 10.11 10.12 ext2_ino_t ino; 10.13 errcode_t retval = image_find_path(_fs, &path, &ino); 10.14 10.15 + // NOTE: Support file creation. 10.16 + 10.17 if (retval) 10.18 return FILEID_INVALID; 10.19 10.20 @@ -41,17 +43,20 @@ 10.21 10.22 /* Return a new accessor for 'fileid'. */ 10.23 10.24 -Accessor *Ext2FileOpener::make_accessor(const char *path, fileid_t fileid) 10.25 +long Ext2FileOpener::make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor) 10.26 { 10.27 - (void) path; 10.28 + (void) path; (void) flags; 10.29 10.30 ext2_file_t file; 10.31 errcode_t retval = ext2fs_file_open(_fs, (ext2_ino_t) fileid, EXT2_FILE_WRITE, &file); 10.32 10.33 + // NOTE: Map error conditions. 10.34 + 10.35 if (retval) 10.36 - return NULL; 10.37 + return -L4_EIO; 10.38 10.39 - return new Ext2FileAccessor(file, fileid); 10.40 + *accessor = new Ext2FileAccessor(file, fileid); 10.41 + return L4_EOK; 10.42 } 10.43 10.44 // vim: tabstop=4 expandtab shiftwidth=4
11.1 --- a/libfsserver/lib/files/file_paging.cc Fri Jul 16 00:40:22 2021 +0200 11.2 +++ b/libfsserver/lib/files/file_paging.cc Sun Jul 18 00:47:14 2021 +0200 11.3 @@ -82,46 +82,59 @@ 11.4 /* Obtain a page mapper for the 'fileid' or register a new one in the 11.5 paging object. */ 11.6 11.7 -PageMapper *FilePaging::get_mapper(const char *path, fileid_t fileid) 11.8 +long FilePaging::get_mapper(const char *path, flags_t flags, fileid_t fileid, PageMapper **mapper) 11.9 { 11.10 /* Obtain any registered page mapper. */ 11.11 11.12 - PageMapper *mapper = get(fileid); 11.13 + *mapper = get(fileid); 11.14 11.15 - if (mapper != NULL) 11.16 - return mapper; 11.17 + if (*mapper != NULL) 11.18 + return L4_EOK; 11.19 11.20 /* Make an accessor and page mapper, registering the mapper. */ 11.21 11.22 - Accessor *accessor = make_accessor(path, fileid); 11.23 + Accessor *accessor; 11.24 + long err = make_accessor(path, flags, fileid, &accessor); 11.25 11.26 - if (accessor == NULL) 11.27 - return NULL; 11.28 + if (err) 11.29 + return err; 11.30 11.31 - mapper = new PageMapper(accessor, _pages); 11.32 + *mapper = new PageMapper(accessor, _pages); 11.33 11.34 - set(fileid, mapper); 11.35 + set(fileid, *mapper); 11.36 11.37 - return mapper; 11.38 + return L4_EOK; 11.39 } 11.40 11.41 11.42 11.43 /* Return a pager initialised with a page mapper. */ 11.44 11.45 -Pager *FilePaging::get_pager(const char *path, fileid_t fileid, map_flags_t flags) 11.46 +long FilePaging::get_pager(const char *path, flags_t flags, Pager **pager) 11.47 { 11.48 std::lock_guard<std::mutex> guard(_lock); 11.49 11.50 + /* Obtain an identifier for the file, even for new files. */ 11.51 + 11.52 + fileid_t fileid = get_fileid(path, flags); 11.53 + 11.54 + if (fileid == FILEID_INVALID) 11.55 + return -L4_ENOENT; 11.56 + 11.57 + /* Obtain any existing page mapper registered for the file, or make a new 11.58 + page mapper. */ 11.59 + 11.60 + PageMapper *mapper; 11.61 + long err = get_mapper(path, flags, fileid, &mapper); 11.62 + 11.63 + if (err) 11.64 + return err; 11.65 + 11.66 /* Initialise the pager with the mapper and a reference to this object for 11.67 closing the mapper and accessor. */ 11.68 11.69 - PageMapper *mapper = get_mapper(path, fileid); 11.70 - 11.71 - if (mapper == NULL) 11.72 - return NULL; 11.73 - 11.74 - return new FilePager(fileid, mapper, flags, this); 11.75 + *pager = new FilePager(fileid, mapper, get_flags(flags), this); 11.76 + return L4_EOK; 11.77 } 11.78 11.79 /* Detach a pager, potentially removing its resources. */
12.1 --- a/libfsserver/lib/files/host_file_opener.cc Fri Jul 16 00:40:22 2021 +0200 12.2 +++ b/libfsserver/lib/files/host_file_opener.cc Sun Jul 18 00:47:14 2021 +0200 12.3 @@ -24,7 +24,23 @@ 12.4 12.5 /* Return a file identifier for the given 'path'. */ 12.6 12.7 -fileid_t HostFileOpener::get_fileid(const char *path) 12.8 +fileid_t HostFileOpener::get_fileid(const char *path, flags_t flags) 12.9 +{ 12.10 + (void) flags; 12.11 + 12.12 + /* Test for a valid file or an attempt to create a file. */ 12.13 + 12.14 + FILE *fp = fopen(path, "r"); 12.15 + 12.16 + if (fp == NULL) 12.17 + return FILEID_INVALID; 12.18 + 12.19 + fclose(fp); 12.20 + 12.21 + return _get_fileid(path, true); 12.22 +} 12.23 + 12.24 +fileid_t HostFileOpener::_get_fileid(const char *path, bool create) 12.25 { 12.26 std::lock_guard<std::mutex> guard(_lock); 12.27 12.28 @@ -40,6 +56,9 @@ 12.29 if (it != _fileids.end()) 12.30 return it->second; 12.31 12.32 + if (!create) 12.33 + return FILEID_INVALID; 12.34 + 12.35 fileid_t fileid = _fileids.size(); 12.36 12.37 _fileids[s] = fileid; 12.38 @@ -49,14 +68,19 @@ 12.39 12.40 /* Return a new accessor for 'fileid'. */ 12.41 12.42 -Accessor *HostFileOpener::make_accessor(const char *path, fileid_t fileid) 12.43 +long HostFileOpener::make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor) 12.44 { 12.45 + // NOTE: Not testing for create or write flags. 12.46 + 12.47 + (void) flags; 12.48 + 12.49 FILE *fp = fopen(path, "r"); 12.50 12.51 if (fp == NULL) 12.52 - return NULL; 12.53 + return -L4_ENOENT; 12.54 12.55 - return new HostFileAccessor(fp, fileid); 12.56 + *accessor = new HostFileAccessor(fp, fileid); 12.57 + return L4_EOK; 12.58 } 12.59 12.60 // vim: tabstop=4 expandtab shiftwidth=4
13.1 --- a/libfsserver/lib/files/opener_resource.cc Fri Jul 16 00:40:22 2021 +0200 13.2 +++ b/libfsserver/lib/files/opener_resource.cc Sun Jul 18 00:47:14 2021 +0200 13.3 @@ -46,15 +46,7 @@ 13.4 13.5 long OpenerResource::open(const char *path, flags_t flags, Pager **pager) 13.6 { 13.7 - fileid_t fileid = get_fileid(path); 13.8 - 13.9 - /* Handle non-existent files. */ 13.10 - 13.11 - if (fileid == FILEID_INVALID) 13.12 - return -L4_ENOENT; 13.13 - 13.14 - *pager = get_pager(path, fileid, get_flags(flags)); 13.15 - return L4_EOK; 13.16 + return get_pager(path, flags, pager); 13.17 } 13.18 13.19
14.1 --- a/libfsserver/lib/files/test_file_opener.cc Fri Jul 16 00:40:22 2021 +0200 14.2 +++ b/libfsserver/lib/files/test_file_opener.cc Sun Jul 18 00:47:14 2021 +0200 14.3 @@ -33,8 +33,10 @@ 14.4 14.5 /* Return a file identifier for the given 'path'. */ 14.6 14.7 -fileid_t TestFileOpener::get_fileid(const char *path) 14.8 +fileid_t TestFileOpener::get_fileid(const char *path, flags_t flags) 14.9 { 14.10 + (void) flags; 14.11 + 14.12 /* NOTE: Just convert the path to a number. */ 14.13 14.14 return atol(path); 14.15 @@ -42,10 +44,11 @@ 14.16 14.17 /* Return a new accessor for 'fileid'. */ 14.18 14.19 -Accessor *TestFileOpener::make_accessor(const char *path, fileid_t fileid) 14.20 +long TestFileOpener::make_accessor(const char *path, flags_t flags, fileid_t fileid, Accessor **accessor) 14.21 { 14.22 - (void) path; 14.23 - return new TestFileAccessor(fileid, _file_size); 14.24 + (void) flags; (void) path; 14.25 + *accessor = new TestFileAccessor(fileid, _file_size); 14.26 + return L4_EOK; 14.27 } 14.28 14.29 // vim: tabstop=4 expandtab shiftwidth=4
15.1 --- a/tests/dstest_file_client.cc Fri Jul 16 00:40:22 2021 +0200 15.2 +++ b/tests/dstest_file_client.cc Sun Jul 18 00:47:14 2021 +0200 15.3 @@ -145,7 +145,7 @@ 15.4 15.5 /* Invoke the open function to receive each file reference. */ 15.6 15.7 - file_t *file1 = client_open(filename, O_RDWR); // | O_CREAT 15.8 + file_t *file1 = client_open(filename, O_RDWR | O_CREAT); 15.9 file_t *file2 = client_open(filename, O_RDWR); 15.10 15.11 if ((file1 == NULL) || (file2 == NULL))