diff --git a/repos/libports/src/lib/libc/vfs_plugin.cc b/repos/libports/src/lib/libc/vfs_plugin.cc index 58f1301536..4c9a9a0e6c 100644 --- a/repos/libports/src/lib/libc/vfs_plugin.cc +++ b/repos/libports/src/lib/libc/vfs_plugin.cc @@ -299,7 +299,7 @@ int Libc::Vfs_plugin::close(Libc::File_descriptor *fd) { Vfs::Vfs_handle *handle = vfs_handle(fd); _vfs_sync(handle); - handle->ds().close(handle); + handle->close(); Libc::file_descriptor_allocator()->free(fd); return 0; } @@ -341,7 +341,7 @@ int Libc::Vfs_plugin::mkdir(const char *path, mode_t mode) switch (_root_dir.opendir(path, true, &dir_handle, _alloc)) { case Opendir_result::OPENDIR_OK: - dir_handle->ds().close(dir_handle); + dir_handle->close(); break; case Opendir_result::OPENDIR_ERR_LOOKUP_FAILED: return Errno(ENOENT); @@ -955,7 +955,7 @@ int Libc::Vfs_plugin::symlink(const char *oldpath, const char *newpath) } while (check.retry); _vfs_sync(handle); - handle->ds().close(handle); + handle->close(); if (out_count != count) return Errno(ENAMETOOLONG); @@ -1064,7 +1064,7 @@ ssize_t Libc::Vfs_plugin::readlink(const char *path, char *buf, ::size_t buf_siz case Result::READ_QUEUED: /* handled above, so never reached */ break; }; - symlink_handle->ds().close(symlink_handle); + symlink_handle->close(); return out_len; } diff --git a/repos/os/include/vfs/dir_file_system.h b/repos/os/include/vfs/dir_file_system.h index ff3e944a56..fd324d2b84 100644 --- a/repos/os/include/vfs/dir_file_system.h +++ b/repos/os/include/vfs/dir_file_system.h @@ -79,7 +79,7 @@ class Vfs::Dir_file_system : public File_system { /* close all sub-handles */ auto f = [&] (Subdir_handle_element &e) { - e.vfs_handle.ds().close(&e.vfs_handle); + e.vfs_handle.close(); destroy(alloc(), &e); }; subdir_handle_registry.for_each(f); @@ -118,7 +118,7 @@ class Vfs::Dir_file_system : public File_system { /* close all sub-handles */ auto f = [&] (Watch_handle_element &e) { - e.watch_handle.fs().close(&e.watch_handle); + e.watch_handle.close(); destroy(alloc(), &e); }; handle_registry.for_each(f); @@ -700,8 +700,9 @@ class Vfs::Dir_file_system : public File_system Vfs_handle *tmp_handle; Opendir_result opendir_result = fs.opendir(path, true, &tmp_handle, alloc); - if (opendir_result == OPENDIR_OK) - fs.close(tmp_handle); + if (opendir_result == OPENDIR_OK) { + tmp_handle->close(); + } return opendir_result; /* return from lambda */ }; diff --git a/repos/os/include/vfs/vfs_handle.h b/repos/os/include/vfs/vfs_handle.h index c1a5976f51..aa307e2da8 100644 --- a/repos/os/include/vfs/vfs_handle.h +++ b/repos/os/include/vfs/vfs_handle.h @@ -68,7 +68,7 @@ class Vfs::Vfs_handle ~Guard() { if (_handle) - _handle->_ds.close(_handle); + _handle->close(); } }; @@ -108,6 +108,13 @@ class Vfs::Vfs_handle * Advance seek offset by 'incr' bytes */ void advance_seek(file_size incr) { _seek += incr; } + + /** + * Close handle at backing file-system. + * + * This leaves the handle pointer in an invalid and unsafe state. + */ + inline void close() { ds().close(this); } }; @@ -122,7 +129,7 @@ class Vfs::Vfs_watch_handle private: - File_system &_fs; + Directory_service &_fs; Genode::Allocator &_alloc; Context *_context = nullptr; @@ -134,7 +141,7 @@ class Vfs::Vfs_watch_handle public: - Vfs_watch_handle(File_system &fs, + Vfs_watch_handle(Directory_service &fs, Genode::Allocator &alloc) : _fs(fs), _alloc(alloc) @@ -142,10 +149,17 @@ class Vfs::Vfs_watch_handle virtual ~Vfs_watch_handle() { } - File_system &fs() { return _fs; } + Directory_service &fs() { return _fs; } Allocator &alloc() { return _alloc; } virtual void context(Context *context) { _context = context; } Context *context() const { return _context; } + + /** + * Close handle at backing file-system. + * + * This leaves the handle pointer in an invalid and unsafe state. + */ + inline void close() { fs().close(this); } }; #endif /* _INCLUDE__VFS__VFS_HANDLE_H_ */ diff --git a/repos/os/src/server/vfs/node.h b/repos/os/src/server/vfs/node.h index b367492e29..2b499af113 100644 --- a/repos/os/src/server/vfs/node.h +++ b/repos/os/src/server/vfs/node.h @@ -335,7 +335,7 @@ class Vfs_server::Watch_node final : public Vfs_server::Node, ~Watch_node() { _watch_handle.context((Vfs::Vfs_watch_handle::Context*)~0ULL); - _watch_handle.fs().close(&_watch_handle); + _watch_handle.close(); } static Watch_node &node_by_context(Vfs::Vfs_watch_handle::Context &context) @@ -368,6 +368,7 @@ struct Vfs_server::Symlink : Io_node _handle->context = &context(); } + ~Symlink() { _handle->close(); } /******************** ** Node interface ** @@ -444,7 +445,7 @@ class Vfs_server::File : public Io_node _handle->context = &context(); } - ~File() { _handle->ds().close(_handle); } + ~File() { _handle->close(); } size_t read(char *dst, size_t len, seek_off_t seek_offset) override { @@ -497,7 +498,7 @@ struct Vfs_server::Directory : Io_node _handle->context = &context(); } - ~Directory() { _handle->ds().close(_handle); } + ~Directory() { _handle->close(); } Node_space::Id file(Node_space &space, Vfs::File_system &vfs, diff --git a/repos/os/src/test/vfs_stress/main.cc b/repos/os/src/test/vfs_stress/main.cc index 363fba634d..fe2b0e66b6 100644 --- a/repos/os/src/test/vfs_stress/main.cc +++ b/repos/os/src/test/vfs_stress/main.cc @@ -171,7 +171,7 @@ struct Mkdir_test : public Stress_test path.append("/b"); Vfs::Vfs_handle *dir_handle; assert_opendir(vfs.opendir(path.base(), true, &dir_handle, alloc)); - vfs.close(dir_handle); + dir_handle->close(); ++count; mkdir_b(depth); } @@ -186,7 +186,7 @@ struct Mkdir_test : public Stress_test path.append("/b"); assert_opendir(vfs.opendir(path.base(), true, &dir_handle, alloc)); - vfs.close(dir_handle); + dir_handle->close(); ++count; mkdir_b(depth); @@ -194,7 +194,7 @@ struct Mkdir_test : public Stress_test path.append("/a"); assert_opendir(vfs.opendir(path.base(), true, &dir_handle, alloc)); - vfs.close(dir_handle); + dir_handle->close(); ++count; mkdir_a(depth); } @@ -474,7 +474,7 @@ struct Unlink_test : public Stress_test } } - vfs.close(dir_handle); + dir_handle->close(); } Unlink_test(Vfs::File_system &vfs, Genode::Allocator &alloc, @@ -561,7 +561,7 @@ void Component::construct(Genode::Env &env) snprintf(path, 3, "/%d", i); Vfs::Vfs_handle *dir_handle; vfs_root.opendir(path, true, &dir_handle, heap); - vfs_root.close(dir_handle); + dir_handle->close(); Mkdir_test test(vfs_root, heap, path); count += test.wait(); }