1.1 --- a/libfsserver/include/fsserver/ext2_file_accessor.h Sun Jul 25 23:18:39 2021 +0200 1.2 +++ b/libfsserver/include/fsserver/ext2_file_accessor.h Fri Jul 30 00:20:35 2021 +0200 1.3 @@ -24,6 +24,7 @@ 1.4 #include <ext2fs/ext2fs.h> 1.5 1.6 #include <fsserver/accessor.h> 1.7 +#include <fsserver/ext2_file_operations.h> 1.8 1.9 1.10 1.11 @@ -32,6 +33,7 @@ 1.12 class Ext2FileAccessor : public Accessor 1.13 { 1.14 protected: 1.15 + Ext2FileOperations *_ops; 1.16 ext2_file_t _file; 1.17 1.18 /* Data transfer helper methods. */ 1.19 @@ -41,7 +43,8 @@ 1.20 virtual void flush_populated(Flexpage *flexpage); 1.21 1.22 public: 1.23 - explicit Ext2FileAccessor(ext2_file_t file, fileid_t fileid); 1.24 + explicit Ext2FileAccessor(Ext2FileOperations *ops, ext2_file_t file, 1.25 + fileid_t fileid); 1.26 1.27 virtual void close(); 1.28
2.1 --- a/libfsserver/include/fsserver/ext2_file_opener.h Sun Jul 25 23:18:39 2021 +0200 2.2 +++ b/libfsserver/include/fsserver/ext2_file_opener.h Fri Jul 30 00:20:35 2021 +0200 2.3 @@ -23,6 +23,7 @@ 2.4 2.5 #include <ext2fs/ext2fs.h> 2.6 2.7 +#include <fsserver/ext2_file_operations.h> 2.8 #include <fsserver/opener_resource.h> 2.9 #include <systypes/user.h> 2.10 2.11 @@ -33,12 +34,12 @@ 2.12 class Ext2FileOpener : public OpenerResource 2.13 { 2.14 protected: 2.15 - ext2_filsys _fs; 2.16 + Ext2FileOperations *_ops; 2.17 user_t _user; 2.18 2.19 public: 2.20 - explicit Ext2FileOpener(FilePaging *paging, ext2_filsys fs, user_t user) 2.21 - : OpenerResource(paging), _fs(fs), _user(user) 2.22 + explicit Ext2FileOpener(FilePaging *paging, Ext2FileOperations *ops, user_t user) 2.23 + : OpenerResource(paging), _ops(ops), _user(user) 2.24 { 2.25 } 2.26
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/libfsserver/include/fsserver/ext2_file_operations.h Fri Jul 30 00:20:35 2021 +0200 3.3 @@ -0,0 +1,62 @@ 3.4 +/* 3.5 + * File operations supporting an Ext2-compatible filesystem. 3.6 + * 3.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 3.8 + * 3.9 + * This program is free software; you can redistribute it and/or 3.10 + * modify it under the terms of the GNU General Public License as 3.11 + * published by the Free Software Foundation; either version 2 of 3.12 + * the License, or (at your option) any later version. 3.13 + * 3.14 + * This program is distributed in the hope that it will be useful, 3.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 3.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 3.17 + * GNU General Public License for more details. 3.18 + * 3.19 + * You should have received a copy of the GNU General Public License 3.20 + * along with this program; if not, write to the Free Software 3.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 3.22 + * Boston, MA 02110-1301, USA 3.23 + */ 3.24 + 3.25 +#pragma once 3.26 + 3.27 +#include <ext2fs/ext2fs.h> 3.28 + 3.29 +#include <systypes/base.h> 3.30 +#include <systypes/user.h> 3.31 + 3.32 + 3.33 + 3.34 +/* An Ext2 file operations collection. */ 3.35 + 3.36 +class Ext2FileOperations 3.37 +{ 3.38 +protected: 3.39 + ext2_filsys _fs; 3.40 + 3.41 +public: 3.42 + explicit Ext2FileOperations(ext2_filsys fs) 3.43 + : _fs(fs) 3.44 + { 3.45 + } 3.46 + 3.47 + long create_file(ext2_ino_t ino_parent, const char *filename, user_t user, 3.48 + ext2_ino_t *ino); 3.49 + 3.50 + long find_file(const char *path, ext2_ino_t *ino, const char **remaining); 3.51 + 3.52 + void close_file(ext2_file_t file); 3.53 + 3.54 + long open_file(ext2_ino_t ino, ext2_file_t *file); 3.55 + 3.56 + offset_t get_size(ext2_file_t file); 3.57 + 3.58 + void set_size(ext2_file_t file, offset_t size); 3.59 + 3.60 + offset_t read_file(ext2_file_t file, offset_t filepos, void *addr, offset_t size); 3.61 + 3.62 + void write_file(ext2_file_t file, offset_t filepos, const void *addr, offset_t size); 3.63 +}; 3.64 + 3.65 +// vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/libfsserver/include/fsserver/ext2_filesystem.h Sun Jul 25 23:18:39 2021 +0200 4.2 +++ b/libfsserver/include/fsserver/ext2_filesystem.h Fri Jul 30 00:20:35 2021 +0200 4.3 @@ -24,6 +24,7 @@ 4.4 4.5 #include <ext2fs/ext2fs.h> 4.6 4.7 +#include <fsserver/ext2_file_operations.h> 4.8 #include <fsserver/filesystem_resource.h> 4.9 4.10 4.11 @@ -33,13 +34,12 @@ 4.12 class Ext2Filesystem : public FilesystemResource 4.13 { 4.14 protected: 4.15 - ext2_filsys _fs; 4.16 + Ext2FileOperations *_ops; 4.17 4.18 public: 4.19 - explicit Ext2Filesystem(Pages *pages, ext2_filsys fs) 4.20 - : FilesystemResource(pages), _fs(fs) 4.21 - { 4.22 - } 4.23 + explicit Ext2Filesystem(Pages *pages, ext2_filsys fs); 4.24 + 4.25 + virtual ~Ext2Filesystem(); 4.26 4.27 /* Filesystem interface methods. */ 4.28
5.1 --- a/libfsserver/lib/Makefile Sun Jul 25 23:18:39 2021 +0200 5.2 +++ b/libfsserver/lib/Makefile Fri Jul 30 00:20:35 2021 +0200 5.3 @@ -43,6 +43,7 @@ 5.4 files/block_file_opener.cc \ 5.5 files/ext2_file_accessor.cc \ 5.6 files/ext2_file_opener.cc \ 5.7 + files/ext2_file_operations.cc \ 5.8 files/ext2_filesystem.cc \ 5.9 files/file_pager.cc \ 5.10 files/file_paging.cc \
6.1 --- a/libfsserver/lib/files/ext2_file_accessor.cc Sun Jul 25 23:18:39 2021 +0200 6.2 +++ b/libfsserver/lib/files/ext2_file_accessor.cc Fri Jul 30 00:20:35 2021 +0200 6.3 @@ -21,8 +21,6 @@ 6.4 6.5 #include <stdio.h> 6.6 #include <string.h> 6.7 -#include <sys/stat.h> 6.8 -#include <sys/types.h> 6.9 6.10 #include <algorithm> 6.11 6.12 @@ -32,8 +30,9 @@ 6.13 6.14 6.15 6.16 -Ext2FileAccessor::Ext2FileAccessor(ext2_file_t file, fileid_t fileid) 6.17 -: Accessor(fileid), _file(file) 6.18 +Ext2FileAccessor::Ext2FileAccessor(Ext2FileOperations *ops, ext2_file_t file, 6.19 + fileid_t fileid) 6.20 +: Accessor(fileid), _ops(ops), _file(file) 6.21 { 6.22 } 6.23 6.24 @@ -41,22 +40,21 @@ 6.25 6.26 offset_t Ext2FileAccessor::get_size() 6.27 { 6.28 - return ext2fs_file_get_size(_file); 6.29 + return _ops->get_size(_file); 6.30 } 6.31 6.32 /* Update the size of the file. */ 6.33 6.34 void Ext2FileAccessor::set_size(offset_t size) 6.35 { 6.36 - ext2fs_file_set_size(_file, size); 6.37 + _ops->set_size(_file, size); 6.38 } 6.39 6.40 /* Perform any closing operation on the file. */ 6.41 6.42 void Ext2FileAccessor::close() 6.43 { 6.44 - ext2fs_file_flush(_file); 6.45 - ext2fs_file_close(_file); 6.46 + _ops->close_file(_file); 6.47 } 6.48 6.49 /* Data transfer helper methods. */ 6.50 @@ -74,10 +72,7 @@ 6.51 6.52 /* Fill the region with file content. */ 6.53 6.54 - ext2fs_file_llseek(_file, filepos, SEEK_SET, NULL); 6.55 - 6.56 - unsigned int nread; 6.57 - ext2fs_file_read(_file, (void *) addr, flexpage->size, &nread); 6.58 + offset_t nread = _ops->read_file(_file, filepos, (void *) addr, flexpage->size); 6.59 6.60 /* Pad the flexpage with zero. */ 6.61 6.62 @@ -98,8 +93,7 @@ 6.63 6.64 /* Copy the populated region to the file. */ 6.65 6.66 - ext2fs_file_llseek(_file, filepos, SEEK_SET, NULL); 6.67 - ext2fs_file_write(_file, (const void *) addr, populated_size, NULL); 6.68 + _ops->write_file(_file, filepos, (const void *) addr, populated_size); 6.69 } 6.70 6.71 // vim: tabstop=4 expandtab shiftwidth=4
7.1 --- a/libfsserver/lib/files/ext2_file_opener.cc Sun Jul 25 23:18:39 2021 +0200 7.2 +++ b/libfsserver/lib/files/ext2_file_opener.cc Fri Jul 30 00:20:35 2021 +0200 7.3 @@ -19,8 +19,6 @@ 7.4 * Boston, MA 02110-1301, USA 7.5 */ 7.6 7.7 -#include <e2access/access.h> 7.8 -#include <e2access/image.h> 7.9 #include <e2access/path.h> 7.10 7.11 #include <systypes/fcntl.h> 7.12 @@ -32,55 +30,39 @@ 7.13 7.14 long Ext2FileOpener::get_fileid(const char *path, flags_t flags, fileid_t *fileid) 7.15 { 7.16 - const char *filename = path; 7.17 - 7.18 - /* Obtain the inode number. */ 7.19 - 7.20 ext2_ino_t ino; 7.21 - errcode_t retval = image_find_path(_fs, &filename, &ino); 7.22 - 7.23 - /* Handle a missing file. */ 7.24 - 7.25 - if (retval) 7.26 - { 7.27 - /* Create a missing file if possible. */ 7.28 - 7.29 - if (flags & O_CREAT) 7.30 - { 7.31 - /* Determine whether only the leafname is left of the path, with 7.32 - the inode number referring to the parent directory. */ 7.33 - 7.34 - if (path_is_leafname(filename)) 7.35 - { 7.36 - struct ext2_inode inode_parent; 7.37 + const char *remaining; 7.38 + long err = _ops->find_file(path, &ino, &remaining); 7.39 7.40 - /* Determine write access in the directory. */ 7.41 - 7.42 - retval = ext2fs_read_inode(_fs, ino, &inode_parent); 7.43 - 7.44 - if (retval) 7.45 - return -L4_EIO; 7.46 - 7.47 - if (!access_can_write(_user, &inode_parent)) 7.48 - return -L4_EPERM; 7.49 - 7.50 - /* If so, use the parent directory inode to create a new file. */ 7.51 + /* Return an existing file. */ 7.52 7.53 - if (image_create_file(_fs, ino, filename, 0666 & ~_user.umask, 7.54 - _user.uid, _user.gid, &ino)) 7.55 - return -L4_EIO; 7.56 - 7.57 - *fileid = (fileid_t) ino; 7.58 - return L4_EOK; 7.59 - } 7.60 - } 7.61 - 7.62 - *fileid = FILEID_INVALID; 7.63 - return -L4_ENOENT; 7.64 + if (!err) 7.65 + { 7.66 + *fileid = (fileid_t) ino; 7.67 + return L4_EOK; 7.68 } 7.69 7.70 - *fileid = (fileid_t) ino; 7.71 - return L4_EOK; 7.72 + *fileid = FILEID_INVALID; 7.73 + 7.74 + /* Create a missing file if possible. */ 7.75 + 7.76 + if (flags & O_CREAT) 7.77 + { 7.78 + /* Determine whether only the leafname is left of the path, with 7.79 + the inode number referring to the parent directory. */ 7.80 + 7.81 + if (path_is_leafname(remaining)) 7.82 + { 7.83 + err = _ops->create_file(ino, remaining, _user, &ino); 7.84 + if (err) 7.85 + return err; 7.86 + 7.87 + *fileid = (fileid_t) ino; 7.88 + return L4_EOK; 7.89 + } 7.90 + } 7.91 + 7.92 + return -L4_ENOENT; 7.93 } 7.94 7.95 /* Return a new accessor for 'fileid'. */ 7.96 @@ -90,14 +72,12 @@ 7.97 (void) path; (void) flags; 7.98 7.99 ext2_file_t file; 7.100 - errcode_t retval = ext2fs_file_open(_fs, (ext2_ino_t) fileid, EXT2_FILE_WRITE, &file); 7.101 - 7.102 - // NOTE: Map error conditions. 7.103 + long err = _ops->open_file((ext2_ino_t) fileid, &file); 7.104 7.105 - if (retval) 7.106 - return -L4_EIO; 7.107 + if (err) 7.108 + return err; 7.109 7.110 - *accessor = new Ext2FileAccessor(file, fileid); 7.111 + *accessor = new Ext2FileAccessor(_ops, file, fileid); 7.112 return L4_EOK; 7.113 } 7.114
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/libfsserver/lib/files/ext2_file_operations.cc Fri Jul 30 00:20:35 2021 +0200 8.3 @@ -0,0 +1,126 @@ 8.4 +/* 8.5 + * File operations performed by an Ext2-compatible filesystem. 8.6 + * 8.7 + * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 8.8 + * 8.9 + * This program is free software; you can redistribute it and/or 8.10 + * modify it under the terms of the GNU General Public License as 8.11 + * published by the Free Software Foundation; either version 2 of 8.12 + * the License, or (at your option) any later version. 8.13 + * 8.14 + * This program is distributed in the hope that it will be useful, 8.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 8.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.17 + * GNU General Public License for more details. 8.18 + * 8.19 + * You should have received a copy of the GNU General Public License 8.20 + * along with this program; if not, write to the Free Software 8.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 8.22 + * Boston, MA 02110-1301, USA 8.23 + */ 8.24 + 8.25 +#include <e2access/access.h> 8.26 +#include <e2access/image.h> 8.27 +#include <e2access/path.h> 8.28 + 8.29 +#include "ext2_file_operations.h" 8.30 + 8.31 +/* Create a file in the directory indicated by the given inode number with the 8.32 + given filename. The file is created with the given user permissions. */ 8.33 + 8.34 +long Ext2FileOperations::create_file(ext2_ino_t ino_parent, const char *filename, 8.35 + user_t user, ext2_ino_t *ino) 8.36 +{ 8.37 + if (!path_is_leafname(filename)) 8.38 + return -L4_EINVAL; 8.39 + 8.40 + struct ext2_inode inode_parent; 8.41 + errcode_t retval = ext2fs_read_inode(_fs, ino_parent, &inode_parent); 8.42 + 8.43 + if (retval) 8.44 + return -L4_EIO; 8.45 + 8.46 + if (!access_can_write(user, &inode_parent)) 8.47 + return -L4_EPERM; 8.48 + 8.49 + if (image_create_file(_fs, ino_parent, filename, 0666 & ~user.umask, 8.50 + user.uid, user.gid, ino)) 8.51 + return -L4_EIO; 8.52 + 8.53 + return L4_EOK; 8.54 +} 8.55 + 8.56 +/* For the given 'path', return an inode number or indicate the 'remaining' 8.57 + part of the path that cannot be resolved. */ 8.58 + 8.59 +long Ext2FileOperations::find_file(const char *path, ext2_ino_t *ino, 8.60 + const char **remaining) 8.61 +{ 8.62 + *remaining = path; 8.63 + errcode_t retval = image_find_path(_fs, remaining, ino); 8.64 + 8.65 + // NOTE: Map error conditions. 8.66 + 8.67 + if (retval) 8.68 + return -L4_EIO; 8.69 + 8.70 + return L4_EOK; 8.71 +} 8.72 + 8.73 +/* Perform closing operations on a file. */ 8.74 + 8.75 +void Ext2FileOperations::close_file(ext2_file_t file) 8.76 +{ 8.77 + ext2fs_file_flush(file); 8.78 + ext2fs_file_close(file); 8.79 +} 8.80 + 8.81 +/* Open the file associated with the indicated inode. */ 8.82 + 8.83 +long Ext2FileOperations::open_file(ext2_ino_t ino, ext2_file_t *file) 8.84 +{ 8.85 + errcode_t retval = ext2fs_file_open(_fs, ino, EXT2_FILE_WRITE, file); 8.86 + 8.87 + // NOTE: Map error conditions. 8.88 + 8.89 + if (retval) 8.90 + return -L4_EIO; 8.91 + 8.92 + return L4_EOK; 8.93 +} 8.94 + 8.95 +/* Obtain the size of a file. */ 8.96 + 8.97 +offset_t Ext2FileOperations::get_size(ext2_file_t file) 8.98 +{ 8.99 + return ext2fs_file_get_size(file); 8.100 +} 8.101 + 8.102 +/* Update the size of a file. */ 8.103 + 8.104 +void Ext2FileOperations::set_size(ext2_file_t file, offset_t size) 8.105 +{ 8.106 + ext2fs_file_set_size(file, size); 8.107 +} 8.108 + 8.109 +/* Populate the given memory region with file content. */ 8.110 + 8.111 +offset_t Ext2FileOperations::read_file(ext2_file_t file, offset_t filepos, void *addr, offset_t size) 8.112 +{ 8.113 + unsigned int nread; 8.114 + 8.115 + ext2fs_file_llseek(file, filepos, SEEK_SET, NULL); 8.116 + ext2fs_file_read(file, (void *) addr, size, &nread); 8.117 + 8.118 + return (offset_t) nread; 8.119 +} 8.120 + 8.121 +/* Transfer content from the given memory region to a file. */ 8.122 + 8.123 +void Ext2FileOperations::write_file(ext2_file_t file, offset_t filepos, const void *addr, offset_t size) 8.124 +{ 8.125 + ext2fs_file_llseek(file, filepos, SEEK_SET, NULL); 8.126 + ext2fs_file_write(file, addr, size, NULL); 8.127 +} 8.128 + 8.129 +// vim: tabstop=4 expandtab shiftwidth=4
9.1 --- a/libfsserver/lib/files/ext2_filesystem.cc Sun Jul 25 23:18:39 2021 +0200 9.2 +++ b/libfsserver/lib/files/ext2_filesystem.cc Fri Jul 30 00:20:35 2021 +0200 9.3 @@ -24,13 +24,24 @@ 9.4 #include "ext2_filesystem.h" 9.5 #include "resource_server.h" 9.6 9.7 +Ext2Filesystem::Ext2Filesystem(Pages *pages, ext2_filsys fs) 9.8 +: FilesystemResource(pages) 9.9 +{ 9.10 + _ops = new Ext2FileOperations(fs); 9.11 +} 9.12 + 9.13 +Ext2Filesystem::~Ext2Filesystem() 9.14 +{ 9.15 + delete _ops; 9.16 +} 9.17 + 9.18 /* Return a file opener object for the given user. */ 9.19 9.20 long Ext2Filesystem::open_for_user(sys_uid_t uid, sys_gid_t gid, 9.21 sys_mode_t umask, l4_cap_idx_t *ref) 9.22 { 9.23 user_t user = (user_t) {uid, gid, umask}; 9.24 - Resource *resource = new Ext2FileOpener(this, _fs, user); 9.25 + Resource *resource = new Ext2FileOpener(this, _ops, user); 9.26 9.27 /* Complete the initialisation and start a server in a new thread. 9.28 If the thread does not start, the resource will be finalised. */