diff --git a/repos/libports/src/lib/libc/vfs_plugin.cc b/repos/libports/src/lib/libc/vfs_plugin.cc index c40cc09a96..483f92f129 100644 --- a/repos/libports/src/lib/libc/vfs_plugin.cc +++ b/repos/libports/src/lib/libc/vfs_plugin.cc @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2014 Genode Labs GmbH + * Copyright (C) 2014-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -328,7 +328,8 @@ Libc::File_descriptor *Libc::Vfs_plugin::open(char const *path, int flags, int Libc::Vfs_plugin::close(Libc::File_descriptor *fd) { - Genode::destroy(Genode::env()->heap(), vfs_handle(fd)); + Vfs::Vfs_handle *handle = vfs_handle(fd); + handle->ds().close(handle); Libc::file_descriptor_allocator()->free(fd); return 0; } diff --git a/repos/os/include/vfs/dir_file_system.h b/repos/os/include/vfs/dir_file_system.h index d6de58e539..f204d11426 100644 --- a/repos/os/include/vfs/dir_file_system.h +++ b/repos/os/include/vfs/dir_file_system.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011-2014 Genode Labs GmbH + * Copyright (C) 2011-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -397,7 +397,10 @@ class Vfs::Dir_file_system : public File_system return 0; } - Open_result open(char const *path, unsigned mode, Vfs_handle **out_handle) override + Open_result open(char const *path, + unsigned mode, + Vfs_handle **out_handle, + Allocator &alloc = *Genode::env()->heap()) override { /* * If 'path' is a directory, we create a 'Vfs_handle' @@ -405,7 +408,7 @@ class Vfs::Dir_file_system : public File_system * are subjected to the stacked file-system layout. */ if (is_directory(path)) { - *out_handle = new (env()->heap()) Vfs_handle(*this, *this, 0); + *out_handle = new (alloc) Vfs_handle(*this, *this, alloc, 0); return OPEN_OK; } @@ -423,23 +426,32 @@ class Vfs::Dir_file_system : public File_system /* path equals directory name */ if (strlen(path) == 0) { - *out_handle = new (env()->heap()) Vfs_handle(*this, *this, 0); + *out_handle = new (alloc) Vfs_handle(*this, *this, alloc, 0); return OPEN_OK; } /* path refers to any of our sub file systems */ for (File_system *fs = _first_file_system; fs; fs = fs->next) { - Open_result const err = fs->open(path, mode, out_handle); - - if (err == OPEN_OK) + Open_result const err = fs->open(path, mode, out_handle, alloc); + switch (err) { + case OPEN_ERR_UNACCESSIBLE: + continue; + default: return err; + } } /* path does not match any existing file or directory */ return OPEN_ERR_UNACCESSIBLE; } + void close(Vfs_handle *handle) override + { + if (handle && (&handle->ds() == this)) + destroy(handle->alloc(), handle); + } + Unlink_result unlink(char const *path) override { auto unlink_fn = [] (File_system &fs, char const *path) diff --git a/repos/os/include/vfs/directory_service.h b/repos/os/include/vfs/directory_service.h index 90e30a572f..5bf21f6f28 100644 --- a/repos/os/include/vfs/directory_service.h +++ b/repos/os/include/vfs/directory_service.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011-2014 Genode Labs GmbH + * Copyright (C) 2011-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -19,6 +19,8 @@ namespace Vfs { class Vfs_handle; struct Directory_service; + + using Genode::Allocator; } @@ -56,7 +58,15 @@ struct Vfs::Directory_service OPEN_OK }; - virtual Open_result open(char const *path, unsigned mode, Vfs_handle **) = 0; + virtual Open_result open(char const *path, + unsigned mode, + Vfs_handle **handle, + Allocator &alloc = *Genode::env()->heap()) = 0; + + /** + * Close handle resources and deallocate handle + */ + virtual void close(Vfs_handle *handle) = 0; /********** diff --git a/repos/os/include/vfs/fs_file_system.h b/repos/os/include/vfs/fs_file_system.h index b51c5d2d13..ef8a55aeef 100644 --- a/repos/os/include/vfs/fs_file_system.h +++ b/repos/os/include/vfs/fs_file_system.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2012-2014 Genode Labs GmbH + * Copyright (C) 2012-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -54,17 +54,11 @@ class Vfs::Fs_file_system : public File_system public: - Fs_vfs_handle(File_system &fs, int status_flags, - ::File_system::File_handle handle) - : Vfs_handle(fs, fs, status_flags), _handle(handle) + Fs_vfs_handle(File_system &fs, Allocator &alloc, + int status_flags, ::File_system::File_handle handle) + : Vfs_handle(fs, fs, alloc, status_flags), _handle(handle) { } - ~Fs_vfs_handle() - { - Fs_file_system &fs = static_cast(ds()); - fs._fs.close(_handle); - } - ::File_system::File_handle file_handle() const { return _handle; } }; @@ -521,7 +515,7 @@ class Vfs::Fs_file_system : public File_system return path; } - Open_result open(char const *path, unsigned vfs_mode, Vfs_handle **out_handle) override + Open_result open(char const *path, unsigned vfs_mode, Vfs_handle **out_handle, Genode::Allocator& alloc) override { Lock::Guard guard(_lock); @@ -554,7 +548,7 @@ class Vfs::Fs_file_system : public File_system ::File_system::File_handle file = _fs.file(dir, file_name.base() + 1, mode, create); - *out_handle = new (env()->heap()) Fs_vfs_handle(*this, vfs_mode, file); + *out_handle = new (alloc) Fs_vfs_handle(*this, alloc, vfs_mode, file); } catch (::File_system::Permission_denied) { return OPEN_ERR_NO_PERM; } catch (::File_system::Invalid_handle) { return OPEN_ERR_NO_PERM; } @@ -567,6 +561,18 @@ class Vfs::Fs_file_system : public File_system return OPEN_OK; } + void close(Vfs_handle *vfs_handle) override + { + Lock::Guard guard(_lock); + + Fs_vfs_handle *handle = static_cast(vfs_handle); + + if (handle) { + _fs.close(handle->file_handle()); + destroy(handle->alloc(), handle); + } + } + /*************************** ** File_system interface ** diff --git a/repos/os/include/vfs/ram_file_system.h b/repos/os/include/vfs/ram_file_system.h index c22c5ec14f..8ee1dd4c7e 100644 --- a/repos/os/include/vfs/ram_file_system.h +++ b/repos/os/include/vfs/ram_file_system.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2015 Genode Labs GmbH + * Copyright (C) 2015-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -323,23 +323,20 @@ class Vfs::Ram_file_system : public Vfs::File_system { private: - class Ram_vfs_handle : public Vfs_handle + struct Ram_vfs_handle : Vfs_handle { - private: + Vfs_ram::File &file; - Vfs_ram::File *_file; - - public: - - Ram_vfs_handle(File_system &fs, int status_flags, Vfs_ram::File *file) - : Vfs_handle(fs, fs, status_flags), _file(file) - { } - - Vfs_ram::File *file() const { return _file; } + Ram_vfs_handle(Ram_file_system &fs, + Allocator &alloc, + int status_flags, + Vfs_ram::File &node) + : Vfs_handle(fs, fs, alloc, status_flags), file(node) + { } }; Genode::Allocator &_alloc; - Vfs_ram::Directory _root; + Vfs_ram::Directory _root = { "" }; Vfs_ram::Node *lookup(char const *path, bool return_parent = false) { @@ -388,7 +385,7 @@ class Vfs::Ram_file_system : public Vfs::File_system public: Ram_file_system(Xml_node config) - : _alloc(*env()->heap()), _root("") { } + : _alloc(*env()->heap()) { } /********************************* ** Directory service interface ** @@ -437,7 +434,7 @@ class Vfs::Ram_file_system : public Vfs::File_system return MKDIR_OK; } - Open_result open(char const *path, unsigned mode, Vfs_handle **handle) override + Open_result open(char const *path, unsigned mode, Vfs_handle **handle, Genode::Allocator &alloc) override { using namespace Vfs_ram; @@ -464,11 +461,21 @@ class Vfs::Ram_file_system : public Vfs::File_system if (!file) return OPEN_ERR_UNACCESSIBLE; } - /* allocate handle on the heap */ - *handle = new (env()->heap()) Ram_vfs_handle(*this, mode, file); + *handle = new (alloc) Ram_vfs_handle(*this, alloc, mode, *file); return OPEN_OK; } + void close(Vfs_handle *vfs_handle) override + { + Ram_vfs_handle *ram_handle = + static_cast(vfs_handle); + + if (ram_handle) { + destroy(_alloc, &ram_handle->file); + destroy(vfs_handle->alloc(), ram_handle); + } + } + Stat_result stat(char const *path, Stat &stat) override { using namespace Vfs_ram; @@ -686,8 +693,8 @@ class Vfs::Ram_file_system : public Vfs::File_system Ram_vfs_handle const *handle = static_cast(vfs_handle); - Vfs_ram::Node::Guard guard(handle->file()); - out = handle->file()->write(buf, len, handle->seek()); + Vfs_ram::Node::Guard guard(&handle->file); + out = handle->file.write(buf, len, handle->seek()); return WRITE_OK; } @@ -702,9 +709,9 @@ class Vfs::Ram_file_system : public Vfs::File_system Ram_vfs_handle const *handle = static_cast(vfs_handle); - Vfs_ram::Node::Guard guard(handle->file()); + Vfs_ram::Node::Guard guard(&handle->file); - out = handle->file()->read(buf, len, handle->seek()); + out = handle->file.read(buf, len, handle->seek()); return READ_OK; } @@ -716,8 +723,8 @@ class Vfs::Ram_file_system : public Vfs::File_system Ram_vfs_handle const *handle = static_cast(vfs_handle); - Vfs_ram::Node::Guard guard(handle->file()); - handle->file()->truncate(len); + Vfs_ram::Node::Guard guard(&handle->file); + handle->file.truncate(len); return FTRUNCATE_OK; } diff --git a/repos/os/include/vfs/rom_file_system.h b/repos/os/include/vfs/rom_file_system.h index daa0adee0a..d06f3793fd 100644 --- a/repos/os/include/vfs/rom_file_system.h +++ b/repos/os/include/vfs/rom_file_system.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2014 Genode Labs GmbH + * Copyright (C) 2014-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -71,11 +71,12 @@ class Vfs::Rom_file_system : public Single_file_system * Overwrite the default open function to update the ROM dataspace * each time when opening the corresponding file. */ - Open_result open(char const *path, unsigned, - Vfs_handle **out_handle) override + Open_result open(char const *path, unsigned, + Vfs_handle **out_handle, + Allocator &alloc) override { Open_result const result = - Single_file_system::open(path, 0, out_handle); + Single_file_system::open(path, 0, out_handle, alloc); _rom.update(); diff --git a/repos/os/include/vfs/single_file_system.h b/repos/os/include/vfs/single_file_system.h index b2f5178bbb..4b7424c301 100644 --- a/repos/os/include/vfs/single_file_system.h +++ b/repos/os/include/vfs/single_file_system.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2014 Genode Labs GmbH + * Copyright (C) 2014-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -127,16 +127,23 @@ class Vfs::Single_file_system : public File_system return _is_single_file(path) ? path : 0; } - Open_result open(char const *path, unsigned, - Vfs_handle **out_handle) override + Open_result open(char const *path, unsigned, + Vfs_handle **out_handle, + Allocator &alloc) override { if (!_is_single_file(path)) return OPEN_ERR_UNACCESSIBLE; - *out_handle = new (env()->heap()) Vfs_handle(*this, *this, 0); + *out_handle = new (alloc) Vfs_handle(*this, *this, alloc, 0); return OPEN_OK; } + void close(Vfs_handle *handle) override + { + if (handle && (&handle->ds() == this)) + destroy(handle->alloc(), handle); + } + Unlink_result unlink(char const *) override { return UNLINK_ERR_NO_PERM; diff --git a/repos/os/include/vfs/symlink_file_system.h b/repos/os/include/vfs/symlink_file_system.h index 82e248c724..1e3c42fb9c 100644 --- a/repos/os/include/vfs/symlink_file_system.h +++ b/repos/os/include/vfs/symlink_file_system.h @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2015 Genode Labs GmbH + * Copyright (C) 2015-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -131,10 +131,12 @@ class Vfs::Symlink_file_system : public File_system void release(char const *path, Dataspace_capability ds_cap) override { } - Open_result open(char const *path, unsigned, - Vfs_handle **out_handle) override { + Open_result open(char const *, unsigned, Vfs_handle **out_handle, + Allocator&) override { return OPEN_ERR_UNACCESSIBLE; } + void close(Vfs_handle *) override { } + Unlink_result unlink(char const *) override { return UNLINK_ERR_NO_PERM; } @@ -171,4 +173,4 @@ class Vfs::Symlink_file_system : public File_system }; -#endif /* _INCLUDE__VFS__SYMLINK_FILE_SYSTEM_H_ */ \ No newline at end of file +#endif /* _INCLUDE__VFS__SYMLINK_FILE_SYSTEM_H_ */ diff --git a/repos/os/include/vfs/tar_file_system.h b/repos/os/include/vfs/tar_file_system.h index fa37287a2e..7b2f93c709 100644 --- a/repos/os/include/vfs/tar_file_system.h +++ b/repos/os/include/vfs/tar_file_system.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011-2014 Genode Labs GmbH + * Copyright (C) 2011-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -102,8 +102,8 @@ class Vfs::Tar_file_system : public File_system public: - Tar_vfs_handle(File_system &fs, int status_flags, Record const *record) - : Vfs_handle(fs, fs, status_flags), _record(record) + Tar_vfs_handle(File_system &fs, Allocator &alloc, int status_flags, Record const *record) + : Vfs_handle(fs, fs, alloc, status_flags), _record(record) { } Record const *record() const { return _record; } @@ -573,18 +573,26 @@ class Vfs::Tar_file_system : public File_system return node ? path : 0; } - Open_result open(char const *path, unsigned, Vfs_handle **out_handle) override + Open_result open(char const *path, unsigned, Vfs_handle **out_handle, Genode::Allocator& alloc) override { Node const *node = dereference(path); if (!node || !node->record || node->record->type() != Record::TYPE_FILE) return OPEN_ERR_UNACCESSIBLE; - *out_handle = new (env()->heap()) - Tar_vfs_handle(*this, 0, node->record); + *out_handle = new (alloc) Tar_vfs_handle(*this, alloc, 0, node->record); return OPEN_OK; } + void close(Vfs_handle *vfs_handle) override + { + Tar_vfs_handle *tar_handle = + static_cast(vfs_handle); + + if (tar_handle) + destroy(vfs_handle->alloc(), tar_handle); + } + /*************************** ** File_system interface ** diff --git a/repos/os/include/vfs/vfs_handle.h b/repos/os/include/vfs/vfs_handle.h index 941cdee645..e893d6a904 100644 --- a/repos/os/include/vfs/vfs_handle.h +++ b/repos/os/include/vfs/vfs_handle.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011-2014 Genode Labs GmbH + * Copyright (C) 2011-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -26,8 +26,9 @@ class Vfs::Vfs_handle Directory_service &_ds; File_io_service &_fs; + Genode::Allocator &_alloc; int _status_flags; - file_size _seek; + file_size _seek = 0; public: @@ -40,21 +41,27 @@ class Vfs::Vfs_handle ~Guard() { if (handle) - Genode::destroy(Genode::env()->heap(), handle); + handle->_ds.close(handle); } }; enum { STATUS_RDONLY = 0, STATUS_WRONLY = 1, STATUS_RDWR = 2 }; - Vfs_handle(Directory_service &ds, File_io_service &fs, int status_flags) + Vfs_handle(Directory_service &ds, + File_io_service &fs, + Genode::Allocator &alloc, + int status_flags) : - _ds(ds), _fs(fs), _status_flags(status_flags), _seek(0) + _ds(ds), _fs(fs), + _alloc(alloc), + _status_flags(status_flags) { } virtual ~Vfs_handle() { } Directory_service &ds() { return _ds; } File_io_service &fs() { return _fs; } + Allocator &alloc() { return _alloc; } int status_flags() const { return _status_flags; } @@ -76,4 +83,5 @@ class Vfs::Vfs_handle void advance_seek(file_size incr) { _seek += incr; } }; + #endif /* _INCLUDE__VFS__VFS_HANDLE_H_ */ diff --git a/repos/ports/src/noux/vfs_io_channel.h b/repos/ports/src/noux/vfs_io_channel.h index efd5de7c6d..a96adb113d 100644 --- a/repos/ports/src/noux/vfs_io_channel.h +++ b/repos/ports/src/noux/vfs_io_channel.h @@ -41,7 +41,7 @@ namespace Noux { ~Vfs_io_channel() { _sig_rec.dissolve(this); - destroy(env()->heap(), _fh); + _fh->ds().close(_fh); } bool write(Sysio *sysio, size_t &offset) override