mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 03:45:24 +00:00
VFS: catch Out_of_ram and Out_of_cap exceptions
Catch out of RAM and capability exceptions and return error values. Abort opening a composite directory at Dir_file_system where an opendir call on any child file-system returns an OUT_OF_RAM or OUT_OF_CAPS error. Ref #2642
This commit is contained in:
parent
c34a4bfdb4
commit
c7d0accac0
@ -540,8 +540,12 @@ class Vfs::Dir_file_system : public File_system
|
||||
* are subjected to the stacked file-system layout.
|
||||
*/
|
||||
if (directory(path)) {
|
||||
*out_handle = new (alloc) Vfs_handle(*this, *this, alloc, 0);
|
||||
return OPEN_OK;
|
||||
try {
|
||||
*out_handle = new (alloc) Vfs_handle(*this, *this, alloc, 0);
|
||||
return OPEN_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
/*
|
||||
@ -558,8 +562,12 @@ class Vfs::Dir_file_system : public File_system
|
||||
|
||||
/* path equals directory name */
|
||||
if (strlen(path) == 0) {
|
||||
*out_handle = new (alloc) Vfs_handle(*this, *this, alloc, 0);
|
||||
return OPEN_OK;
|
||||
try {
|
||||
*out_handle = new (alloc) Vfs_handle(*this, *this, alloc, 0);
|
||||
return OPEN_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
/* path refers to any of our sub file systems */
|
||||
@ -595,6 +603,9 @@ class Vfs::Dir_file_system : public File_system
|
||||
switch (r) {
|
||||
case OPENDIR_OK:
|
||||
break;
|
||||
case OPEN_ERR_OUT_OF_RAM:
|
||||
case OPEN_ERR_OUT_OF_CAPS:
|
||||
return r;
|
||||
case OPENDIR_ERR_LOOKUP_FAILED:
|
||||
default:
|
||||
continue;
|
||||
@ -625,8 +636,13 @@ class Vfs::Dir_file_system : public File_system
|
||||
* only, VFS root additionally calls 'open_composite_dirs' in order to
|
||||
* open its file systems
|
||||
*/
|
||||
Dir_vfs_handle *root_handle = new (alloc)
|
||||
Dir_vfs_handle(*this, *this, alloc, path);
|
||||
Dir_vfs_handle *root_handle;
|
||||
try {
|
||||
root_handle = new (alloc)
|
||||
Dir_vfs_handle(*this, *this, alloc, path);
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPENDIR_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPENDIR_ERR_OUT_OF_CAPS; }
|
||||
|
||||
/* the VFS root may contain more file systems */
|
||||
if (_vfs_root)
|
||||
@ -667,8 +683,13 @@ class Vfs::Dir_file_system : public File_system
|
||||
return opendir_result;
|
||||
}
|
||||
|
||||
Dir_vfs_handle *dir_vfs_handle = new (alloc)
|
||||
Dir_vfs_handle(*this, *this, alloc, path);
|
||||
Dir_vfs_handle *dir_vfs_handle;
|
||||
try {
|
||||
dir_vfs_handle = new (alloc)
|
||||
Dir_vfs_handle(*this, *this, alloc, path);
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPENDIR_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPENDIR_ERR_OUT_OF_CAPS; }
|
||||
|
||||
/* path equals "/" (for reading the name of this directory) */
|
||||
if (strlen(sub_path) == 0)
|
||||
|
@ -202,10 +202,14 @@ class Vfs::Single_file_system : public File_system
|
||||
if (create)
|
||||
return OPENDIR_ERR_PERMISSION_DENIED;
|
||||
|
||||
*out_handle =
|
||||
new (alloc) Single_vfs_dir_handle(*this, *this, alloc,
|
||||
_node_type, _filename);
|
||||
return OPENDIR_OK;
|
||||
try {
|
||||
*out_handle = new (alloc)
|
||||
Single_vfs_dir_handle(*this, *this, alloc,
|
||||
_node_type, _filename);
|
||||
return OPENDIR_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPENDIR_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPENDIR_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
void close(Vfs_handle *handle) override
|
||||
|
@ -384,22 +384,26 @@ class Vfs::Block_file_system : public Single_file_system
|
||||
if (!_single_file(path))
|
||||
return OPEN_ERR_UNACCESSIBLE;
|
||||
|
||||
*out_handle = new (alloc) Block_vfs_handle(*this, *this, alloc,
|
||||
_label, _lock,
|
||||
_block_buffer,
|
||||
_block_buffer_count,
|
||||
_tx_block_alloc,
|
||||
_block,
|
||||
_block_size,
|
||||
_block_count,
|
||||
_block_ops,
|
||||
_tx_source,
|
||||
_readable,
|
||||
_writeable,
|
||||
_signal_receiver,
|
||||
_signal_context,
|
||||
_source_submit_cap);
|
||||
return OPEN_OK;
|
||||
try {
|
||||
*out_handle = new (alloc) Block_vfs_handle(*this, *this, alloc,
|
||||
_label, _lock,
|
||||
_block_buffer,
|
||||
_block_buffer_count,
|
||||
_tx_block_alloc,
|
||||
_block,
|
||||
_block_size,
|
||||
_block_count,
|
||||
_block_ops,
|
||||
_tx_source,
|
||||
_readable,
|
||||
_writeable,
|
||||
_signal_receiver,
|
||||
_signal_context,
|
||||
_source_submit_cap);
|
||||
return OPEN_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
Stat_result stat(char const *path, Stat &out) override
|
||||
|
@ -775,9 +775,9 @@ class Vfs::Fs_file_system : public File_system
|
||||
catch (::File_system::Invalid_name) { return OPEN_ERR_NAME_TOO_LONG; }
|
||||
catch (::File_system::Name_too_long) { return OPEN_ERR_NAME_TOO_LONG; }
|
||||
catch (::File_system::No_space) { return OPEN_ERR_NO_SPACE; }
|
||||
catch (::File_system::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (::File_system::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
catch (::File_system::Unavailable) { return OPEN_ERR_UNACCESSIBLE; }
|
||||
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
|
||||
return OPEN_OK;
|
||||
}
|
||||
@ -800,9 +800,9 @@ class Vfs::Fs_file_system : public File_system
|
||||
catch (::File_system::Name_too_long) { return OPENDIR_ERR_NAME_TOO_LONG; }
|
||||
catch (::File_system::Node_already_exists) { return OPENDIR_ERR_NODE_ALREADY_EXISTS; }
|
||||
catch (::File_system::No_space) { return OPENDIR_ERR_NO_SPACE; }
|
||||
catch (::File_system::Out_of_ram) { return OPENDIR_ERR_OUT_OF_RAM; }
|
||||
catch (::File_system::Out_of_caps) { return OPENDIR_ERR_OUT_OF_CAPS; }
|
||||
catch (::File_system::Permission_denied) { return OPENDIR_ERR_PERMISSION_DENIED; }
|
||||
catch (Genode::Out_of_ram) { return OPENDIR_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPENDIR_ERR_OUT_OF_CAPS; }
|
||||
|
||||
return OPENDIR_OK;
|
||||
}
|
||||
@ -844,10 +844,10 @@ class Vfs::Fs_file_system : public File_system
|
||||
catch (::File_system::Lookup_failed) { return OPENLINK_ERR_LOOKUP_FAILED; }
|
||||
catch (::File_system::Node_already_exists) { return OPENLINK_ERR_NODE_ALREADY_EXISTS; }
|
||||
catch (::File_system::No_space) { return OPENLINK_ERR_NO_SPACE; }
|
||||
catch (::File_system::Out_of_ram) { return OPENLINK_ERR_OUT_OF_RAM; }
|
||||
catch (::File_system::Out_of_caps) { return OPENLINK_ERR_OUT_OF_CAPS; }
|
||||
catch (::File_system::Permission_denied) { return OPENLINK_ERR_PERMISSION_DENIED; }
|
||||
catch (::File_system::Unavailable) { return OPENLINK_ERR_LOOKUP_FAILED; }
|
||||
catch (Genode::Out_of_ram) { return OPENLINK_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPENLINK_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
void close(Vfs_handle *vfs_handle) override
|
||||
|
@ -125,9 +125,13 @@ class Vfs::Inline_file_system : public Single_file_system
|
||||
if (!_single_file(path))
|
||||
return OPEN_ERR_UNACCESSIBLE;
|
||||
|
||||
*out_handle = new (alloc) Inline_vfs_handle(*this, *this, alloc,
|
||||
_base, _size);
|
||||
return OPEN_OK;
|
||||
try {
|
||||
*out_handle = new (alloc)
|
||||
Inline_vfs_handle(*this, *this, alloc, _base, _size);
|
||||
return OPEN_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
Stat_result stat(char const *path, Stat &out) override
|
||||
|
@ -115,9 +115,13 @@ class Vfs::Log_file_system : public Single_file_system
|
||||
if (!_single_file(path))
|
||||
return OPEN_ERR_UNACCESSIBLE;
|
||||
|
||||
*out_handle = new (alloc) Log_vfs_handle(*this, *this, alloc,
|
||||
_log);
|
||||
return OPEN_OK;
|
||||
try {
|
||||
*out_handle = new (alloc)
|
||||
Log_vfs_handle(*this, *this, alloc, _log);
|
||||
return OPEN_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -69,8 +69,13 @@ struct Vfs::Null_file_system : Single_file_system
|
||||
if (!_single_file(path))
|
||||
return OPEN_ERR_UNACCESSIBLE;
|
||||
|
||||
*out_handle = new (alloc) Null_vfs_handle(*this, *this, alloc);
|
||||
return OPEN_OK;
|
||||
try {
|
||||
*out_handle = new (alloc)
|
||||
Null_vfs_handle(*this, *this, alloc);
|
||||
return OPEN_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
/********************************
|
||||
|
@ -551,8 +551,9 @@ class Vfs::Ram_file_system : public Vfs::File_system
|
||||
|
||||
File *file;
|
||||
char const *name = basename(path);
|
||||
bool const create = mode & OPEN_MODE_CREATE;
|
||||
|
||||
if (mode & OPEN_MODE_CREATE) {
|
||||
if (create) {
|
||||
Directory *parent = lookup_parent(path);
|
||||
if (!parent) return OPEN_ERR_UNACCESSIBLE;
|
||||
Node::Guard guard(parent);
|
||||
@ -573,8 +574,22 @@ class Vfs::Ram_file_system : public Vfs::File_system
|
||||
if (!file) return OPEN_ERR_UNACCESSIBLE;
|
||||
}
|
||||
|
||||
*handle = new (alloc) Ram_vfs_handle(*this, alloc, mode, *file);
|
||||
return OPEN_OK;
|
||||
try {
|
||||
*handle = new (alloc) Ram_vfs_handle(*this, alloc, mode, *file);
|
||||
return OPEN_OK;
|
||||
} catch (Genode::Out_of_ram) {
|
||||
if (create) {
|
||||
lookup_parent(path)->release(file);
|
||||
remove(file);
|
||||
}
|
||||
return OPEN_ERR_OUT_OF_RAM;
|
||||
} catch (Genode::Out_of_caps) {
|
||||
if (create) {
|
||||
lookup_parent(path)->release(file);
|
||||
remove(file);
|
||||
}
|
||||
return OPEN_ERR_OUT_OF_CAPS;
|
||||
}
|
||||
}
|
||||
|
||||
Opendir_result opendir(char const *path, bool create,
|
||||
@ -599,9 +614,8 @@ class Vfs::Ram_file_system : public Vfs::File_system
|
||||
if (parent->child(name))
|
||||
return OPENDIR_ERR_NODE_ALREADY_EXISTS;
|
||||
|
||||
try {
|
||||
dir = new (_alloc) Directory(name);
|
||||
} catch (Out_of_memory) { return OPENDIR_ERR_NO_SPACE; }
|
||||
try { dir = new (_alloc) Directory(name); }
|
||||
catch (Out_of_memory) { return OPENDIR_ERR_NO_SPACE; }
|
||||
|
||||
parent->adopt(dir);
|
||||
|
||||
@ -614,11 +628,24 @@ class Vfs::Ram_file_system : public Vfs::File_system
|
||||
if (!dir) return OPENDIR_ERR_LOOKUP_FAILED;
|
||||
}
|
||||
|
||||
*handle = new (alloc) Ram_vfs_handle(*this, alloc,
|
||||
Ram_vfs_handle::STATUS_RDONLY,
|
||||
*dir);
|
||||
|
||||
return OPENDIR_OK;
|
||||
try {
|
||||
*handle = new (alloc) Ram_vfs_handle(*this, alloc,
|
||||
Ram_vfs_handle::STATUS_RDONLY,
|
||||
*dir);
|
||||
return OPENDIR_OK;
|
||||
} catch (Genode::Out_of_ram) {
|
||||
if (create) {
|
||||
parent->release(dir);
|
||||
remove(dir);
|
||||
}
|
||||
return OPENDIR_ERR_OUT_OF_RAM;
|
||||
} catch (Genode::Out_of_caps) {
|
||||
if (create) {
|
||||
parent->release(dir);
|
||||
remove(dir);
|
||||
}
|
||||
return OPENDIR_ERR_OUT_OF_CAPS;
|
||||
}
|
||||
}
|
||||
|
||||
Openlink_result openlink(char const *path, bool create,
|
||||
@ -660,11 +687,24 @@ class Vfs::Ram_file_system : public Vfs::File_system
|
||||
if (!link) return OPENLINK_ERR_LOOKUP_FAILED;
|
||||
}
|
||||
|
||||
*handle = new (alloc) Ram_vfs_handle(*this, alloc,
|
||||
Ram_vfs_handle::STATUS_RDWR,
|
||||
*link);
|
||||
|
||||
return OPENLINK_OK;
|
||||
try {
|
||||
*handle = new (alloc) Ram_vfs_handle(*this, alloc,
|
||||
Ram_vfs_handle::STATUS_RDWR,
|
||||
*link);
|
||||
return OPENLINK_OK;
|
||||
} catch (Genode::Out_of_ram) {
|
||||
if (create) {
|
||||
parent->release(link);
|
||||
remove(link);
|
||||
}
|
||||
return OPENLINK_ERR_OUT_OF_RAM;
|
||||
} catch (Genode::Out_of_caps) {
|
||||
if (create) {
|
||||
parent->release(link);
|
||||
remove(link);
|
||||
}
|
||||
return OPENLINK_ERR_OUT_OF_CAPS;
|
||||
}
|
||||
}
|
||||
|
||||
void close(Vfs_handle *vfs_handle) override
|
||||
|
@ -128,8 +128,13 @@ class Vfs::Rom_file_system : public Single_file_system
|
||||
|
||||
_rom.update();
|
||||
|
||||
*out_handle = new (alloc) Rom_vfs_handle(*this, *this, alloc, _rom);
|
||||
return OPEN_OK;
|
||||
try {
|
||||
*out_handle = new (alloc)
|
||||
Rom_vfs_handle(*this, *this, alloc, _rom);
|
||||
return OPEN_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
Dataspace_capability dataspace(char const *) override
|
||||
|
@ -109,9 +109,13 @@ class Vfs::Rtc_file_system : public Single_file_system
|
||||
if (!_single_file(path))
|
||||
return OPEN_ERR_UNACCESSIBLE;
|
||||
|
||||
*out_handle = new (alloc) Rtc_vfs_handle(*this, *this, alloc,
|
||||
_rtc);
|
||||
return OPEN_OK;
|
||||
try {
|
||||
*out_handle = new (alloc)
|
||||
Rtc_vfs_handle(*this, *this, alloc, _rtc);
|
||||
return OPEN_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
Stat_result stat(char const *path, Stat &out) override
|
||||
|
@ -59,8 +59,12 @@ class Vfs::Symlink_file_system : public Single_file_system
|
||||
if (create)
|
||||
return OPENLINK_ERR_NODE_ALREADY_EXISTS;
|
||||
|
||||
*out_handle = new (alloc) Vfs_handle(*this, *this, alloc, 0);
|
||||
return OPENLINK_OK;
|
||||
try {
|
||||
*out_handle = new (alloc) Vfs_handle(*this, *this, alloc, 0);
|
||||
return OPENLINK_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPENLINK_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPENLINK_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
void close(Vfs_handle *vfs_handle) override
|
||||
|
@ -651,9 +651,13 @@ class Vfs::Tar_file_system : public File_system
|
||||
if (!node || !node->record || node->record->type() != Record::TYPE_FILE)
|
||||
return OPEN_ERR_UNACCESSIBLE;
|
||||
|
||||
*out_handle = new (alloc) Tar_vfs_file_handle(*this, alloc, 0, node);
|
||||
|
||||
return OPEN_OK;
|
||||
try {
|
||||
*out_handle = new (alloc)
|
||||
Tar_vfs_file_handle(*this, alloc, 0, node);
|
||||
return OPEN_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
Opendir_result opendir(char const *path, bool /* create */,
|
||||
@ -666,9 +670,13 @@ class Vfs::Tar_file_system : public File_system
|
||||
(node->record && (node->record->type() != Record::TYPE_DIR)))
|
||||
return OPENDIR_ERR_LOOKUP_FAILED;
|
||||
|
||||
*out_handle = new (alloc) Tar_vfs_dir_handle(*this, alloc, 0, node);
|
||||
|
||||
return OPENDIR_OK;
|
||||
try {
|
||||
*out_handle = new (alloc)
|
||||
Tar_vfs_dir_handle(*this, alloc, 0, node);
|
||||
return OPENDIR_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPENDIR_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPENDIR_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
Openlink_result openlink(char const *path, bool /* create */,
|
||||
@ -679,9 +687,13 @@ class Vfs::Tar_file_system : public File_system
|
||||
node->record->type() != Record::TYPE_SYMLINK)
|
||||
return OPENLINK_ERR_LOOKUP_FAILED;
|
||||
|
||||
*out_handle = new (alloc) Tar_vfs_symlink_handle(*this, alloc, 0, node);
|
||||
|
||||
return OPENLINK_OK;
|
||||
try {
|
||||
*out_handle = new (alloc)
|
||||
Tar_vfs_symlink_handle(*this, alloc, 0, node);
|
||||
return OPENLINK_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPENLINK_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPENLINK_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
void close(Vfs_handle *vfs_handle) override
|
||||
|
@ -128,10 +128,13 @@ class Vfs::Terminal_file_system : public Single_file_system
|
||||
if (!_single_file(path))
|
||||
return OPEN_ERR_UNACCESSIBLE;
|
||||
|
||||
*out_handle = new (alloc)
|
||||
Registered_handle(_handle_registry, *this, *this, alloc, 0);
|
||||
|
||||
return OPEN_OK;
|
||||
try {
|
||||
*out_handle = new (alloc)
|
||||
Registered_handle(_handle_registry, *this, *this, alloc, 0);
|
||||
return OPEN_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
/********************************
|
||||
|
@ -71,8 +71,12 @@ struct Vfs::Zero_file_system : Single_file_system
|
||||
if (!_single_file(path))
|
||||
return OPEN_ERR_UNACCESSIBLE;
|
||||
|
||||
*out_handle = new (alloc) Zero_vfs_handle(*this, *this, alloc);
|
||||
return OPEN_OK;
|
||||
try {
|
||||
*out_handle = new (alloc) Zero_vfs_handle(*this, *this, alloc);
|
||||
return OPEN_OK;
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
}
|
||||
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user