From e22cd98a4f8ee82bc84276a61f9ddb95ca2aa098 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Thu, 17 Mar 2016 16:29:27 +0100 Subject: [PATCH] File_system::Connection: session upgrading Upgrade the File_system session RAM quota when an Out_of_metadata exception is caught. Issue #1751 Issue #1909 --- .../include/file_system_session/connection.h | 75 +++++++++++++++++-- 1 file changed, 68 insertions(+), 7 deletions(-) diff --git a/repos/os/include/file_system_session/connection.h b/repos/os/include/file_system_session/connection.h index f6802cdc33..691e350658 100644 --- a/repos/os/include/file_system_session/connection.h +++ b/repos/os/include/file_system_session/connection.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -17,9 +17,11 @@ #include #include #include +#include namespace File_system { + struct Connection_base; struct Connection; /* recommended packet transmission buffer size */ @@ -28,7 +30,10 @@ namespace File_system { } -struct File_system::Connection : Genode::Connection, Session_client +/** + * The base implementation of a File_system connection + */ +struct File_system::Connection_base : Genode::Connection, Session_client { /** * Constructor @@ -36,12 +41,15 @@ struct File_system::Connection : Genode::Connection, Session_client * \param tx_buffer_alloc allocator used for managing the * transmission buffer * \param tx_buf_size size of transmission buffer in bytes + * \param label session label + * \param root root directory of session + * \param writeable session is writable */ - Connection(Genode::Range_allocator &tx_block_alloc, - size_t tx_buf_size = DEFAULT_TX_BUF_SIZE, - char const *label = "", - char const *root = "/", - bool writeable = true) + Connection_base(Genode::Range_allocator &tx_block_alloc, + size_t tx_buf_size = DEFAULT_TX_BUF_SIZE, + char const *label = "", + char const *root = "/", + bool writeable = true) : Genode::Connection( session("ram_quota=%zd, " @@ -56,4 +64,57 @@ struct File_system::Connection : Genode::Connection, Session_client { } }; + +/** + * A File_system connection that upgrades its RAM quota + */ +struct File_system::Connection : File_system::Connection_base +{ + /* reuse constructor */ + using Connection_base::Connection_base; + + /** + * Upgrade the session quota in response to Out_of_metadata + */ + void upgrade_ram() + { + PWRN("upgrading File_system session"); + Genode::env()->parent()->upgrade(cap(), "ram=8K"); + } + + enum { UPGRADE_ATTEMPTS = 2 }; + + Dir_handle dir(Path const &path, bool create) override + { + return Genode::retry( + [&] () { return Session_client::dir(path, create); }, + [&] () { upgrade_ram(); }, + UPGRADE_ATTEMPTS); + } + + File_handle file(Dir_handle dir, Name const &name, Mode mode, bool create) override + { + return Genode::retry( + [&] () { return Session_client::file(dir, name, mode, create); }, + [&] () { upgrade_ram(); }, + UPGRADE_ATTEMPTS); + } + + Symlink_handle symlink(Dir_handle dir, Name const &name, bool create) override + { + return Genode::retry( + [&] () { return Session_client::symlink(dir, name, create); }, + [&] () { upgrade_ram(); }, + UPGRADE_ATTEMPTS); + } + + Node_handle node(Path const &path) override + { + return Genode::retry( + [&] () { return Session_client::node(path); }, + [&] () { upgrade_ram(); }, + UPGRADE_ATTEMPTS); + } +}; + #endif /* _INCLUDE__FILE_SYSTEM_SESSION__CONNECTION_H_ */