diff --git a/repos/os/include/file_system_session/file_system_session.h b/repos/os/include/file_system_session/file_system_session.h index 5ab438647..1b79ea56b 100644 --- a/repos/os/include/file_system_session/file_system_session.h +++ b/repos/os/include/file_system_session/file_system_session.h @@ -217,11 +217,18 @@ struct File_system::Session : public Genode::Session * \throw Invalid_name file name contains invalid characters * \throw Lookup_failed the name refers to a node other than a * file + * \throw Out_of_node_handles server cannot allocate metadata + * \throw No_space */ virtual File_handle file(Dir_handle, Name const &name, Mode, bool create) = 0; /** * Open or create symlink + * + * \throw Invalid_handle directory handle is invalid + * \throw Invalid_name file name contains invalid characters + * \throw Out_of_node_handles server cannot allocate metadata + * \throw No_space */ virtual Symlink_handle symlink(Dir_handle, Name const &name, bool create) = 0; @@ -234,6 +241,7 @@ struct File_system::Session : public Genode::Session * \throw Lookup_failed path lookup failed because one element * of 'path' does not exist * \throw Name_too_long + * \throw Out_of_node_handles server cannot allocate metadata * \throw No_space */ virtual Dir_handle dir(Path const &path, bool create) = 0; @@ -243,6 +251,10 @@ struct File_system::Session : public Genode::Session * * The returned node handle can be used merely as argument for * 'status'. + * + * \throw Lookup_failed path lookup failed because one element + * of 'path' does not exist + * \throw Out_of_node_handles server cannot allocate metadata */ virtual Node_handle node(Path const &path) = 0; @@ -268,6 +280,10 @@ struct File_system::Session : public Genode::Session /** * Truncate or grow file to specified size + * + * \throw Permission_denied node modification not allowed + * \throw Invalid_handle node handle is invalid + * \throw No_space new size exceeds free space */ virtual void truncate(File_handle, file_size_t size) = 0; @@ -286,8 +302,7 @@ struct File_system::Session : public Genode::Session * Synchronize file system * * This is only needed by file systems that maintain an internal - * cache, which needs to be flushed on certain occasions. Therefore, - * the default implementation just serves as a reminder. + * cache, which needs to be flushed on certain occasions. */ virtual void sync(Node_handle) { } @@ -300,18 +315,22 @@ struct File_system::Session : public Genode::Session GENODE_RPC_THROW(Rpc_file, File_handle, file, GENODE_TYPE_LIST(Invalid_handle, Node_already_exists, Invalid_name, Lookup_failed, - Permission_denied), + Permission_denied, No_space, + Out_of_node_handles), Dir_handle, Name const &, Mode, bool); GENODE_RPC_THROW(Rpc_symlink, Symlink_handle, symlink, GENODE_TYPE_LIST(Invalid_handle, Node_already_exists, - Invalid_name, Lookup_failed, Permission_denied), + Invalid_name, Lookup_failed, + Permission_denied, No_space, + Out_of_node_handles), Dir_handle, Name const &, bool); GENODE_RPC_THROW(Rpc_dir, Dir_handle, dir, GENODE_TYPE_LIST(Permission_denied, Node_already_exists, - Lookup_failed, Name_too_long, No_space), + Lookup_failed, Name_too_long, + No_space, Out_of_node_handles), Path const &, bool); GENODE_RPC_THROW(Rpc_node, Node_handle, node, - GENODE_TYPE_LIST(Lookup_failed), + GENODE_TYPE_LIST(Lookup_failed, Out_of_node_handles), Path const &); GENODE_RPC(Rpc_close, void, close, Node_handle); GENODE_RPC(Rpc_status, Status, status, Node_handle); @@ -320,7 +339,7 @@ struct File_system::Session : public Genode::Session GENODE_TYPE_LIST(Permission_denied, Invalid_name, Lookup_failed), Dir_handle, Name const &); GENODE_RPC_THROW(Rpc_truncate, void, truncate, - GENODE_TYPE_LIST(Permission_denied, Invalid_handle), + GENODE_TYPE_LIST(Permission_denied, Invalid_handle, No_space), File_handle, file_size_t); GENODE_RPC_THROW(Rpc_move, void, move, GENODE_TYPE_LIST(Permission_denied, Invalid_name, Lookup_failed), diff --git a/repos/os/include/vfs/fs_file_system.h b/repos/os/include/vfs/fs_file_system.h index 7e6adb56a..6fb9eefe0 100644 --- a/repos/os/include/vfs/fs_file_system.h +++ b/repos/os/include/vfs/fs_file_system.h @@ -17,7 +17,6 @@ /* Genode includes */ #include #include -#include namespace Vfs { class Fs_file_system; } @@ -241,7 +240,8 @@ class Vfs::Fs_file_system : public File_system void release(char const *path, Dataspace_capability ds_cap) override { - env()->ram_session()->free(static_cap_cast(ds_cap)); + if (ds_cap.valid()) + env()->ram_session()->free(static_cap_cast(ds_cap)); } Stat_result stat(char const *path, Stat &out) override @@ -347,9 +347,8 @@ class Vfs::Fs_file_system : public File_system _fs.unlink(dir, file_name.base() + 1); } - catch (...) { - return UNLINK_ERR_NO_ENTRY; - } + catch (::File_system::Permission_denied) { return UNLINK_ERR_NO_PERM; } + catch (...) { return UNLINK_ERR_NO_ENTRY; } return UNLINK_OK; } @@ -399,15 +398,14 @@ class Vfs::Fs_file_system : public File_system try { ::File_system::Dir_handle from_dir = _fs.dir(from_dir_path.base(), false); Fs_handle_guard from_dir_guard(_fs, from_dir); - ::File_system::Dir_handle to_dir = _fs.dir(to_dir_path.base(), false); Fs_handle_guard to_dir_guard(_fs, to_dir); _fs.move(from_dir, from_file_name.base() + 1, to_dir, to_file_name.base() + 1); - - } catch (...) { - return RENAME_ERR_NO_ENTRY; } + } + catch (::File_system::Lookup_failed) { return RENAME_ERR_NO_ENTRY; } + catch (...) { return RENAME_ERR_NO_PERM; } return RENAME_OK; } @@ -421,15 +419,15 @@ class Vfs::Fs_file_system : public File_system try { _fs.close(_fs.dir(abs_path.base(), true)); - return MKDIR_OK; } catch (::File_system::Permission_denied) { return MKDIR_ERR_NO_PERM; } catch (::File_system::Node_already_exists) { return MKDIR_ERR_EXISTS; } catch (::File_system::Lookup_failed) { return MKDIR_ERR_NO_ENTRY; } catch (::File_system::Name_too_long) { return MKDIR_ERR_NAME_TOO_LONG; } catch (::File_system::No_space) { return MKDIR_ERR_NO_SPACE; } + catch (::File_system::Out_of_node_handles) { return MKDIR_ERR_NO_ENTRY; } - return MKDIR_ERR_NO_PERM; + return MKDIR_OK; } Symlink_result symlink(char const *from, char const *to) override @@ -458,15 +456,16 @@ class Vfs::Fs_file_system : public File_system Fs_handle_guard symlink_guard(_fs, symlink_handle); _write(symlink_handle, from, strlen(from) + 1, 0); - return SYMLINK_OK; } catch (::File_system::Invalid_handle) { return SYMLINK_ERR_NO_ENTRY; } - catch (::File_system::Node_already_exists) { return SYMLINK_ERR_EXISTS; } + catch (::File_system::Node_already_exists) { return SYMLINK_ERR_EXISTS; } catch (::File_system::Invalid_name) { return SYMLINK_ERR_NAME_TOO_LONG; } catch (::File_system::Lookup_failed) { return SYMLINK_ERR_NO_ENTRY; } - catch (::File_system::Permission_denied) { return SYMLINK_ERR_NO_PERM; } + catch (::File_system::Permission_denied) { return SYMLINK_ERR_NO_PERM; } + catch (::File_system::No_space) { return SYMLINK_ERR_NO_SPACE; } + catch (::File_system::Out_of_node_handles) { return SYMLINK_ERR_NO_ENTRY; } - return SYMLINK_ERR_NO_ENTRY; + return SYMLINK_OK; } file_size num_dirent(char const *path) override @@ -507,8 +506,7 @@ class Vfs::Fs_file_system : public File_system ::File_system::Node_handle node = _fs.node(path); _fs.close(node); } - catch (...) { - return 0; } + catch (...) { return 0; } return path; } @@ -546,14 +544,16 @@ class Vfs::Fs_file_system : public File_system mode, create); *out_handle = new (env()->heap()) Fs_vfs_handle(*this, vfs_mode, file); - return OPEN_OK; } catch (::File_system::Permission_denied) { return OPEN_ERR_NO_PERM; } catch (::File_system::Invalid_handle) { return OPEN_ERR_NO_PERM; } catch (::File_system::Lookup_failed) { return OPEN_ERR_UNACCESSIBLE; } - catch (::File_system::Node_already_exists) { return OPEN_ERR_EXISTS; } + catch (::File_system::Node_already_exists) { return OPEN_ERR_EXISTS; } + catch (::File_system::Invalid_name) { return OPEN_ERR_NAME_TOO_LONG; } + catch (::File_system::No_space) { return OPEN_ERR_NO_SPACE; } + catch (::File_system::Out_of_node_handles) { return OPEN_ERR_UNACCESSIBLE; } - return OPEN_ERR_UNACCESSIBLE; + return OPEN_OK; } @@ -615,9 +615,10 @@ class Vfs::Fs_file_system : public File_system try { _fs.truncate(handle->file_handle(), len); - } + } catch (::File_system::Invalid_handle) { return FTRUNCATE_ERR_NO_PERM; } catch (::File_system::Permission_denied) { return FTRUNCATE_ERR_NO_PERM; } + catch (::File_system::No_space) { return FTRUNCATE_ERR_NO_SPACE; } return FTRUNCATE_OK; }