diff --git a/doc/components.txt b/doc/components.txt index b676abe2fc..b0c1b44b7a 100644 --- a/doc/components.txt +++ b/doc/components.txt @@ -343,10 +343,6 @@ Separate components Provides each file contained in a tar file obtained via Genode's ROM session as separate ROM session. -:_os/src/server/iso9660/_: - Provides each file of an ISO9660 file system accessed via a block session as - separate ROM session. - :_os/src/server/lx_fs/_: A file system server that makes the file system of a Linux base platform available to Genode. diff --git a/repos/os/src/server/iso9660/README b/repos/os/src/server/iso9660/README deleted file mode 100644 index 9ac812303c..0000000000 --- a/repos/os/src/server/iso9660/README +++ /dev/null @@ -1,27 +0,0 @@ -This directory contains an implementation of an ISO 9660 file system. - -Limitations ------------ - -At the moment, the only file-name format supported is the Rock Ridge extension. -The ISO specified 8.3 upper-case-file names are not supported, as well as Joliet. - -Usage ------ - -The server requires an ATAPI-block device as back-end. Please have a look at -'os/src/drivers/atapi'. The front-end of the server is implemented as a ROM -session server. In order to access this server from your application, you need -to route the ROM session to the ISO-ROM-session server in Genode's configuration -file: - -! -! -! -! -! -! - -Currently, the RAM quota necessary to obtain a file from the ISO file system -is allocated on behalf of the ISO server. Please make sure to provide -sufficient RAM quota to the ISO server. diff --git a/repos/os/src/server/iso9660/iso9660.cc b/repos/os/src/server/iso9660/iso9660.cc deleted file mode 100644 index 768101e230..0000000000 --- a/repos/os/src/server/iso9660/iso9660.cc +++ /dev/null @@ -1,476 +0,0 @@ -/* - * \brief ISO 9660 file system support - * \author Sebastian Sumpf - * \date 2010-07-26 - */ - -/* - * Copyright (C) 2010-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -/* Genode includes */ -#include -#include -#include -#include -#include -#include - -#include "iso9660.h" - -using namespace Genode; - -namespace Iso { - class Sector; - class Rock_ridge; - class Iso_base; -} - - -/* - * Sector reads one or more packets from the block interface - */ -class Iso::Sector { - - public: - - enum { - MAX_SECTORS = 32, /* max. number sectors that can be read in one - transaction */ - BLOCK_SIZE = 2048, - }; - - private: - - Block::Session::Tx::Source &_source; - Block::Packet_descriptor _p { }; - - public: - - Sector(Block::Connection<> &block, - unsigned long blk_nr, unsigned long count) - : _source(*block.tx()) - { - try { - _p = Block::Packet_descriptor( - block.alloc_packet(blk_size() * count), - Block::Packet_descriptor::READ, - blk_nr * ((float)blk_size() / BLOCK_SIZE), - count * ((float)blk_size() / BLOCK_SIZE)); - - _source.submit_packet(_p); - _p = _source.get_acked_packet(); - - if (!_p.succeeded()) { - Genode::error("Could not read block ", blk_nr); - throw Io_error(); - } - - } catch (Block::Session::Tx::Source::Packet_alloc_failed) { - Genode::error("packet overrun!"); - _p = _source.get_acked_packet(); - throw Io_error(); - } - } - - ~Sector() { - _source.release_packet(_p); - } - - /** - * Return address of packet content - */ - template - T addr() { return reinterpret_cast(_source.packet_content(_p)); } - - static size_t blk_size() { return BLOCK_SIZE; } - - static unsigned long to_blk(unsigned long bytes) { - return ((bytes + blk_size() - 1) & ~(blk_size() - 1)) / blk_size(); } -}; - - -/** - * Rock ridge extension (see IEEE P1282) - */ -class Iso::Rock_ridge -{ - public: - - enum { - NM = 0x4d4e, /* POSIX name system use entry (little endian) */ - }; - - private: - - uint16_t _signature; - uint8_t _length; - uint8_t _version; - uint8_t _flags; - char _name; - - public: - - char *name() { return &_name; } - uint8_t length() { return _length - 5; } - - static Rock_ridge* scan_name(uint8_t *ptr, uint8_t size) - { - Rock_ridge *rr = (Rock_ridge *)ptr; - - while (rr->_length && ((uint8_t *)rr < ptr + size - 4)) { - if (rr->_signature == NM) - return rr; - rr = rr->next(); - } - - return 0; - } - - Rock_ridge *next() { return (Rock_ridge *)((uint8_t *)this + _length); } -}; - - -/********************* - ** ISO9660 classes ** - *********************/ - -/** - * Access memory using offsets - */ -class Iso::Iso_base -{ - protected: - - template - T value(int offset) { return *((T *)(this + offset)); } - - template - T ptr(int offset) { return (T)(this + offset); } -}; - - -/** - * Class representing a directory descriptions (see ECMA 119) - */ -class Directory_record : public Iso::Iso_base -{ - enum { - TABLE_LENGTH = 33, /* fixed length of directory record */ - - ROOT_DIR = 0x0, /* special names of root and parent directories */ - PARENT_DIR = 0x1, - - DIR_FLAG = 0x2, /* directory flag in attributes */ - }; - - public: - - /* total length of this record */ - uint8_t record_length() { return value(0); } - - /* starting block of extent */ - uint32_t blk_nr() { return value(2); } - - /* length in bytes of extent */ - uint32_t data_length() { return value(10); } - - /* attributes */ - uint8_t file_flags() { return value(25); } - - /* length of file name */ - uint8_t file_name_length() { return value(32); } - - /* retrieve the file name */ - void file_name(char *buf) - { - buf[0] = 0; - - /* try Rock Ridge name */ - Iso::Rock_ridge *rr = Iso::Rock_ridge::scan_name(system_use(), - system_use_size()); - - if (rr) { - memcpy(buf, rr->name(), rr->length()); - buf[rr->length()] = 0; - return; - } - - /* retrieve iso name */ - char *name = ptr(33); - - /* - * Check for root and parent directory names and modify them - * to '.' and '..' respectively. - */ - if (file_name_length() == 1) - - switch (name[0]) { - - case PARENT_DIR: - - buf[2] = 0; - buf[1] = '.'; - buf[0] = '.'; - return; - - case ROOT_DIR: - - buf[1] = 0; - buf[0] = '.'; - return; - } - - memcpy(buf, name, file_name_length()); - buf[file_name_length()] = 0; - } - - /* pad byte after file name (if file name length is even, only) */ - uint8_t pad_byte() { return !(file_name_length() % 2) ? 1 : 0; } - - /* system use area */ - uint8_t *system_use() - { - return (uint8_t*)this + TABLE_LENGTH - + file_name_length() + pad_byte(); - } - - /* length in bytes of system use area */ - uint8_t system_use_size() - { - return record_length() - file_name_length() - - TABLE_LENGTH - pad_byte(); - } - - /* retrieve next record */ - Directory_record *next() - { - Directory_record *_next = this + record_length(); - - if (_next->record_length()) - return _next; - - return 0; - } - - /* find a directory record with file name matching 'level' */ - Directory_record *locate(char const *level) - { - Directory_record *dir = this; - - while (dir) { - - char name[Iso::LEVEL_LENGTH]; - dir->file_name(name); - - if (!strcmp(name, level)) - return dir; - - dir = dir->next(); - } - - return 0; - } - - /* describes this record a directory */ - bool directory() { return file_flags() & DIR_FLAG; } -}; - - -/** - * Volume descriptor (see ECMA 119) - */ -class Volume_descriptor : public Iso::Iso_base -{ - enum { - /* volume types */ - PRIMARY = 0x01, /* type of primary volume descriptor */ - TERMINATOR = 0xff, /* type of terminating descriptor */ - - /* constants */ - ROOT_SIZE = 34, /* the root directory record has a fixed length */ - }; - - public: - - /* descriptor type */ - uint8_t type() { return value(0); } - - /* root directory record */ - Directory_record * root_record() { return ptr(156); } - - /* check for primary descriptor */ - bool primary() { return type() == PRIMARY; } - - /* check for terminating descriptor */ - bool terminator() { return type() == TERMINATOR; } - - /* copy the root record */ - Directory_record *copy_root_record(Genode::Allocator &alloc) - { - return alloc.try_alloc(ROOT_SIZE).convert( - - [&] (void *ptr) -> Directory_record * { - memcpy(ptr, root_record(), ROOT_SIZE); - return (Directory_record *)ptr; }, - - [&] (Allocator::Alloc_error e) -> Directory_record * { - Allocator::throw_alloc_error(e); } - ); - } -}; - - -/** - * Locate the root-directory record in the primary volume descriptor - */ -static Directory_record *locate_root(Genode::Allocator &alloc, - Block::Connection<> &block) -{ - /* volume descriptors in ISO9660 start at block 16 */ - for (unsigned long blk_nr = 16;; blk_nr++) { - Iso::Sector sec(block, blk_nr, 1); - Volume_descriptor *vol = sec.addr(); - - if (vol->primary()) - return vol->copy_root_record(alloc); - - if (vol->terminator()) - return nullptr; - } -} - - -/** - * Return root directory record - */ -static Directory_record *root_dir(Genode::Allocator &alloc, - Block::Connection<> &block) -{ - Directory_record *root = locate_root(alloc, block); - - if (!root) { throw Iso::Non_data_disc(); } - - return root; -} - - -/******************* - ** Iso interface ** - *******************/ - -static Directory_record *_root_dir; - - -Iso::File_info *Iso::file_info(Genode::Allocator &alloc, - Block::Connection<> &block, char const *path) -{ - char level[PATH_LENGTH]; - - struct Scanner_policy_file - { - static bool identifier_char(char c, unsigned /* i */) - { - return c != '/' && c != 0; - } - }; - typedef ::Genode::Token Token; - - Token t(path); - - if (!_root_dir) { - _root_dir = root_dir(alloc, block); - } - - Directory_record *dir = _root_dir; - uint32_t blk_nr = 0, data_length = 0; - - /* determine block nr and file length on disk, parse directory records */ - while (t) { - - if (t.type() != Token::IDENT) { - t = t.next(); - continue; - } - - t.string(level, PATH_LENGTH); - - /* - * Save current block number in a variable because successive - * iterations might override the memory location where dir points - * to when a directory entry spans several sectors. - */ - uint32_t current_blk_nr = dir->blk_nr(); - - /* load extent of directory record and search for level */ - for (unsigned long i = 0; i < Sector::to_blk(dir->data_length()); i++) { - Sector sec(block, current_blk_nr + i, 1); - Directory_record *tmp = sec.addr()->locate(level); - - if (!tmp && i == Sector::to_blk(dir->data_length()) - 1) { - Genode::error("file not found: ", Genode::Cstring(path)); - throw File_not_found(); - } - - if (!tmp) continue; - - dir = tmp; - current_blk_nr = dir->blk_nr(); - - if (!dir->directory()) { - blk_nr = current_blk_nr; - data_length = dir->data_length(); - } - - break; - } - - t = t.next(); - } - - /* Warning: Don't access 'dir' after this point, since the sector is gone */ - - if (!blk_nr && !data_length) { - Genode::error("file not found: ", Genode::Cstring(path)); - throw File_not_found(); - } - - return new (alloc) File_info(blk_nr, data_length); -} - - -unsigned long Iso::read_file(Block::Connection<> &block, File_info *info, - off_t file_offset, uint32_t length, void *buf_ptr) -{ - uint8_t *buf = (uint8_t *)buf_ptr; - if (info->size() <= (size_t)(length + file_offset)) - length = info->size() - file_offset - 1; - - unsigned long total_blk_count = ((length + (Sector::blk_size() - 1)) & - ~((Sector::blk_size()) - 1)) / Sector::blk_size(); - unsigned long ret = total_blk_count; - unsigned long blk_count; - unsigned long blk_nr = info->blk_nr() + (file_offset / Sector::blk_size()); - - while ((blk_count = min(Sector::MAX_SECTORS, total_blk_count))) { - Sector sec(block, blk_nr, blk_count); - - total_blk_count -= blk_count; - blk_nr += blk_count; - - unsigned long copy_length = blk_count * Sector::blk_size(); - memcpy(buf, sec.addr(), copy_length); - - length -= copy_length; - buf += copy_length; - - /* zero out rest of page */ - if (!total_blk_count && (blk_count % 2)) - memset(buf, 0, Sector::blk_size()); - } - - return ret * Sector::blk_size(); -} diff --git a/repos/os/src/server/iso9660/iso9660.h b/repos/os/src/server/iso9660/iso9660.h deleted file mode 100644 index a937b69a44..0000000000 --- a/repos/os/src/server/iso9660/iso9660.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * \brief ISO interface to session server - * \author Sebastian Sumpf - * \date 2010-07-26 - */ - -/* - * Copyright (C) 2010-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -/* Genode includes */ -#include -#include - -namespace Iso { - - /* - * Exceptions - */ - class Io_error : public Genode::Exception { }; - class Non_data_disc : public Genode::Exception { }; - class File_not_found : public Genode::Exception { }; - - /* enable/disable debugging output */ - const int verbose = 0; - - enum { - PATH_LENGTH = 128, /* max. length of a path */ - LEVEL_LENGTH = 32, /* max. length of a level of a path */ - PAGE_SIZE = 4096, - }; - - - class File_info - { - private: - - Genode::uint32_t _blk_nr; - Genode::size_t _size; - - public: - - File_info(Genode::uint32_t blk_nr, Genode::size_t size) - : _blk_nr(blk_nr), _size(size) {} - - Genode::uint32_t blk_nr() { return _blk_nr; } - Genode::size_t size() { return _size; } - Genode::size_t page_sized() { return (_size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); } - }; - - - /******************* - ** Iso interface ** - *******************/ - - /** - * Retrieve file information - * - * \param alloc allocator used for File_info object - * \param block Block session used to read sectors from ISO - * \param path absolute path of the file (slash separated) - * - * \throw File_not_found - * \throw Io_error - * \throw Non_data_disc - * - * \return Pointer to File_info class - */ - File_info *file_info(Genode::Allocator &alloc, Block::Connection<> &block, char const *path); - - /** - * Read data from ISO - * - * \param block Block session used to read sectors from ISO - * \param info File Info of file to read the data from - * \param file_offset Offset in file - * \param length Number of bytes to read - * \param buf Output buffer - * - * \throw Io_error - * - * \return Number of bytes read - */ - unsigned long read_file(Block::Connection<> &block, File_info *info, Genode::off_t file_offset, - Genode::uint32_t length, void *buf); -} /* namespace Iso */ diff --git a/repos/os/src/server/iso9660/main.cc b/repos/os/src/server/iso9660/main.cc deleted file mode 100644 index fa41152716..0000000000 --- a/repos/os/src/server/iso9660/main.cc +++ /dev/null @@ -1,197 +0,0 @@ -/* - * \brief Rom-session server for ISO file systems - * \author Sebastian Sumpf - * \date 2010-07-26 - */ - -/* - * Copyright (C) 2010-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -/* Genode includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* local includes */ -#include "iso9660.h" - -using namespace Genode; - - -/***************** - ** ROM service ** - *****************/ - -namespace Iso { - - typedef Avl_string File_base; - typedef Avl_tree File_cache; - - class File; - class Rom_component; - - typedef Genode::Root_component Root_component; - - - class Root; -} - - -/** - * File abstraction - */ -class Iso::File : public File_base -{ - private: - - /* - * Noncopyable - */ - File(File const &); - File &operator = (File const &); - - Genode::Allocator &_alloc; - - File_info *_info; - Attached_ram_dataspace _ds; - - public: - - File(Genode::Env &env, Genode::Allocator &alloc, - Block::Connection<> &block, char const *path) - : - File_base(path), _alloc(alloc), - _info(Iso::file_info(_alloc, block, path)), - _ds(env.ram(), env.rm(), align_addr(_info->page_sized(), 12)) - { - Iso::read_file(block, _info, 0, _ds.size(), _ds.local_addr()); - } - - ~File() { destroy(_alloc, _info); } - - Dataspace_capability dataspace() { return _ds.cap(); } -}; - - -class Iso::Rom_component : public Genode::Rpc_object -{ - private: - - /* - * Noncopyable - */ - Rom_component(Rom_component const &); - Rom_component &operator = (Rom_component const &); - - File *_file = nullptr; - - File *_lookup(File_cache &cache, char const *path) - { - return static_cast(cache.first() ? - cache.first()->find_by_name(path) : - 0); - } - - public: - - Rom_dataspace_capability dataspace() override { - return static_cap_cast(_file->dataspace()); } - - void sigh(Signal_context_capability) override { } - - Rom_component(Genode::Env &env, Genode::Allocator &alloc, - File_cache &cache, Block::Connection<> &block, - char const *path) - { - if ((_file = _lookup(cache, path))) { - Genode::log("cache hit for file ", Genode::Cstring(path)); - return; - } - - _file = new (alloc) File(env, alloc, block, path); - Genode::log("request for file ", Genode::Cstring(path)); - - cache.insert(_file); - } -}; - - -class Iso::Root : public Iso::Root_component -{ - private: - - Genode::Env &_env; - Genode::Allocator &_alloc; - - Allocator_avl _block_alloc { &_alloc }; - Block::Connection<> _block { _env, &_block_alloc }; - - /* - * Entries in the cache are never freed, even if the ROM session - * gets destroyed. - */ - File_cache _cache { }; - - char _path[PATH_LENGTH]; - - protected: - - Rom_component *_create_session(const char *args) override - { - size_t ram_quota = - Arg_string::find_arg(args, "ram_quota").ulong_value(0); - size_t session_size = sizeof(Rom_component) + sizeof(File_info); - if (ram_quota < session_size) - throw Insufficient_ram_quota(); - - Session_label const label = label_from_args(args); - copy_cstring(_path, label.last_element().string(), sizeof(_path)); - - if (verbose) - Genode::log("Request for file ", Cstring(_path), " len ", strlen(_path)); - - try { - return new (_alloc) Rom_component(_env, _alloc, _cache, _block, _path); - } - catch (Io_error) { throw Service_denied(); } - catch (Non_data_disc) { throw Service_denied(); } - catch (File_not_found) { throw Service_denied(); } - } - - public: - - Root(Genode::Env &env, Allocator &alloc) - : - Root_component(&env.ep().rpc_ep(), &alloc), - _env(env), _alloc(alloc) - { } -}; - - -struct Main -{ - Genode::Env &_env; - Genode::Heap _heap { _env.ram(), _env.rm() }; - - Iso::Root _root { _env, _heap }; - - Main(Genode::Env &env) : _env(env) - { - _env.parent().announce(_env.ep().manage(_root)); - } -}; - - -void Component::construct(Genode::Env &env) { static Main main(env); } diff --git a/repos/os/src/server/iso9660/target.mk b/repos/os/src/server/iso9660/target.mk deleted file mode 100644 index 3d6d3a7950..0000000000 --- a/repos/os/src/server/iso9660/target.mk +++ /dev/null @@ -1,5 +0,0 @@ -TARGET = iso9660 -SRC_CC = main.cc iso9660.cc -LIBS = base - -CC_CXX_WARN_STRICT_CONVERSION =