# HG changeset patch # User Paul Boddie # Date 1619298921 -7200 # Node ID 126394a73109ace5247c32f59d48bdda3f408c26 # Parent b7455dda5368225ee0b8eacad78bea585408ba8d Replaced the filesystem client accessor and opener with ext2-based equivalents. diff -r b7455dda5368 -r 126394a73109 conf/dstest_client.cfg --- a/conf/dstest_client.cfg Thu Apr 22 00:12:16 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ --- vim:set ft=lua: - -local L4 = require("L4"); - -local l = L4.default_loader; - -local blocksvr = l:new_channel(); - -l:startv({ - caps = { - server = blocksvr:svr(), - }, - log = { "blocksvr", "r" }, - }, - "rom/dstest_block_server", "10"); - -local clientsvr = l:new_channel(); - -l:startv({ - caps = { - server = blocksvr, - clientsvr = clientsvr:svr(), - }, - log = { "clientsvr", "r" }, - }, - "rom/dstest_client_server", "10", "clientsvr"); - -l:startv({ - caps = { - server = clientsvr, - }, - log = { "client", "g" }, - }, - "rom/dstest_block_client_simple", "rom/dstest_client.cfg"); diff -r b7455dda5368 -r 126394a73109 conf/dstest_client.list --- a/conf/dstest_client.list Thu Apr 22 00:12:16 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -entry dstest_client -roottask moe rom/dstest_client.cfg -module dstest_client.cfg -module l4re -module ned -module dstest_block_client_simple -module dstest_block_server -module dstest_client_server -module lib4re-c.so -module lib4re-c-util.so -module lib4re.so -module lib4re-util.so -module libc_be_l4refile.so -module libc_be_l4re.so -module libc_be_socket_noop.so -module libc_support_misc.so -module libdl.so -module libipc.so -module libl4sys-direct.so -module libl4sys.so -module libl4util.so -module libld-l4.so -module libpthread.so -module libstdc++.so -module libsupc++.so -module libuc_c.so diff -r b7455dda5368 -r 126394a73109 conf/dstest_ext2.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/dstest_ext2.cfg Sat Apr 24 23:15:21 2021 +0200 @@ -0,0 +1,34 @@ +-- vim:set ft=lua: + +local L4 = require("L4"); + +local l = L4.default_loader; + +local blocksvr = l:new_channel(); + +l:startv({ + caps = { + server = blocksvr:svr(), + }, + log = { "blocksvr", "r" }, + }, + "rom/dstest_block_server", "10"); + +local ext2svr = l:new_channel(); + +l:startv({ + caps = { + blocksvr = blocksvr, + ext2svr = ext2svr:svr(), + }, + log = { "ext2svr", "y" }, + }, + "rom/dstest_ext2_server", "blocksvr", "rom/e2test.fs", "10", "ext2svr"); + +l:startv({ + caps = { + server = ext2svr, + }, + log = { "client", "g" }, + }, + "rom/dstest_block_client_simple", "home/paulb/LICENCE.txt", "1"); diff -r b7455dda5368 -r 126394a73109 conf/dstest_ext2.list --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/dstest_ext2.list Sat Apr 24 23:15:21 2021 +0200 @@ -0,0 +1,27 @@ +entry dstest_ext2 +roottask moe rom/dstest_ext2.cfg +module dstest_ext2.cfg +module e2test.fs +module l4re +module ned +module dstest_block_client_simple +module dstest_block_server +module dstest_ext2_server +module lib4re-c.so +module lib4re-c-util.so +module lib4re.so +module lib4re-util.so +module libc_be_l4refile.so +module libc_be_l4re.so +module libc_be_socket_noop.so +module libc_support_misc.so +module libdl.so +module libipc.so +module libl4sys-direct.so +module libl4sys.so +module libl4util.so +module libld-l4.so +module libpthread.so +module libstdc++.so +module libsupc++.so +module libuc_c.so diff -r b7455dda5368 -r 126394a73109 libfsserver/Control --- a/libfsserver/Control Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/Control Sat Apr 24 23:15:21 2021 +0200 @@ -1,3 +1,3 @@ -requires: libstdc++ libc libipc libmem libfsclient +requires: libstdc++ libc libipc libmem libfsclient libext2fs libext2fs_blockserver libe2access libe2access_blockserver provides: libfsserver maintainer: paul@boddie.org.uk diff -r b7455dda5368 -r 126394a73109 libfsserver/include/fsserver/accessor.h --- a/libfsserver/include/fsserver/accessor.h Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/include/fsserver/accessor.h Sat Apr 24 23:15:21 2021 +0200 @@ -51,8 +51,6 @@ virtual void close(); - virtual void open(); - /* Data transfer methods. */ virtual void fill(Flexpage *flexpage); diff -r b7455dda5368 -r 126394a73109 libfsserver/include/fsserver/block_file_accessor.h --- a/libfsserver/include/fsserver/block_file_accessor.h Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/include/fsserver/block_file_accessor.h Sat Apr 24 23:15:21 2021 +0200 @@ -21,6 +21,8 @@ #pragma once +#include + #include @@ -32,6 +34,7 @@ { protected: offset_t _size; + FILE *_fp; char *_data; /* Data transfer helper methods. */ @@ -41,7 +44,7 @@ virtual void flush_populated(Flexpage *flexpage); public: - explicit BlockFileAccessor(const char *path, fileid_t fileid); + explicit BlockFileAccessor(FILE *fp, fileid_t fileid); virtual offset_t get_size(); diff -r b7455dda5368 -r 126394a73109 libfsserver/include/fsserver/block_file_opener.h --- a/libfsserver/include/fsserver/block_file_opener.h Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/include/fsserver/block_file_opener.h Sat Apr 24 23:15:21 2021 +0200 @@ -32,7 +32,7 @@ protected: /* Configurable methods. */ - virtual Accessor *make_accessor(fileid_t fileid); + virtual Accessor *make_accessor(const char *path, fileid_t fileid); public: explicit BlockFileOpener(Pages *pages) diff -r b7455dda5368 -r 126394a73109 libfsserver/include/fsserver/client_file_accessor.h --- a/libfsserver/include/fsserver/client_file_accessor.h Thu Apr 22 00:12:16 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * A file accessor employing a file provided via the filesystem client - * interface. - * - * Copyright (C) 2021 Paul Boddie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - -#pragma once - -#include - -#include - - - -/* A filesystem client file accessor, providing flexpages corresponding to file - regions. */ - -class ClientFileAccessor : public Accessor -{ -protected: - const char *_path; - file_t *_file; - - /* Data transfer helper methods. */ - - virtual void fill_populated(Flexpage *flexpage); - - virtual void flush_populated(Flexpage *flexpage); - -public: - explicit ClientFileAccessor(const char *path, fileid_t fileid); - - virtual void close(); - - virtual void open(); - - virtual offset_t get_size(); - - virtual void set_size(offset_t size); -}; - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r b7455dda5368 -r 126394a73109 libfsserver/include/fsserver/client_file_opener.h --- a/libfsserver/include/fsserver/client_file_opener.h Thu Apr 22 00:12:16 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * An opener for a file provided via the filesystem client interface. - * - * Copyright (C) 2021 Paul Boddie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - -#pragma once - -#include - - - -/* Support for providing access to files. */ - -class ClientFileOpener : public HostFileOpener -{ -protected: - //const char *_filename; - fileid_t _counter = 1; // NOTE: Temporary measure. - - /* Configurable methods. */ - - virtual fileid_t get_fileid(const char *path); - - virtual Accessor *make_accessor(fileid_t fileid); - -public: - explicit ClientFileOpener(Pages *pages) - : HostFileOpener(pages) - { - } -}; - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r b7455dda5368 -r 126394a73109 libfsserver/include/fsserver/ext2_file_accessor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libfsserver/include/fsserver/ext2_file_accessor.h Sat Apr 24 23:15:21 2021 +0200 @@ -0,0 +1,53 @@ +/* + * A file accessor employing a file provided by an Ext2-compatible filesystem. + * + * Copyright (C) 2021 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#pragma once + +#include + +#include + + + +/* An Ext2 file accessor, providing flexpages corresponding to file regions. */ + +class Ext2FileAccessor : public Accessor +{ +protected: + ext2_file_t _file; + + /* Data transfer helper methods. */ + + virtual void fill_populated(Flexpage *flexpage); + + virtual void flush_populated(Flexpage *flexpage); + +public: + explicit Ext2FileAccessor(ext2_file_t file, fileid_t fileid); + + virtual void close(); + + virtual offset_t get_size(); + + virtual void set_size(offset_t size); +}; + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r b7455dda5368 -r 126394a73109 libfsserver/include/fsserver/ext2_file_opener.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libfsserver/include/fsserver/ext2_file_opener.h Sat Apr 24 23:15:21 2021 +0200 @@ -0,0 +1,50 @@ +/* + * An opener for a file provided by an Ext2-compatible filesystem. + * + * Copyright (C) 2021 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#pragma once + +#include + +#include + + + +/* Support for providing access to files. */ + +class Ext2FileOpener : public OpenerResource +{ +protected: + ext2_filsys _fs; + + /* Configurable methods. */ + + virtual fileid_t get_fileid(const char *path); + + virtual Accessor *make_accessor(const char *path, fileid_t fileid); + +public: + explicit Ext2FileOpener(ext2_filsys fs, Pages *pages) + : OpenerResource(pages), _fs(fs) + { + } +}; + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r b7455dda5368 -r 126394a73109 libfsserver/include/fsserver/file_paging.h --- a/libfsserver/include/fsserver/file_paging.h Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/include/fsserver/file_paging.h Sat Apr 24 23:15:21 2021 +0200 @@ -49,9 +49,9 @@ /* Pager initialisation methods. */ - PageMapper *get_mapper(fileid_t fileid); + PageMapper *get_mapper(const char *path, fileid_t fileid); - Pager *get_pager(fileid_t fileid, flags_t flags); + Pager *get_pager(const char *path, fileid_t fileid, flags_t flags); /* Configurable methods. */ @@ -59,12 +59,14 @@ virtual flags_t get_flags(flags_t flags); - virtual Accessor *make_accessor(fileid_t fileid) = 0; + virtual Accessor *make_accessor(const char *path, fileid_t fileid) = 0; /* Mapper registry access. */ PageMapper *get(fileid_t fileid); + void remove(fileid_t fileid, PageMapper *mapper); + void set(fileid_t fileid, PageMapper *mapper); public: diff -r b7455dda5368 -r 126394a73109 libfsserver/include/fsserver/host_file_accessor.h --- a/libfsserver/include/fsserver/host_file_accessor.h Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/include/fsserver/host_file_accessor.h Sat Apr 24 23:15:21 2021 +0200 @@ -34,7 +34,6 @@ { protected: offset_t _size; - const char *_path; FILE *_fp; /* Data transfer helper methods. */ @@ -44,15 +43,13 @@ virtual void flush_populated(Flexpage *flexpage); public: - explicit HostFileAccessor(const char *path, fileid_t fileid); + explicit HostFileAccessor(FILE *fp, fileid_t fileid); virtual offset_t get_size(); virtual void set_size(offset_t size); virtual void close(); - - virtual void open(); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r b7455dda5368 -r 126394a73109 libfsserver/include/fsserver/host_file_opener.h --- a/libfsserver/include/fsserver/host_file_opener.h Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/include/fsserver/host_file_opener.h Sat Apr 24 23:15:21 2021 +0200 @@ -27,25 +27,17 @@ -/* Collection types. */ - -typedef std::map FilePaths; -typedef std::pair FilePathEntry; - - - /* Support for providing access to files. */ class HostFileOpener : public OpenerResource { protected: - FilePaths _paths; /* Configurable methods. */ virtual fileid_t get_fileid(const char *path); - virtual Accessor *make_accessor(fileid_t fileid); + virtual Accessor *make_accessor(const char *path, fileid_t fileid); public: explicit HostFileOpener(Pages *pages) diff -r b7455dda5368 -r 126394a73109 libfsserver/include/fsserver/test_file_opener.h --- a/libfsserver/include/fsserver/test_file_opener.h Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/include/fsserver/test_file_opener.h Sat Apr 24 23:15:21 2021 +0200 @@ -36,7 +36,7 @@ virtual fileid_t get_fileid(const char *path); - virtual Accessor *make_accessor(fileid_t fileid); + virtual Accessor *make_accessor(const char *path, fileid_t fileid); public: explicit TestFileOpener(Pages *pages, offset_t file_size=0); diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/Makefile --- a/libfsserver/lib/Makefile Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/lib/Makefile Sat Apr 24 23:15:21 2021 +0200 @@ -37,8 +37,8 @@ PLAIN_SRC_CC = \ files/block_file_accessor.cc \ files/block_file_opener.cc \ - files/client_file_accessor.cc \ - files/client_file_opener.cc \ + files/ext2_file_accessor.cc \ + files/ext2_file_opener.cc \ files/file_pager.cc \ files/file_paging.cc \ files/host_file_accessor.cc \ @@ -69,7 +69,9 @@ $(SERVER_INTERFACES_SRC_CC) \ $(PLAIN_SRC_CC) -REQUIRES_LIBS = l4re_c-util libmem libipc libstdc++ libsystypes libfsclient +REQUIRES_LIBS = \ + l4re_c-util libmem libipc libstdc++ libsystypes libfsclient \ + libext2fs libext2fs_blockserver libe2access libe2access_blockserver PRIVATE_INCDIR = $(PKGDIR)/include $(PKGDIR)/include/fsserver \ $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR) diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/files/block_file_accessor.cc --- a/libfsserver/lib/files/block_file_accessor.cc Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/lib/files/block_file_accessor.cc Sat Apr 24 23:15:21 2021 +0200 @@ -30,14 +30,14 @@ -BlockFileAccessor::BlockFileAccessor(const char *path, fileid_t fileid) -: Accessor(fileid) +BlockFileAccessor::BlockFileAccessor(FILE *fp, fileid_t fileid) +: Accessor(fileid), _fp(fp) { /* Obtain the size of the file. */ struct stat buf; - if (stat(path, &buf)) + if (fstat(fileno(fp), &buf)) { _size = 0; return; @@ -53,17 +53,7 @@ /* Load the file into memory and initialise the size. */ - FILE *fp = fopen(path, "r"); - - if (fp == NULL) - { - free(_data); - return; - } - _size = fread(_data, sizeof(char), _size, fp); - - fclose(fp); } /* Return the size of the file. */ diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/files/block_file_opener.cc --- a/libfsserver/lib/files/block_file_opener.cc Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/lib/files/block_file_opener.cc Sat Apr 24 23:15:21 2021 +0200 @@ -24,14 +24,14 @@ /* Return a new accessor for 'fileid'. */ -Accessor *BlockFileOpener::make_accessor(fileid_t fileid) +Accessor *BlockFileOpener::make_accessor(const char *path, fileid_t fileid) { - FilePaths::iterator found = _paths.find(fileid); + FILE *fp = fopen(path, "r"); - if (found != _paths.end()) - return new BlockFileAccessor(found->second, fileid); - else + if (fp == NULL) return NULL; + + return new BlockFileAccessor(fp, fileid); } // vim: tabstop=4 expandtab shiftwidth=4 diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/files/client_file_accessor.cc --- a/libfsserver/lib/files/client_file_accessor.cc Thu Apr 22 00:12:16 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * A file accessor using the filesystem client interface. - * - * Copyright (C) 2021 Paul Boddie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - -#include -#include - -#include - -#include -#include - -#include "client_file_accessor.h" - - - -ClientFileAccessor::ClientFileAccessor(const char *path, fileid_t fileid) -: Accessor(fileid), _path(path) -{ -} - -/* Return the size of the file. */ - -offset_t ClientFileAccessor::get_size() -{ - return _file->size; -} - -/* Update the size of the file. */ - -void ClientFileAccessor::set_size(offset_t size) -{ - file_resize(_file, size); -} - -/* Perform any closing operation on the file. */ - -void ClientFileAccessor::close() -{ - client_close(_file); -} - -/* Perform any opening operation on the file. */ - -void ClientFileAccessor::open() -{ - _file = client_open(_path, O_RDWR); -} - -/* Data transfer helper methods. */ - -/* Fill the populated portion of a flexpage. */ - -void ClientFileAccessor::fill_populated(Flexpage *flexpage) -{ - offset_t filepos = flexpage->base_offset; - offset_t addr = flexpage->base_addr; - - /* Tag the region with file state. */ - - flexpage->region->fill(fileid, filepos); - - /* Fill the region with file content. */ - - client_seek(_file, filepos, SEEK_SET); - offset_t nread = client_read(_file, (char *) addr, flexpage->size); - - /* Pad the flexpage with zero. */ - - memset((void *) (addr + nread), 0, flexpage->size - nread); -} - -/* Flush the populated portion of a flexpage. */ - -void ClientFileAccessor::flush_populated(Flexpage *flexpage) -{ - offset_t filepos = flexpage->base_offset; - offset_t addr = flexpage->base_addr; - offset_t populated_size = std::min(flexpage->size, get_size() - filepos); - - /* Remove the file state tag from the region. */ - - flexpage->region->flush(); - - /* Copy the populated region to the file. */ - - client_seek(_file, filepos, SEEK_SET); - client_write(_file, (char *) addr, populated_size); -} - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/files/client_file_opener.cc --- a/libfsserver/lib/files/client_file_opener.cc Thu Apr 22 00:12:16 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * An opener for a file provided via the filesystem client interface. - * - * Copyright (C) 2021 Paul Boddie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - */ - -#include "client_file_accessor.h" -#include "client_file_opener.h" - -/* Return a file identifier for the given 'path'. */ - -fileid_t ClientFileOpener::get_fileid(const char *path) -{ - _paths.insert(FilePathEntry(_counter, path)); - - return _counter++; -} - -/* Return a new accessor for 'fileid'. */ - -Accessor *ClientFileOpener::make_accessor(fileid_t fileid) -{ - FilePaths::iterator found = _paths.find(fileid); - - if (found != _paths.end()) - return new ClientFileAccessor(found->second, fileid); - else - return NULL; -} - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/files/ext2_file_accessor.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libfsserver/lib/files/ext2_file_accessor.cc Sat Apr 24 23:15:21 2021 +0200 @@ -0,0 +1,105 @@ +/* + * A file accessor employing a file provided by an Ext2-compatible filesystem. + * + * Copyright (C) 2021 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include + +#include + +#include + +#include "ext2_file_accessor.h" + + + +Ext2FileAccessor::Ext2FileAccessor(ext2_file_t file, fileid_t fileid) +: Accessor(fileid), _file(file) +{ +} + +/* Return the size of the file. */ + +offset_t Ext2FileAccessor::get_size() +{ + return ext2fs_file_get_size(_file); +} + +/* Update the size of the file. */ + +void Ext2FileAccessor::set_size(offset_t size) +{ + ext2fs_file_set_size(_file, size); +} + +/* Perform any closing operation on the file. */ + +void Ext2FileAccessor::close() +{ + ext2fs_file_flush(_file); + ext2fs_file_close(_file); +} + +/* Data transfer helper methods. */ + +/* Fill the populated portion of a flexpage. */ + +void Ext2FileAccessor::fill_populated(Flexpage *flexpage) +{ + offset_t filepos = flexpage->base_offset; + offset_t addr = flexpage->base_addr; + + /* Tag the region with file state. */ + + flexpage->region->fill(fileid, filepos); + + /* Fill the region with file content. */ + + ext2fs_file_llseek(_file, filepos, SEEK_SET, NULL); + + unsigned int nread; + ext2fs_file_read(_file, (void *) addr, flexpage->size, &nread); + + /* Pad the flexpage with zero. */ + + memset((void *) (addr + nread), 0, flexpage->size - nread); +} + +/* Flush the populated portion of a flexpage. */ + +void Ext2FileAccessor::flush_populated(Flexpage *flexpage) +{ + offset_t filepos = flexpage->base_offset; + offset_t addr = flexpage->base_addr; + offset_t populated_size = std::min(flexpage->size, get_size() - filepos); + + /* Remove the file state tag from the region. */ + + flexpage->region->flush(); + + /* Copy the populated region to the file. */ + + ext2fs_file_llseek(_file, filepos, SEEK_SET, NULL); + ext2fs_file_write(_file, (const void *) addr, populated_size, NULL); +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/files/ext2_file_opener.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libfsserver/lib/files/ext2_file_opener.cc Sat Apr 24 23:15:21 2021 +0200 @@ -0,0 +1,57 @@ +/* + * An opener for a file provided by an Ext2-compatible filesystem. + * + * Copyright (C) 2021 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include + +#include "ext2_file_accessor.h" +#include "ext2_file_opener.h" + +/* Return a file identifier for the given 'path'. */ + +fileid_t Ext2FileOpener::get_fileid(const char *path) +{ + /* Obtain the inode number. */ + + ext2_ino_t ino; + errcode_t retval = image_find_path(_fs, &path, &ino); + + if (retval) + return FILEID_INVALID; + + return (fileid_t) ino; +} + +/* Return a new accessor for 'fileid'. */ + +Accessor *Ext2FileOpener::make_accessor(const char *path, fileid_t fileid) +{ + (void) path; + + ext2_file_t file; + errcode_t retval = ext2fs_file_open(_fs, (ext2_ino_t) fileid, EXT2_FILE_WRITE, &file); + + if (retval) + return NULL; + + return new Ext2FileAccessor(file, fileid); +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/files/file_paging.cc --- a/libfsserver/lib/files/file_paging.cc Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/lib/files/file_paging.cc Sat Apr 24 23:15:21 2021 +0200 @@ -53,6 +53,15 @@ return mapper; } +/* Remove a page mapper and its resources for the given 'fileid'. */ + +void FilePaging::remove(fileid_t fileid, PageMapper *mapper) +{ + _mappers.erase(fileid); + delete mapper->accessor(); + delete mapper; +} + /* Register a page 'mapper' for the given 'fileid'. */ void FilePaging::set(fileid_t fileid, PageMapper *mapper) @@ -77,7 +86,7 @@ /* Obtain a page mapper for the 'fileid' or register a new one in the paging object. */ -PageMapper *FilePaging::get_mapper(fileid_t fileid) +PageMapper *FilePaging::get_mapper(const char *path, fileid_t fileid) { /* Obtain any registered page mapper. */ @@ -88,7 +97,11 @@ /* Make an accessor and page mapper, registering the mapper. */ - Accessor *accessor = make_accessor(fileid); + Accessor *accessor = make_accessor(path, fileid); + + if (accessor == NULL) + return NULL; + mapper = new PageMapper(accessor, _pages); set(fileid, mapper); @@ -100,14 +113,18 @@ /* Return a pager initialised with a page mapper. */ -Pager *FilePaging::get_pager(fileid_t fileid, flags_t flags) +Pager *FilePaging::get_pager(const char *path, fileid_t fileid, flags_t flags) { std::lock_guard guard(_lock); /* Initialise the pager with the mapper and a reference to this object for closing the mapper and accessor. */ - PageMapper *mapper = get_mapper(fileid); + PageMapper *mapper = get_mapper(path, fileid); + + if (mapper == NULL) + return NULL; + return new FilePager(fileid, mapper, flags, this); } @@ -118,11 +135,7 @@ std::lock_guard guard(_lock); if (!mapper->detach()) - { - _mappers.erase(fileid); - delete mapper->accessor(); - delete mapper; - } + remove(fileid, mapper); } // vim: tabstop=4 expandtab shiftwidth=4 diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/files/host_file_accessor.cc --- a/libfsserver/lib/files/host_file_accessor.cc Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/lib/files/host_file_accessor.cc Sat Apr 24 23:15:21 2021 +0200 @@ -26,14 +26,14 @@ #include "host_file_accessor.h" -HostFileAccessor::HostFileAccessor(const char *path, fileid_t fileid) -: Accessor(fileid), _path(path) +HostFileAccessor::HostFileAccessor(FILE *fp, fileid_t fileid) +: Accessor(fileid), _fp(fp) { /* Initialise the size of the file. */ struct stat buf; - if (!stat(_path, &buf)) + if (!fstat(fileno(fp), &buf)) _size = buf.st_size; else _size = 0; @@ -60,13 +60,6 @@ fclose(_fp); } -/* Perform any opening operation on the file. */ - -void HostFileAccessor::open() -{ - _fp = fopen(_path, "r"); -} - /* Data transfer helper methods. */ void HostFileAccessor::fill_populated(Flexpage *flexpage) diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/files/host_file_opener.cc --- a/libfsserver/lib/files/host_file_opener.cc Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/lib/files/host_file_opener.cc Sat Apr 24 23:15:21 2021 +0200 @@ -35,21 +35,19 @@ stat(path, &statbuf); - _paths.insert(FilePathEntry(statbuf.st_ino, path)); - return statbuf.st_ino; } /* Return a new accessor for 'fileid'. */ -Accessor *HostFileOpener::make_accessor(fileid_t fileid) +Accessor *HostFileOpener::make_accessor(const char *path, fileid_t fileid) { - FilePaths::iterator found = _paths.find(fileid); + FILE *fp = fopen(path, "r"); - if (found != _paths.end()) - return new HostFileAccessor(found->second, fileid); - else + if (fp == NULL) return NULL; + + return new HostFileAccessor(fp, fileid); } // vim: tabstop=4 expandtab shiftwidth=4 diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/files/opener_resource.cc --- a/libfsserver/lib/files/opener_resource.cc Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/lib/files/opener_resource.cc Sat Apr 24 23:15:21 2021 +0200 @@ -51,7 +51,7 @@ if (fileid == FILEID_INVALID) return NULL; - return get_pager(fileid, get_flags(flags)); + return get_pager(path, fileid, get_flags(flags)); } diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/files/test_file_opener.cc --- a/libfsserver/lib/files/test_file_opener.cc Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/lib/files/test_file_opener.cc Sat Apr 24 23:15:21 2021 +0200 @@ -42,8 +42,9 @@ /* Return a new accessor for 'fileid'. */ -Accessor *TestFileOpener::make_accessor(fileid_t fileid) +Accessor *TestFileOpener::make_accessor(const char *path, fileid_t fileid) { + (void) path; return new TestFileAccessor(fileid, _file_size); } diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/generic/accessor.cc --- a/libfsserver/lib/generic/accessor.cc Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/lib/generic/accessor.cc Sat Apr 24 23:15:21 2021 +0200 @@ -40,12 +40,6 @@ { } -/* Perform any opening operation on the file. */ - -void Accessor::open() -{ -} - /* Data transfer methods. */ void Accessor::fill(Flexpage *flexpage) diff -r b7455dda5368 -r 126394a73109 libfsserver/lib/mapping/page_mapper.cc --- a/libfsserver/lib/mapping/page_mapper.cc Thu Apr 22 00:12:16 2021 +0200 +++ b/libfsserver/lib/mapping/page_mapper.cc Sat Apr 24 23:15:21 2021 +0200 @@ -37,9 +37,6 @@ { std::lock_guard guard(_lock); - if (!_attached) - _accessor->open(); - _attached += 1; } diff -r b7455dda5368 -r 126394a73109 servers/Control --- a/servers/Control Thu Apr 22 00:12:16 2021 +0200 +++ b/servers/Control Sat Apr 24 23:15:21 2021 +0200 @@ -1,3 +1,3 @@ -requires: libstdc++ libc libipc libfsserver libmem +requires: libstdc++ libc libipc libfsserver libmem libe2access_blockserver provides: fsservers maintainer: paul@boddie.org.uk diff -r b7455dda5368 -r 126394a73109 servers/Makefile --- a/servers/Makefile Thu Apr 22 00:12:16 2021 +0200 +++ b/servers/Makefile Sat Apr 24 23:15:21 2021 +0200 @@ -3,7 +3,7 @@ TARGET = \ dstest_block_server \ - dstest_client_server \ + dstest_ext2_server \ dstest_host_server \ dstest_pipe_server \ dstest_test_server @@ -12,7 +12,7 @@ SRC_CC_dstest_block_server = block_file_server.cc -SRC_CC_dstest_client_server = client_file_server.cc +SRC_CC_dstest_ext2_server = ext2_file_server.cc SRC_CC_dstest_host_server = host_file_server.cc @@ -20,6 +20,6 @@ SRC_CC_dstest_test_server = test_file_server.cc -REQUIRES_LIBS = l4re_c-util libmem libfsserver libipc libstdc++ libsystypes +REQUIRES_LIBS = l4re_c-util libmem libfsserver libipc libstdc++ libsystypes libe2access_blockserver include $(L4DIR)/mk/prog.mk diff -r b7455dda5368 -r 126394a73109 servers/ext2_file_server.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servers/ext2_file_server.cc Sat Apr 24 23:15:21 2021 +0200 @@ -0,0 +1,113 @@ +/* + * A dataspace server exposing file contents from an Ext2-based filesystem. + * + * Copyright (C) 2020, 2021 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + + + +/* Default number of pages for files. */ + +const unsigned int MEMORY_PAGES = 20; + + + +/* Server program. */ + +int main(int argc, char *argv[]) +{ + /* Require filesystem object details. */ + + if (argc < 3) + { + printf("Need a filesystem capability name and filename.\n"); + return 1; + } + + const char *fs_cap = argv[1]; + const char *fs_filename = argv[2]; + long err; + + /* Introduce concurrency control. */ + + err = ipc_thread_init(); + + if (err) + { + printf("Initialisation error: %s\n", l4sys_errtostr(err)); + return 1; + } + + unsigned int memory_pages = MEMORY_PAGES; + + if (argc > 3) + memory_pages = atoi(argv[3]); + + const char *server_name = (argc > 4) ? argv[4] : "server"; + + /* Set the capability used to access the filesystem. */ + + e2access_init(fs_cap); + + /* Attempt to open the filesystem. */ + + ext2_filsys fs; + errcode_t retval = e2access_open(fs_filename, EXT2_FLAG_RW, &fs); // EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_64BITS + + if (retval) + { + printf("Could not obtain filesystem: %ld.\n", retval); + return 1; + } + + /* Some memory plus infrastructure. */ + + MemoryIncremental mem(memory_pages); + PageQueueShared queue; + Pages pages(&mem, &queue); + Ext2FileOpener opener(fs, &pages); + + /* Register a server associating it with the given object. */ + + ResourceServer server(&opener); + err = server.bind(server_name); + + if (err) + { + printf("Could not bind server: %s\n", l4sys_errtostr(err)); + return 1; + } + + printf("Starting server using %d pages...\n", memory_pages); + server.start(); + return 0; +} diff -r b7455dda5368 -r 126394a73109 tests/dstest_block_client_simple.cc --- a/tests/dstest_block_client_simple.cc Thu Apr 22 00:12:16 2021 +0200 +++ b/tests/dstest_block_client_simple.cc Sat Apr 24 23:15:21 2021 +0200 @@ -22,6 +22,7 @@ #include #include +#include #include @@ -31,13 +32,14 @@ { if (argc < 2) { - printf("Need a filename.\n"); + printf("Need a filename and optional repetition.\n"); return 1; } /* Obtain filename and access parameters. */ char *filename = argv[1]; + int repetition = argc > 2 ? atoi(argv[2]) : 10; /* Invoke the open method to receive the file reference. */ @@ -67,7 +69,7 @@ printf("Copy %ld bytes to end...\n", nread); - for (int times = 0; times < 10; times++) + for (int times = 0; times < repetition; times++) { printf("Copy #%d...\n", times);