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 5ab4386470..1b79ea56bf 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 7e6adb56a9..6fb9eefe0d 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;
}