# HG changeset patch # User Paul Boddie # Date 1627925950 -7200 # Node ID d29545453b6a0bdf6fae0fdf71b5205c23d2d44f # Parent efe24033add9493b66d58c0d6b968d84d5158e8b Modified the pager acquisition mechanism to support different object types. diff -r efe24033add9 -r d29545453b6a libfsserver/include/fsserver/block_file_opener.h --- a/libfsserver/include/fsserver/block_file_opener.h Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/include/fsserver/block_file_opener.h Mon Aug 02 19:39:10 2021 +0200 @@ -35,6 +35,8 @@ { } + virtual ~BlockFileOpener(); + /* Configurable methods. */ virtual long get_fileid(const char *path, flags_t flags, fileid_t *fileid); diff -r efe24033add9 -r d29545453b6a libfsserver/include/fsserver/ext2_file_opener.h --- a/libfsserver/include/fsserver/ext2_file_opener.h Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/include/fsserver/ext2_file_opener.h Mon Aug 02 19:39:10 2021 +0200 @@ -37,12 +37,20 @@ Ext2FileOperations *_ops; user_t _user; + /* Convenience methods determining different object types. */ + + virtual bool accessing_directory(const char *path, flags_t flags, fileid_t fileid); + + virtual bool accessing_file(const char *path, flags_t flags, fileid_t fileid); + public: explicit Ext2FileOpener(FilePaging *paging, Ext2FileOperations *ops, user_t user) : OpenerResource(paging), _ops(ops), _user(user) { } + virtual ~Ext2FileOpener(); + /* Configurable methods. */ virtual long get_fileid(const char *path, flags_t flags, fileid_t *fileid); diff -r efe24033add9 -r d29545453b6a libfsserver/include/fsserver/ext2_file_operations.h --- a/libfsserver/include/fsserver/ext2_file_operations.h Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/include/fsserver/ext2_file_operations.h Mon Aug 02 19:39:10 2021 +0200 @@ -44,13 +44,17 @@ { } + bool is_directory(ext2_ino_t ino_file); + + bool is_file(ext2_ino_t ino_file); + long create_file(ext2_ino_t ino_parent, const char *filename, user_t user, ext2_ino_t *ino); long find_file(const char *path, ext2_ino_t *ino, const char **remaining); void close_file(ext2_file_t file); - + long open_file(ext2_ino_t ino, ext2_file_t *file); offset_t get_size(ext2_file_t file); diff -r efe24033add9 -r d29545453b6a libfsserver/include/fsserver/file_paging.h --- a/libfsserver/include/fsserver/file_paging.h Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/include/fsserver/file_paging.h Mon Aug 02 19:39:10 2021 +0200 @@ -67,7 +67,7 @@ long get_mapper(FileOpening *opening, const char *path, flags_t flags, fileid_t fileid, PageMapper **mapper); - long get_pager(FileOpening *opening, const char *path, flags_t flags, Pager **pager); + long get_pager(FileOpening *opening, const char *path, flags_t flags, fileid_t fileid, Pager **pager); /* Methods for the pager. */ diff -r efe24033add9 -r d29545453b6a libfsserver/include/fsserver/host_file_opener.h --- a/libfsserver/include/fsserver/host_file_opener.h Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/include/fsserver/host_file_opener.h Mon Aug 02 19:39:10 2021 +0200 @@ -48,12 +48,20 @@ virtual fileid_t _get_fileid(const char *path, bool create); + /* Convenience methods determining different object types. */ + + virtual bool accessing_directory(const char *path, flags_t flags, fileid_t fileid); + + virtual bool accessing_file(const char *path, flags_t flags, fileid_t fileid); + public: explicit HostFileOpener(FilePaging *paging) : OpenerResource(paging) { } + virtual ~HostFileOpener(); + /* Configurable methods. */ virtual long get_fileid(const char *path, flags_t flags, fileid_t *fileid); diff -r efe24033add9 -r d29545453b6a libfsserver/include/fsserver/opener_resource.h --- a/libfsserver/include/fsserver/opener_resource.h Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/include/fsserver/opener_resource.h Mon Aug 02 19:39:10 2021 +0200 @@ -36,9 +36,23 @@ protected: FilePaging *_paging; + /* 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 pager types. */ + + virtual long get_directory(const char *path, flags_t flags, fileid_t fileid, Pager **pager); + + virtual long get_file(const char *path, flags_t flags, fileid_t fileid, Pager **pager); + public: explicit OpenerResource(FilePaging *paging); + virtual ~OpenerResource(); + /* Server details. */ int expected_items(); diff -r efe24033add9 -r d29545453b6a libfsserver/include/fsserver/test_file_opener.h --- a/libfsserver/include/fsserver/test_file_opener.h Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/include/fsserver/test_file_opener.h Mon Aug 02 19:39:10 2021 +0200 @@ -32,9 +32,17 @@ protected: offset_t _file_size; + /* Convenience methods determining different object types. */ + + virtual bool accessing_directory(const char *path, flags_t flags, fileid_t fileid); + + virtual bool accessing_file(const char *path, flags_t flags, fileid_t fileid); + public: explicit TestFileOpener(FilePaging *paging, offset_t file_size=0); + virtual ~TestFileOpener(); + /* Configurable methods. */ virtual long get_fileid(const char *path, flags_t flags, fileid_t *fileid); diff -r efe24033add9 -r d29545453b6a libfsserver/lib/files/block_file_opener.cc --- a/libfsserver/lib/files/block_file_opener.cc Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/lib/files/block_file_opener.cc Mon Aug 02 19:39:10 2021 +0200 @@ -24,6 +24,10 @@ #include "block_file_accessor.h" #include "block_file_opener.h" +BlockFileOpener::~BlockFileOpener() +{ +} + /* Return a file identifier for the given 'path'. */ long BlockFileOpener::get_fileid(const char *path, flags_t flags, fileid_t *fileid) diff -r efe24033add9 -r d29545453b6a libfsserver/lib/files/ext2_file_opener.cc --- a/libfsserver/lib/files/ext2_file_opener.cc Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/lib/files/ext2_file_opener.cc Mon Aug 02 19:39:10 2021 +0200 @@ -26,6 +26,26 @@ #include "ext2_file_accessor.h" #include "ext2_file_opener.h" +Ext2FileOpener::~Ext2FileOpener() +{ +} + +/* Test if a directory is being accessed. */ + +bool Ext2FileOpener::accessing_directory(const char *path, flags_t flags, fileid_t fileid) +{ + (void) path; (void) flags; + return _ops->is_directory((ext2_ino_t) fileid); +} + +/* Test if a file is being accessed. */ + +bool Ext2FileOpener::accessing_file(const char *path, flags_t flags, fileid_t fileid) +{ + (void) path; (void) flags; + return _ops->is_file((ext2_ino_t) fileid); +} + /* Return a file identifier for the given 'path'. */ long Ext2FileOpener::get_fileid(const char *path, flags_t flags, fileid_t *fileid) @@ -46,7 +66,7 @@ /* Create a missing file if possible. */ - if (flags & O_CREAT) + if ((flags & O_CREAT) && (flags & ~O_DIRECTORY)) { /* Determine whether only the leafname is left of the path, with the inode number referring to the parent directory. */ diff -r efe24033add9 -r d29545453b6a libfsserver/lib/files/ext2_file_operations.cc --- a/libfsserver/lib/files/ext2_file_operations.cc Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/lib/files/ext2_file_operations.cc Mon Aug 02 19:39:10 2021 +0200 @@ -25,6 +25,22 @@ #include "ext2_file_operations.h" +/* Object type tests. */ + +bool Ext2FileOperations::is_directory(ext2_ino_t ino_file) +{ + std::lock_guard guard(_lock); + + return _image_isdir(_fs, ino_file); +} + +bool Ext2FileOperations::is_file(ext2_ino_t ino_file) +{ + std::lock_guard guard(_lock); + + return _image_isfile(_fs, ino_file); +} + /* Create a file in the directory indicated by the given inode number with the given filename. The file is created with the given user permissions. */ diff -r efe24033add9 -r d29545453b6a libfsserver/lib/files/file_paging.cc --- a/libfsserver/lib/files/file_paging.cc Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/lib/files/file_paging.cc Mon Aug 02 19:39:10 2021 +0200 @@ -110,23 +110,15 @@ /* Return a pager initialised with a page mapper. */ -long FilePaging::get_pager(FileOpening *opening, const char *path, flags_t flags, Pager **pager) +long FilePaging::get_pager(FileOpening *opening, const char *path, flags_t flags, fileid_t fileid, Pager **pager) { std::lock_guard guard(_lock); - /* Obtain an identifier for the file, even for new files. */ - - fileid_t fileid; - long err = opening->get_fileid(path, flags, &fileid); - - if (err) - return err; - /* Obtain any existing page mapper registered for the file, or make a new page mapper. */ PageMapper *mapper; - err = get_mapper(opening, path, flags, fileid, &mapper); + long err = get_mapper(opening, path, flags, fileid, &mapper); if (err) return err; diff -r efe24033add9 -r d29545453b6a libfsserver/lib/files/host_file_opener.cc --- a/libfsserver/lib/files/host_file_opener.cc Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/lib/files/host_file_opener.cc Mon Aug 02 19:39:10 2021 +0200 @@ -19,9 +19,37 @@ * Boston, MA 02110-1301, USA */ +#include + #include "host_file_accessor.h" #include "host_file_opener.h" +HostFileOpener::~HostFileOpener() +{ +} + +bool HostFileOpener::accessing_directory(const char *path, flags_t flags, fileid_t fileid) +{ + (void) flags; (void) fileid; + struct stat st; + + if (stat(path, &st)) + return false; + + return (st.st_mode & S_IFDIR) ? true : false; +} + +bool HostFileOpener::accessing_file(const char *path, flags_t flags, fileid_t fileid) +{ + (void) flags; (void) fileid; + struct stat st; + + if (stat(path, &st)) + return false; + + return (st.st_mode & S_IFREG) ? true : false; +} + /* Return a file identifier for the given 'path'. */ long HostFileOpener::get_fileid(const char *path, flags_t flags, fileid_t *fileid) diff -r efe24033add9 -r d29545453b6a libfsserver/lib/files/opener_resource.cc --- a/libfsserver/lib/files/opener_resource.cc Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/lib/files/opener_resource.cc Mon Aug 02 19:39:10 2021 +0200 @@ -30,6 +30,10 @@ { } +OpenerResource::~OpenerResource() +{ +} + int OpenerResource::expected_items() { return Opener_expected_items; @@ -46,7 +50,39 @@ long OpenerResource::open(const char *path, flags_t flags, Pager **pager) { - return _paging->get_pager(this, path, flags, pager); + /* Obtain an identifier for the file, even for new files. */ + + fileid_t fileid; + long err = get_fileid(path, flags, &fileid); + + if (err) + return err; + + /* Test for file and directory access. */ + + if (accessing_directory(path, flags, fileid)) + return get_directory(path, flags, fileid, pager); + else if (accessing_file(path, flags, fileid)) + return get_file(path, flags, fileid, pager); + else + return -L4_EIO; +} + + + +/* Return a directory pager. */ + +long OpenerResource::get_directory(const char *path, flags_t flags, fileid_t fileid, Pager **pager) +{ + (void) path; (void) flags; (void) fileid; *pager = NULL; + return -L4_EIO; +} + +/* Return a file pager. */ + +long OpenerResource::get_file(const char *path, flags_t flags, fileid_t fileid, Pager **pager) +{ + return _paging->get_pager(this, path, flags, fileid, pager); } diff -r efe24033add9 -r d29545453b6a libfsserver/lib/files/test_file_opener.cc --- a/libfsserver/lib/files/test_file_opener.cc Sun Aug 01 22:48:12 2021 +0200 +++ b/libfsserver/lib/files/test_file_opener.cc Mon Aug 02 19:39:10 2021 +0200 @@ -31,6 +31,22 @@ { } +TestFileOpener::~TestFileOpener() +{ +} + +bool TestFileOpener::accessing_directory(const char *path, flags_t flags, fileid_t fileid) +{ + (void) path; (void) flags; (void) fileid; + return false; +} + +bool TestFileOpener::accessing_file(const char *path, flags_t flags, fileid_t fileid) +{ + (void) path; (void) flags; (void) fileid; + return true; +} + /* Return a file identifier for the given 'path'. */ long TestFileOpener::get_fileid(const char *path, flags_t flags, fileid_t *fileid)