mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-22 03:55:26 +00:00
File_system session: broaden error handling
Throw Invalid_name, No_space, and Out_of_node_handles where appropriate. Catch the new range of errors thrown by at the VFS. Catch Out_of_node_handles at the VFS, but print a message and re-throw. Issue #1648
This commit is contained in:
parent
1d4bd10701
commit
1c6164a0c5
@ -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),
|
||||
|
@ -17,7 +17,6 @@
|
||||
/* Genode includes */
|
||||
#include <base/allocator_avl.h>
|
||||
#include <file_system_session/connection.h>
|
||||
#include <util/string.h>
|
||||
|
||||
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<Genode::Ram_dataspace>(ds_cap));
|
||||
if (ds_cap.valid())
|
||||
env()->ram_session()->free(static_cap_cast<Genode::Ram_dataspace>(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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user