mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-20 06:07:59 +00:00
parent
30948a4b0d
commit
547cc06976
@ -13,7 +13,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <file_system/open_node.h>
|
|
||||||
#include <file_system_session/rpc_object.h>
|
#include <file_system_session/rpc_object.h>
|
||||||
#include <base/attached_rom_dataspace.h>
|
#include <base/attached_rom_dataspace.h>
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
@ -29,6 +28,7 @@
|
|||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include "file_system.h"
|
#include "file_system.h"
|
||||||
#include "directory.h"
|
#include "directory.h"
|
||||||
|
#include "open_node.h"
|
||||||
|
|
||||||
namespace Rump_fs {
|
namespace Rump_fs {
|
||||||
|
|
||||||
|
95
repos/dde_rump/src/server/rump_fs/open_node.h
Normal file
95
repos/dde_rump/src/server/rump_fs/open_node.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* \brief Representation of an open file system node within the component (deprecated)
|
||||||
|
* \author Christian Prochaska
|
||||||
|
* \date 2017-06-09
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _OPEN_NODE_H_
|
||||||
|
#define _OPEN_NODE_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <file_system/listener.h>
|
||||||
|
#include <file_system_session/file_system_session.h>
|
||||||
|
|
||||||
|
namespace File_system {
|
||||||
|
/*
|
||||||
|
* \param NODE component-specific node type
|
||||||
|
*/
|
||||||
|
template <typename NODE> class Open_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename NODE>
|
||||||
|
class File_system::Open_node : public File_system::Node
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Genode::Id_space<File_system::Node>::Element _element;
|
||||||
|
|
||||||
|
NODE &_node;
|
||||||
|
Genode::Constructible<File_system::Listener> _listener;
|
||||||
|
|
||||||
|
Listener::Version const _version_when_opened = _node.curr_version();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flag to track whether the underlying file-system node was
|
||||||
|
* modified via this 'Open_node'. That is, if closing the 'Open_node'
|
||||||
|
* should notify listeners of the file.
|
||||||
|
*/
|
||||||
|
bool _was_written = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Open_node(NODE &node, Genode::Id_space<File_system::Node> &id_space)
|
||||||
|
: _element(*this, id_space), _node(node) { }
|
||||||
|
|
||||||
|
~Open_node()
|
||||||
|
{
|
||||||
|
if (_listener.constructed()) {
|
||||||
|
_node.remove_listener(&*_listener);
|
||||||
|
_listener.destruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notify remaining listeners about the changed file
|
||||||
|
*/
|
||||||
|
if (_was_written)
|
||||||
|
_node.notify_listeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
NODE &node() { return _node; }
|
||||||
|
File_system::Listener &listener() { return *_listener; }
|
||||||
|
|
||||||
|
Genode::Id_space<File_system::Node>::Id id() { return _element.id(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register packet stream sink to be notified of node changes
|
||||||
|
*/
|
||||||
|
void register_notify(File_system::Sink &sink)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If there was already a handler registered for the node,
|
||||||
|
* remove the old handler.
|
||||||
|
*/
|
||||||
|
if (_listener.constructed()) {
|
||||||
|
_node.remove_listener(&*_listener);
|
||||||
|
_listener.destruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register new handler
|
||||||
|
*/
|
||||||
|
_listener.construct(sink, id(), _version_when_opened);
|
||||||
|
_node.add_listener(&*_listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mark_as_written() { _was_written = true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _OPEN_NODE_H_ */
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/component.h>
|
#include <base/component.h>
|
||||||
#include <file_system/open_node.h>
|
|
||||||
#include <file_system_session/rpc_object.h>
|
#include <file_system_session/rpc_object.h>
|
||||||
#include <root/component.h>
|
#include <root/component.h>
|
||||||
#include <base/attached_rom_dataspace.h>
|
#include <base/attached_rom_dataspace.h>
|
||||||
@ -25,6 +24,7 @@
|
|||||||
/* local includes */
|
/* local includes */
|
||||||
#include <directory.h>
|
#include <directory.h>
|
||||||
#include <file.h>
|
#include <file.h>
|
||||||
|
#include <open_node.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
|
||||||
/* Genode block backend */
|
/* Genode block backend */
|
||||||
|
95
repos/libports/src/server/fatfs_fs/open_node.h
Normal file
95
repos/libports/src/server/fatfs_fs/open_node.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* \brief Representation of an open file system node within the component (deprecated)
|
||||||
|
* \author Christian Prochaska
|
||||||
|
* \date 2017-06-09
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _OPEN_NODE_H_
|
||||||
|
#define _OPEN_NODE_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <file_system/listener.h>
|
||||||
|
#include <file_system_session/file_system_session.h>
|
||||||
|
|
||||||
|
namespace File_system {
|
||||||
|
/*
|
||||||
|
* \param NODE component-specific node type
|
||||||
|
*/
|
||||||
|
template <typename NODE> class Open_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename NODE>
|
||||||
|
class File_system::Open_node : public File_system::Node
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Genode::Id_space<File_system::Node>::Element _element;
|
||||||
|
|
||||||
|
NODE &_node;
|
||||||
|
Genode::Constructible<File_system::Listener> _listener;
|
||||||
|
|
||||||
|
Listener::Version const _version_when_opened = _node.curr_version();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flag to track whether the underlying file-system node was
|
||||||
|
* modified via this 'Open_node'. That is, if closing the 'Open_node'
|
||||||
|
* should notify listeners of the file.
|
||||||
|
*/
|
||||||
|
bool _was_written = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Open_node(NODE &node, Genode::Id_space<File_system::Node> &id_space)
|
||||||
|
: _element(*this, id_space), _node(node) { }
|
||||||
|
|
||||||
|
~Open_node()
|
||||||
|
{
|
||||||
|
if (_listener.constructed()) {
|
||||||
|
_node.remove_listener(&*_listener);
|
||||||
|
_listener.destruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notify remaining listeners about the changed file
|
||||||
|
*/
|
||||||
|
if (_was_written)
|
||||||
|
_node.notify_listeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
NODE &node() { return _node; }
|
||||||
|
File_system::Listener &listener() { return *_listener; }
|
||||||
|
|
||||||
|
Genode::Id_space<File_system::Node>::Id id() { return _element.id(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register packet stream sink to be notified of node changes
|
||||||
|
*/
|
||||||
|
void register_notify(File_system::Sink &sink)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If there was already a handler registered for the node,
|
||||||
|
* remove the old handler.
|
||||||
|
*/
|
||||||
|
if (_listener.constructed()) {
|
||||||
|
_node.remove_listener(&*_listener);
|
||||||
|
_listener.destruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register new handler
|
||||||
|
*/
|
||||||
|
_listener.construct(sink, id(), _version_when_opened);
|
||||||
|
_node.add_listener(&*_listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mark_as_written() { _was_written = true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _OPEN_NODE_H_ */
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/heap.h>
|
#include <base/heap.h>
|
||||||
#include <file_system/open_node.h>
|
|
||||||
#include <file_system_session/rpc_object.h>
|
#include <file_system_session/rpc_object.h>
|
||||||
#include <base/attached_rom_dataspace.h>
|
#include <base/attached_rom_dataspace.h>
|
||||||
#include <os/session_policy.h>
|
#include <os/session_policy.h>
|
||||||
@ -26,6 +25,7 @@
|
|||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <directory.h>
|
#include <directory.h>
|
||||||
|
#include <open_node.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
|
||||||
|
|
||||||
|
95
repos/libports/src/server/fuse_fs/open_node.h
Normal file
95
repos/libports/src/server/fuse_fs/open_node.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* \brief Representation of an open file system node within the component (deprecated)
|
||||||
|
* \author Christian Prochaska
|
||||||
|
* \date 2017-06-09
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _OPEN_NODE_H_
|
||||||
|
#define _OPEN_NODE_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <file_system/listener.h>
|
||||||
|
#include <file_system_session/file_system_session.h>
|
||||||
|
|
||||||
|
namespace File_system {
|
||||||
|
/*
|
||||||
|
* \param NODE component-specific node type
|
||||||
|
*/
|
||||||
|
template <typename NODE> class Open_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename NODE>
|
||||||
|
class File_system::Open_node : public File_system::Node
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Genode::Id_space<File_system::Node>::Element _element;
|
||||||
|
|
||||||
|
NODE &_node;
|
||||||
|
Genode::Constructible<File_system::Listener> _listener;
|
||||||
|
|
||||||
|
Listener::Version const _version_when_opened = _node.curr_version();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flag to track whether the underlying file-system node was
|
||||||
|
* modified via this 'Open_node'. That is, if closing the 'Open_node'
|
||||||
|
* should notify listeners of the file.
|
||||||
|
*/
|
||||||
|
bool _was_written = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Open_node(NODE &node, Genode::Id_space<File_system::Node> &id_space)
|
||||||
|
: _element(*this, id_space), _node(node) { }
|
||||||
|
|
||||||
|
~Open_node()
|
||||||
|
{
|
||||||
|
if (_listener.constructed()) {
|
||||||
|
_node.remove_listener(&*_listener);
|
||||||
|
_listener.destruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notify remaining listeners about the changed file
|
||||||
|
*/
|
||||||
|
if (_was_written)
|
||||||
|
_node.notify_listeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
NODE &node() { return _node; }
|
||||||
|
File_system::Listener &listener() { return *_listener; }
|
||||||
|
|
||||||
|
Genode::Id_space<File_system::Node>::Id id() { return _element.id(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register packet stream sink to be notified of node changes
|
||||||
|
*/
|
||||||
|
void register_notify(File_system::Sink &sink)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If there was already a handler registered for the node,
|
||||||
|
* remove the old handler.
|
||||||
|
*/
|
||||||
|
if (_listener.constructed()) {
|
||||||
|
_node.remove_listener(&*_listener);
|
||||||
|
_listener.destruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register new handler
|
||||||
|
*/
|
||||||
|
_listener.construct(sink, id(), _version_when_opened);
|
||||||
|
_node.add_listener(&*_listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mark_as_written() { _was_written = true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _OPEN_NODE_H_ */
|
@ -32,10 +32,10 @@ class File_system::Open_node : public File_system::Node
|
|||||||
|
|
||||||
Genode::Id_space<File_system::Node>::Element _element;
|
Genode::Id_space<File_system::Node>::Element _element;
|
||||||
|
|
||||||
NODE &_node;
|
Genode::Weak_ptr<NODE> _node;
|
||||||
Genode::Constructible<File_system::Listener> _listener;
|
Genode::Constructible<File_system::Listener> _listener;
|
||||||
|
|
||||||
Listener::Version const _version_when_opened = _node.curr_version();
|
Listener::Version const _version_when_opened { _node_version(_node) };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flag to track whether the underlying file-system node was
|
* Flag to track whether the underlying file-system node was
|
||||||
@ -44,15 +44,29 @@ class File_system::Open_node : public File_system::Node
|
|||||||
*/
|
*/
|
||||||
bool _was_written = false;
|
bool _was_written = false;
|
||||||
|
|
||||||
|
static Listener::Version const _node_version(Genode::Weak_ptr<NODE> node)
|
||||||
|
{
|
||||||
|
Genode::Locked_ptr<NODE> locked_node { node };
|
||||||
|
|
||||||
|
if (locked_node.valid())
|
||||||
|
return locked_node->curr_version();
|
||||||
|
else
|
||||||
|
return Listener::Version { 0 };
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Open_node(NODE &node, Genode::Id_space<File_system::Node> &id_space)
|
Open_node(Genode::Weak_ptr<NODE> node,
|
||||||
|
Genode::Id_space<File_system::Node> &id_space)
|
||||||
: _element(*this, id_space), _node(node) { }
|
: _element(*this, id_space), _node(node) { }
|
||||||
|
|
||||||
~Open_node()
|
~Open_node()
|
||||||
{
|
{
|
||||||
|
Genode::Locked_ptr<NODE> node { _node };
|
||||||
|
|
||||||
if (_listener.constructed()) {
|
if (_listener.constructed()) {
|
||||||
_node.remove_listener(&*_listener);
|
if (node.valid())
|
||||||
|
node->remove_listener(&*_listener);
|
||||||
_listener.destruct();
|
_listener.destruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,10 +74,11 @@ class File_system::Open_node : public File_system::Node
|
|||||||
* Notify remaining listeners about the changed file
|
* Notify remaining listeners about the changed file
|
||||||
*/
|
*/
|
||||||
if (_was_written)
|
if (_was_written)
|
||||||
_node.notify_listeners();
|
if (node.valid())
|
||||||
|
node->notify_listeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
NODE &node() { return _node; }
|
Genode::Weak_ptr<NODE>&node() { return _node; }
|
||||||
File_system::Listener &listener() { return *_listener; }
|
File_system::Listener &listener() { return *_listener; }
|
||||||
|
|
||||||
Genode::Id_space<File_system::Node>::Id id() { return _element.id(); }
|
Genode::Id_space<File_system::Node>::Id id() { return _element.id(); }
|
||||||
@ -73,20 +88,25 @@ class File_system::Open_node : public File_system::Node
|
|||||||
*/
|
*/
|
||||||
void register_notify(File_system::Sink &sink)
|
void register_notify(File_system::Sink &sink)
|
||||||
{
|
{
|
||||||
|
Genode::Locked_ptr<NODE> node { _node };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there was already a handler registered for the node,
|
* If there was already a handler registered for the node,
|
||||||
* remove the old handler.
|
* remove the old handler.
|
||||||
*/
|
*/
|
||||||
if (_listener.constructed()) {
|
if (_listener.constructed()) {
|
||||||
_node.remove_listener(&*_listener);
|
if (node.valid())
|
||||||
|
node->remove_listener(&*_listener);
|
||||||
_listener.destruct();
|
_listener.destruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register new handler
|
* Register new handler
|
||||||
*/
|
*/
|
||||||
_listener.construct(sink, id(), _version_when_opened);
|
if (node.valid()) {
|
||||||
_node.add_listener(&*_listener);
|
_listener.construct(sink, id(), _version_when_opened);
|
||||||
|
node->add_listener(&*_listener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mark_as_written() { _was_written = true; }
|
void mark_as_written() { _was_written = true; }
|
||||||
|
@ -105,6 +105,7 @@ namespace File_system {
|
|||||||
class No_space : Exception { };
|
class No_space : Exception { };
|
||||||
class Not_empty : Exception { };
|
class Not_empty : Exception { };
|
||||||
class Permission_denied : Exception { };
|
class Permission_denied : Exception { };
|
||||||
|
class Unavailable : Exception { };
|
||||||
|
|
||||||
struct Session;
|
struct Session;
|
||||||
}
|
}
|
||||||
@ -288,6 +289,7 @@ struct File_system::Session : public Genode::Session
|
|||||||
* \throw Out_of_ram server cannot allocate metadata
|
* \throw Out_of_ram server cannot allocate metadata
|
||||||
* \throw Out_of_caps
|
* \throw Out_of_caps
|
||||||
* \throw Permission_denied
|
* \throw Permission_denied
|
||||||
|
* \throw Unavailable directory vanished
|
||||||
*/
|
*/
|
||||||
virtual File_handle file(Dir_handle, Name const &name, Mode, bool create) = 0;
|
virtual File_handle file(Dir_handle, Name const &name, Mode, bool create) = 0;
|
||||||
|
|
||||||
@ -303,6 +305,7 @@ struct File_system::Session : public Genode::Session
|
|||||||
* \throw Out_of_ram server cannot allocate metadata
|
* \throw Out_of_ram server cannot allocate metadata
|
||||||
* \throw Out_of_caps
|
* \throw Out_of_caps
|
||||||
* \throw Permission_denied
|
* \throw Permission_denied
|
||||||
|
* \throw Unavailable directory vanished
|
||||||
*/
|
*/
|
||||||
virtual Symlink_handle symlink(Dir_handle, Name const &name, bool create) = 0;
|
virtual Symlink_handle symlink(Dir_handle, Name const &name, bool create) = 0;
|
||||||
|
|
||||||
@ -345,6 +348,7 @@ struct File_system::Session : public Genode::Session
|
|||||||
* Request information about an open file or directory
|
* Request information about an open file or directory
|
||||||
*
|
*
|
||||||
* \throw Invalid_handle node handle is invalid
|
* \throw Invalid_handle node handle is invalid
|
||||||
|
* \throw Unavailable node vanished
|
||||||
*/
|
*/
|
||||||
virtual Status status(Node_handle) = 0;
|
virtual Status status(Node_handle) = 0;
|
||||||
|
|
||||||
@ -352,6 +356,7 @@ struct File_system::Session : public Genode::Session
|
|||||||
* Set information about an open file or directory
|
* Set information about an open file or directory
|
||||||
*
|
*
|
||||||
* \throw Invalid_handle node handle is invalid
|
* \throw Invalid_handle node handle is invalid
|
||||||
|
* \throw Unavailable node vanished
|
||||||
*/
|
*/
|
||||||
virtual void control(Node_handle, Control) = 0;
|
virtual void control(Node_handle, Control) = 0;
|
||||||
|
|
||||||
@ -364,6 +369,7 @@ struct File_system::Session : public Genode::Session
|
|||||||
* \throw Not_empty argument is a non-empty directory and
|
* \throw Not_empty argument is a non-empty directory and
|
||||||
* the backend does not support recursion
|
* the backend does not support recursion
|
||||||
* \throw Permission_denied
|
* \throw Permission_denied
|
||||||
|
* \throw Unavailable directory vanished
|
||||||
*/
|
*/
|
||||||
virtual void unlink(Dir_handle dir, Name const &name) = 0;
|
virtual void unlink(Dir_handle dir, Name const &name) = 0;
|
||||||
|
|
||||||
@ -373,6 +379,7 @@ struct File_system::Session : public Genode::Session
|
|||||||
* \throw Invalid_handle node handle is invalid
|
* \throw Invalid_handle node handle is invalid
|
||||||
* \throw No_space new size exceeds free space
|
* \throw No_space new size exceeds free space
|
||||||
* \throw Permission_denied node modification not allowed
|
* \throw Permission_denied node modification not allowed
|
||||||
|
* \throw Unavailable node vanished
|
||||||
*/
|
*/
|
||||||
virtual void truncate(File_handle, file_size_t size) = 0;
|
virtual void truncate(File_handle, file_size_t size) = 0;
|
||||||
|
|
||||||
@ -383,6 +390,7 @@ struct File_system::Session : public Genode::Session
|
|||||||
* \throw Invalid_name 'to' contains invalid characters
|
* \throw Invalid_name 'to' contains invalid characters
|
||||||
* \throw Lookup_failed 'from' not found
|
* \throw Lookup_failed 'from' not found
|
||||||
* \throw Permission_denied node modification not allowed
|
* \throw Permission_denied node modification not allowed
|
||||||
|
* \throw Unavailable a directory vanished
|
||||||
*/
|
*/
|
||||||
virtual void move(Dir_handle, Name const &from,
|
virtual void move(Dir_handle, Name const &from,
|
||||||
Dir_handle, Name const &to) = 0;
|
Dir_handle, Name const &to) = 0;
|
||||||
@ -397,13 +405,13 @@ struct File_system::Session : public Genode::Session
|
|||||||
GENODE_TYPE_LIST(Invalid_handle, Invalid_name,
|
GENODE_TYPE_LIST(Invalid_handle, Invalid_name,
|
||||||
Lookup_failed, Node_already_exists,
|
Lookup_failed, Node_already_exists,
|
||||||
No_space, Out_of_ram, Out_of_caps,
|
No_space, Out_of_ram, Out_of_caps,
|
||||||
Permission_denied),
|
Permission_denied, Unavailable),
|
||||||
Dir_handle, Name const &, Mode, bool);
|
Dir_handle, Name const &, Mode, bool);
|
||||||
GENODE_RPC_THROW(Rpc_symlink, Symlink_handle, symlink,
|
GENODE_RPC_THROW(Rpc_symlink, Symlink_handle, symlink,
|
||||||
GENODE_TYPE_LIST(Invalid_handle, Invalid_name,
|
GENODE_TYPE_LIST(Invalid_handle, Invalid_name,
|
||||||
Lookup_failed, Node_already_exists,
|
Lookup_failed, Node_already_exists,
|
||||||
No_space, Out_of_ram, Out_of_caps,
|
No_space, Out_of_ram, Out_of_caps,
|
||||||
Permission_denied),
|
Permission_denied, Unavailable),
|
||||||
Dir_handle, Name const &, bool);
|
Dir_handle, Name const &, bool);
|
||||||
GENODE_RPC_THROW(Rpc_dir, Dir_handle, dir,
|
GENODE_RPC_THROW(Rpc_dir, Dir_handle, dir,
|
||||||
GENODE_TYPE_LIST(Lookup_failed, Name_too_long,
|
GENODE_TYPE_LIST(Lookup_failed, Name_too_long,
|
||||||
@ -417,23 +425,23 @@ struct File_system::Session : public Genode::Session
|
|||||||
GENODE_TYPE_LIST(Invalid_handle),
|
GENODE_TYPE_LIST(Invalid_handle),
|
||||||
Node_handle);
|
Node_handle);
|
||||||
GENODE_RPC_THROW(Rpc_status, Status, status,
|
GENODE_RPC_THROW(Rpc_status, Status, status,
|
||||||
GENODE_TYPE_LIST(Invalid_handle),
|
GENODE_TYPE_LIST(Invalid_handle, Unavailable),
|
||||||
Node_handle);
|
Node_handle);
|
||||||
GENODE_RPC_THROW(Rpc_control, void, control,
|
GENODE_RPC_THROW(Rpc_control, void, control,
|
||||||
GENODE_TYPE_LIST(Invalid_handle),
|
GENODE_TYPE_LIST(Invalid_handle, Unavailable),
|
||||||
Node_handle, Control);
|
Node_handle, Control);
|
||||||
GENODE_RPC_THROW(Rpc_unlink, void, unlink,
|
GENODE_RPC_THROW(Rpc_unlink, void, unlink,
|
||||||
GENODE_TYPE_LIST(Invalid_handle, Invalid_name,
|
GENODE_TYPE_LIST(Invalid_handle, Invalid_name,
|
||||||
Lookup_failed, Not_empty,
|
Lookup_failed, Not_empty,
|
||||||
Permission_denied),
|
Permission_denied, Unavailable),
|
||||||
Dir_handle, Name const &);
|
Dir_handle, Name const &);
|
||||||
GENODE_RPC_THROW(Rpc_truncate, void, truncate,
|
GENODE_RPC_THROW(Rpc_truncate, void, truncate,
|
||||||
GENODE_TYPE_LIST(Invalid_handle, No_space,
|
GENODE_TYPE_LIST(Invalid_handle, No_space,
|
||||||
Permission_denied),
|
Permission_denied, Unavailable),
|
||||||
File_handle, file_size_t);
|
File_handle, file_size_t);
|
||||||
GENODE_RPC_THROW(Rpc_move, void, move,
|
GENODE_RPC_THROW(Rpc_move, void, move,
|
||||||
GENODE_TYPE_LIST(Invalid_handle, Invalid_name,
|
GENODE_TYPE_LIST(Invalid_handle, Invalid_name,
|
||||||
Lookup_failed, Permission_denied),
|
Lookup_failed, Permission_denied, Unavailable),
|
||||||
Dir_handle, Name const &, Dir_handle, Name const &);
|
Dir_handle, Name const &, Dir_handle, Name const &);
|
||||||
|
|
||||||
GENODE_RPC_INTERFACE(Rpc_tx_cap, Rpc_file, Rpc_symlink, Rpc_dir, Rpc_node,
|
GENODE_RPC_INTERFACE(Rpc_tx_cap, Rpc_file, Rpc_symlink, Rpc_dir, Rpc_node,
|
||||||
|
@ -638,6 +638,7 @@ class Vfs::Fs_file_system : public File_system
|
|||||||
catch (::File_system::Lookup_failed) { return UNLINK_ERR_NO_ENTRY; }
|
catch (::File_system::Lookup_failed) { return UNLINK_ERR_NO_ENTRY; }
|
||||||
catch (::File_system::Not_empty) { return UNLINK_ERR_NOT_EMPTY; }
|
catch (::File_system::Not_empty) { return UNLINK_ERR_NOT_EMPTY; }
|
||||||
catch (::File_system::Permission_denied) { return UNLINK_ERR_NO_PERM; }
|
catch (::File_system::Permission_denied) { return UNLINK_ERR_NO_PERM; }
|
||||||
|
catch (::File_system::Unavailable) { return UNLINK_ERR_NO_ENTRY; }
|
||||||
|
|
||||||
return UNLINK_OK;
|
return UNLINK_OK;
|
||||||
}
|
}
|
||||||
@ -765,6 +766,7 @@ class Vfs::Fs_file_system : public File_system
|
|||||||
catch (::File_system::No_space) { return OPEN_ERR_NO_SPACE; }
|
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_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||||
catch (::File_system::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
catch (::File_system::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||||
|
catch (::File_system::Unavailable) { return OPEN_ERR_UNACCESSIBLE; }
|
||||||
|
|
||||||
return OPEN_OK;
|
return OPEN_OK;
|
||||||
}
|
}
|
||||||
@ -834,6 +836,7 @@ class Vfs::Fs_file_system : public File_system
|
|||||||
catch (::File_system::Out_of_ram) { return OPENLINK_ERR_OUT_OF_RAM; }
|
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::Out_of_caps) { return OPENLINK_ERR_OUT_OF_CAPS; }
|
||||||
catch (::File_system::Permission_denied) { return OPENLINK_ERR_PERMISSION_DENIED; }
|
catch (::File_system::Permission_denied) { return OPENLINK_ERR_PERMISSION_DENIED; }
|
||||||
|
catch (::File_system::Unavailable) { return OPENLINK_ERR_LOOKUP_FAILED; }
|
||||||
}
|
}
|
||||||
|
|
||||||
void close(Vfs_handle *vfs_handle) override
|
void close(Vfs_handle *vfs_handle) override
|
||||||
@ -940,6 +943,7 @@ class Vfs::Fs_file_system : public File_system
|
|||||||
catch (::File_system::Invalid_handle) { return FTRUNCATE_ERR_NO_PERM; }
|
catch (::File_system::Invalid_handle) { return FTRUNCATE_ERR_NO_PERM; }
|
||||||
catch (::File_system::Permission_denied) { 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; }
|
catch (::File_system::No_space) { return FTRUNCATE_ERR_NO_SPACE; }
|
||||||
|
catch (::File_system::Unavailable) { return FTRUNCATE_ERR_NO_PERM; }
|
||||||
|
|
||||||
return FTRUNCATE_OK;
|
return FTRUNCATE_OK;
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,13 @@
|
|||||||
#include <base/heap.h>
|
#include <base/heap.h>
|
||||||
#include <base/attached_rom_dataspace.h>
|
#include <base/attached_rom_dataspace.h>
|
||||||
#include <root/component.h>
|
#include <root/component.h>
|
||||||
#include <file_system/open_node.h>
|
|
||||||
#include <file_system_session/rpc_object.h>
|
#include <file_system_session/rpc_object.h>
|
||||||
#include <os/session_policy.h>
|
#include <os/session_policy.h>
|
||||||
#include <util/xml_node.h>
|
#include <util/xml_node.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <directory.h>
|
#include <directory.h>
|
||||||
|
#include <open_node.h>
|
||||||
|
|
||||||
namespace Lx_fs {
|
namespace Lx_fs {
|
||||||
|
|
||||||
|
95
repos/os/src/server/lx_fs/open_node.h
Normal file
95
repos/os/src/server/lx_fs/open_node.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* \brief Representation of an open file system node within the component (deprecated)
|
||||||
|
* \author Christian Prochaska
|
||||||
|
* \date 2017-06-09
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _OPEN_NODE_H_
|
||||||
|
#define _OPEN_NODE_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <file_system/listener.h>
|
||||||
|
#include <file_system_session/file_system_session.h>
|
||||||
|
|
||||||
|
namespace File_system {
|
||||||
|
/*
|
||||||
|
* \param NODE component-specific node type
|
||||||
|
*/
|
||||||
|
template <typename NODE> class Open_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename NODE>
|
||||||
|
class File_system::Open_node : public File_system::Node
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Genode::Id_space<File_system::Node>::Element _element;
|
||||||
|
|
||||||
|
NODE &_node;
|
||||||
|
Genode::Constructible<File_system::Listener> _listener;
|
||||||
|
|
||||||
|
Listener::Version const _version_when_opened = _node.curr_version();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flag to track whether the underlying file-system node was
|
||||||
|
* modified via this 'Open_node'. That is, if closing the 'Open_node'
|
||||||
|
* should notify listeners of the file.
|
||||||
|
*/
|
||||||
|
bool _was_written = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Open_node(NODE &node, Genode::Id_space<File_system::Node> &id_space)
|
||||||
|
: _element(*this, id_space), _node(node) { }
|
||||||
|
|
||||||
|
~Open_node()
|
||||||
|
{
|
||||||
|
if (_listener.constructed()) {
|
||||||
|
_node.remove_listener(&*_listener);
|
||||||
|
_listener.destruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notify remaining listeners about the changed file
|
||||||
|
*/
|
||||||
|
if (_was_written)
|
||||||
|
_node.notify_listeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
NODE &node() { return _node; }
|
||||||
|
File_system::Listener &listener() { return *_listener; }
|
||||||
|
|
||||||
|
Genode::Id_space<File_system::Node>::Id id() { return _element.id(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register packet stream sink to be notified of node changes
|
||||||
|
*/
|
||||||
|
void register_notify(File_system::Sink &sink)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If there was already a handler registered for the node,
|
||||||
|
* remove the old handler.
|
||||||
|
*/
|
||||||
|
if (_listener.constructed()) {
|
||||||
|
_node.remove_listener(&*_listener);
|
||||||
|
_listener.destruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register new handler
|
||||||
|
*/
|
||||||
|
_listener.construct(sink, id(), _version_when_opened);
|
||||||
|
_node.add_listener(&*_listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mark_as_written() { _was_written = true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _OPEN_NODE_H_ */
|
@ -76,30 +76,47 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
|||||||
switch (packet.operation()) {
|
switch (packet.operation()) {
|
||||||
|
|
||||||
case Packet_descriptor::READ:
|
case Packet_descriptor::READ:
|
||||||
if (content && (packet.length() <= packet.size()))
|
if (content && (packet.length() <= packet.size())) {
|
||||||
res_length = open_node.node().read((char *)content, length, packet.position());
|
Locked_ptr<Node> node { open_node.node() };
|
||||||
|
if (!node.valid())
|
||||||
|
break;
|
||||||
|
res_length = node->read((char *)content, length,
|
||||||
|
packet.position());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Packet_descriptor::WRITE:
|
case Packet_descriptor::WRITE:
|
||||||
if (content && (packet.length() <= packet.size()))
|
if (content && (packet.length() <= packet.size())) {
|
||||||
res_length = open_node.node().write((char const *)content, length, packet.position());
|
Locked_ptr<Node> node { open_node.node() };
|
||||||
|
if (!node.valid())
|
||||||
|
break;
|
||||||
|
res_length = node->write((char const *)content, length,
|
||||||
|
packet.position());
|
||||||
|
}
|
||||||
open_node.mark_as_written();
|
open_node.mark_as_written();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Packet_descriptor::CONTENT_CHANGED:
|
case Packet_descriptor::CONTENT_CHANGED: {
|
||||||
open_node.register_notify(*tx_sink());
|
open_node.register_notify(*tx_sink());
|
||||||
open_node.node().notify_listeners();
|
Locked_ptr<Node> node { open_node.node() };
|
||||||
|
if (!node.valid())
|
||||||
|
return;
|
||||||
|
node->notify_listeners();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case Packet_descriptor::READ_READY:
|
case Packet_descriptor::READ_READY:
|
||||||
/* not supported */
|
/* not supported */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Packet_descriptor::SYNC:
|
case Packet_descriptor::SYNC: {
|
||||||
open_node.node().notify_listeners();
|
Locked_ptr<Node> node { open_node.node() };
|
||||||
|
if (!node.valid())
|
||||||
|
break;
|
||||||
|
node->notify_listeners();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
packet.length(res_length);
|
packet.length(res_length);
|
||||||
packet.succeeded(res_length > 0);
|
packet.succeeded(res_length > 0);
|
||||||
@ -207,7 +224,10 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
|||||||
|
|
||||||
auto file_fn = [&] (Open_node &open_node) {
|
auto file_fn = [&] (Open_node &open_node) {
|
||||||
|
|
||||||
Node &dir = open_node.node();
|
Locked_ptr<Node> dir { open_node.node() };
|
||||||
|
|
||||||
|
if (!dir.valid())
|
||||||
|
throw Unavailable();
|
||||||
|
|
||||||
if (!_writable)
|
if (!_writable)
|
||||||
if (mode != STAT_ONLY && mode != READ_ONLY)
|
if (mode != STAT_ONLY && mode != READ_ONLY)
|
||||||
@ -218,23 +238,23 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
|||||||
if (!_writable)
|
if (!_writable)
|
||||||
throw Permission_denied();
|
throw Permission_denied();
|
||||||
|
|
||||||
if (dir.has_sub_node_unsynchronized(name.string()))
|
if (dir->has_sub_node_unsynchronized(name.string()))
|
||||||
throw Node_already_exists();
|
throw Node_already_exists();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File * const file = new (_alloc)
|
File * const file = new (_alloc)
|
||||||
File(_alloc, name.string());
|
File(_alloc, name.string());
|
||||||
|
|
||||||
dir.adopt_unsynchronized(file);
|
dir->adopt_unsynchronized(file);
|
||||||
open_node.mark_as_written();
|
open_node.mark_as_written();
|
||||||
}
|
}
|
||||||
catch (Allocator::Out_of_memory) { throw No_space(); }
|
catch (Allocator::Out_of_memory) { throw No_space(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
File *file = dir.lookup_file(name.string());
|
File *file = dir->lookup_file(name.string());
|
||||||
|
|
||||||
Open_node *open_file =
|
Open_node *open_file =
|
||||||
new (_alloc) Open_node(*file, _open_node_registry);
|
new (_alloc) Open_node(file->weak_ptr(), _open_node_registry);
|
||||||
|
|
||||||
return open_file->id();
|
return open_file->id();
|
||||||
};
|
};
|
||||||
@ -255,29 +275,32 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
|||||||
|
|
||||||
auto symlink_fn = [&] (Open_node &open_node) {
|
auto symlink_fn = [&] (Open_node &open_node) {
|
||||||
|
|
||||||
Node &dir = open_node.node();
|
Locked_ptr<Node> dir { open_node.node() };
|
||||||
|
|
||||||
|
if (!dir.valid())
|
||||||
|
throw Unavailable();
|
||||||
|
|
||||||
if (create) {
|
if (create) {
|
||||||
|
|
||||||
if (!_writable)
|
if (!_writable)
|
||||||
throw Permission_denied();
|
throw Permission_denied();
|
||||||
|
|
||||||
if (dir.has_sub_node_unsynchronized(name.string()))
|
if (dir->has_sub_node_unsynchronized(name.string()))
|
||||||
throw Node_already_exists();
|
throw Node_already_exists();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Symlink * const symlink = new (_alloc)
|
Symlink * const symlink = new (_alloc)
|
||||||
Symlink(name.string());
|
Symlink(name.string());
|
||||||
|
|
||||||
dir.adopt_unsynchronized(symlink);
|
dir->adopt_unsynchronized(symlink);
|
||||||
}
|
}
|
||||||
catch (Allocator::Out_of_memory) { throw No_space(); }
|
catch (Allocator::Out_of_memory) { throw No_space(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
Symlink *symlink = dir.lookup_symlink(name.string());
|
Symlink *symlink = dir->lookup_symlink(name.string());
|
||||||
|
|
||||||
Open_node *open_symlink =
|
Open_node *open_symlink =
|
||||||
new (_alloc) Open_node(*symlink, _open_node_registry);
|
new (_alloc) Open_node(symlink->weak_ptr(), _open_node_registry);
|
||||||
|
|
||||||
return open_symlink->id();
|
return open_symlink->id();
|
||||||
};
|
};
|
||||||
@ -325,7 +348,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
|||||||
Directory *dir = _root.lookup_dir(path_str);
|
Directory *dir = _root.lookup_dir(path_str);
|
||||||
|
|
||||||
Open_node *open_dir =
|
Open_node *open_dir =
|
||||||
new (_alloc) Open_node(*dir, _open_node_registry);
|
new (_alloc) Open_node(dir->weak_ptr(), _open_node_registry);
|
||||||
|
|
||||||
return Dir_handle { open_dir->id().value };
|
return Dir_handle { open_dir->id().value };
|
||||||
}
|
}
|
||||||
@ -337,7 +360,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
|||||||
Node *node = _root.lookup(path.string() + 1);
|
Node *node = _root.lookup(path.string() + 1);
|
||||||
|
|
||||||
Open_node *open_node =
|
Open_node *open_node =
|
||||||
new (_alloc) Open_node(*node, _open_node_registry);
|
new (_alloc) Open_node(node->weak_ptr(), _open_node_registry);
|
||||||
|
|
||||||
return open_node->id();
|
return open_node->id();
|
||||||
}
|
}
|
||||||
@ -345,7 +368,8 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
|||||||
void close(Node_handle handle)
|
void close(Node_handle handle)
|
||||||
{
|
{
|
||||||
auto close_fn = [&] (Open_node &open_node) {
|
auto close_fn = [&] (Open_node &open_node) {
|
||||||
destroy(_alloc, &open_node); };
|
destroy(_alloc, &open_node);
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_open_node_registry.apply<Open_node>(handle, close_fn);
|
_open_node_registry.apply<Open_node>(handle, close_fn);
|
||||||
@ -357,7 +381,11 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
|||||||
Status status(Node_handle node_handle)
|
Status status(Node_handle node_handle)
|
||||||
{
|
{
|
||||||
auto status_fn = [&] (Open_node &open_node) {
|
auto status_fn = [&] (Open_node &open_node) {
|
||||||
return open_node.node().status(); };
|
Locked_ptr<Node> node { open_node.node() };
|
||||||
|
if (!node.valid())
|
||||||
|
throw Unavailable();
|
||||||
|
return node->status();
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return _open_node_registry.apply<Open_node>(node_handle, status_fn);
|
return _open_node_registry.apply<Open_node>(node_handle, status_fn);
|
||||||
@ -378,14 +406,14 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
|||||||
|
|
||||||
auto unlink_fn = [&] (Open_node &open_node) {
|
auto unlink_fn = [&] (Open_node &open_node) {
|
||||||
|
|
||||||
Node &dir = open_node.node();
|
Locked_ptr<Node> dir { open_node.node() };
|
||||||
|
|
||||||
Node *node = dir.lookup(name.string());
|
if (!dir.valid())
|
||||||
|
throw Unavailable();
|
||||||
|
|
||||||
dir.discard(node);
|
Node *node = dir->lookup(name.string());
|
||||||
|
|
||||||
// XXX implement ref counting, do not destroy node that is
|
dir->discard(node);
|
||||||
// is still referenced by a node handle
|
|
||||||
|
|
||||||
destroy(_alloc, node);
|
destroy(_alloc, node);
|
||||||
open_node.mark_as_written();
|
open_node.mark_as_written();
|
||||||
@ -404,7 +432,10 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
|||||||
throw Permission_denied();
|
throw Permission_denied();
|
||||||
|
|
||||||
auto truncate_fn = [&] (Open_node &open_node) {
|
auto truncate_fn = [&] (Open_node &open_node) {
|
||||||
open_node.node().truncate(size);
|
Locked_ptr<Node> node { open_node.node() };
|
||||||
|
if (!node.valid())
|
||||||
|
throw Unavailable();
|
||||||
|
node->truncate(size);
|
||||||
open_node.mark_as_written();
|
open_node.mark_as_written();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -431,17 +462,23 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
|||||||
|
|
||||||
auto inner_move_fn = [&] (Open_node &open_to_dir_node) {
|
auto inner_move_fn = [&] (Open_node &open_to_dir_node) {
|
||||||
|
|
||||||
Node &from_dir = open_from_dir_node.node();
|
Locked_ptr<Node> from_dir { open_from_dir_node.node() };
|
||||||
|
|
||||||
Node *node = from_dir.lookup(from_name.string());
|
if (!from_dir.valid())
|
||||||
|
throw Unavailable();
|
||||||
|
|
||||||
|
Node *node = from_dir->lookup(from_name.string());
|
||||||
node->name(to_name.string());
|
node->name(to_name.string());
|
||||||
|
|
||||||
Node &to_dir = open_to_dir_node.node();
|
if (!(open_to_dir_node.node() == open_from_dir_node.node())) {
|
||||||
|
|
||||||
if (&to_dir != &from_dir) {
|
Locked_ptr<Node> to_dir { open_to_dir_node.node() };
|
||||||
|
|
||||||
from_dir.discard(node);
|
if (!to_dir.valid())
|
||||||
to_dir.adopt_unsynchronized(node);
|
throw Unavailable();
|
||||||
|
|
||||||
|
from_dir->discard(node);
|
||||||
|
to_dir->adopt_unsynchronized(node);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the file was moved from one directory to another we
|
* If the file was moved from one directory to another we
|
||||||
@ -449,13 +486,13 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
|||||||
* directory 'from_dir' will always get notified (i.e.,
|
* directory 'from_dir' will always get notified (i.e.,
|
||||||
* when just the file name was changed) below.
|
* when just the file name was changed) below.
|
||||||
*/
|
*/
|
||||||
to_dir.mark_as_updated();
|
to_dir->mark_as_updated();
|
||||||
open_to_dir_node.mark_as_written();
|
open_to_dir_node.mark_as_written();
|
||||||
to_dir.notify_listeners();
|
to_dir->notify_listeners();
|
||||||
|
|
||||||
from_dir.mark_as_updated();
|
from_dir->mark_as_updated();
|
||||||
open_from_dir_node.mark_as_written();
|
open_from_dir_node.mark_as_written();
|
||||||
from_dir.notify_listeners();
|
from_dir->notify_listeners();
|
||||||
|
|
||||||
node->mark_as_updated();
|
node->mark_as_updated();
|
||||||
node->notify_listeners();
|
node->notify_listeners();
|
||||||
|
@ -29,7 +29,8 @@ namespace Ram_fs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Ram_fs::Node : public File_system::Node_base, public List<Node>::Element
|
class Ram_fs::Node : public File_system::Node_base, public Weak_object<Node>,
|
||||||
|
public List<Node>::Element
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -56,6 +57,8 @@ class Ram_fs::Node : public File_system::Node_base, public List<Node>::Element
|
|||||||
: _ref_count(0), _inode(_unique_inode())
|
: _ref_count(0), _inode(_unique_inode())
|
||||||
{ _name[0] = 0; }
|
{ _name[0] = 0; }
|
||||||
|
|
||||||
|
virtual ~Node() { lock_for_destruction(); }
|
||||||
|
|
||||||
unsigned long inode() const { return _inode; }
|
unsigned long inode() const { return _inode; }
|
||||||
char const *name() const { return _name; }
|
char const *name() const { return _name; }
|
||||||
|
|
||||||
|
@ -658,22 +658,36 @@ class Trace_fs::Session_component : public Session_rpc_object
|
|||||||
switch (packet.operation()) {
|
switch (packet.operation()) {
|
||||||
|
|
||||||
case Packet_descriptor::READ:
|
case Packet_descriptor::READ:
|
||||||
if (content && (packet.length() <= packet.size()))
|
if (content && (packet.length() <= packet.size())) {
|
||||||
res_length = open_node.node().read((char *)content, length, packet.position());
|
Locked_ptr<Node> node { open_node.node() };
|
||||||
|
if (!node.valid())
|
||||||
|
break;
|
||||||
|
res_length = node->read((char *)content, length, packet.position());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Packet_descriptor::WRITE:
|
case Packet_descriptor::WRITE:
|
||||||
if (content && (packet.length() <= packet.size()))
|
if (content && (packet.length() <= packet.size())) {
|
||||||
res_length = open_node.node().write((char const *)content, length, packet.position());
|
Locked_ptr<Node> node { open_node.node() };
|
||||||
|
if (!node.valid())
|
||||||
|
break;
|
||||||
|
res_length = node->write((char const *)content, length, packet.position());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Packet_descriptor::CONTENT_CHANGED:
|
case Packet_descriptor::CONTENT_CHANGED: {
|
||||||
open_node.register_notify(*tx_sink());
|
open_node.register_notify(*tx_sink());
|
||||||
|
|
||||||
/* notify_listeners may bounce the packet back*/
|
/* notify_listeners may bounce the packet back*/
|
||||||
open_node.node().notify_listeners();
|
Locked_ptr<Node> node { open_node.node() };
|
||||||
|
if (!node.valid())
|
||||||
|
return;
|
||||||
|
node->notify_listeners();
|
||||||
|
|
||||||
/* otherwise defer acknowledgement of this packet */
|
/* otherwise defer acknowledgement of this packet */
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case Packet_descriptor::READ_READY:
|
case Packet_descriptor::READ_READY:
|
||||||
/* not supported */
|
/* not supported */
|
||||||
break;
|
break;
|
||||||
@ -824,17 +838,20 @@ class Trace_fs::Session_component : public Session_rpc_object
|
|||||||
|
|
||||||
auto file_fn = [&] (Open_node &open_node) {
|
auto file_fn = [&] (Open_node &open_node) {
|
||||||
|
|
||||||
Node &dir = open_node.node();
|
Locked_ptr<Node> dir { open_node.node() };
|
||||||
|
|
||||||
|
if (!dir.valid())
|
||||||
|
throw Invalid_handle();
|
||||||
|
|
||||||
if (create)
|
if (create)
|
||||||
throw Permission_denied();
|
throw Permission_denied();
|
||||||
|
|
||||||
File *file = dynamic_cast<File*>(dir.lookup(name.string()));
|
File *file = dynamic_cast<File*>(dir->lookup(name.string()));
|
||||||
if (!file)
|
if (!file)
|
||||||
throw Invalid_name();
|
throw Invalid_name();
|
||||||
|
|
||||||
Open_node *open_file =
|
Open_node *open_file =
|
||||||
new (_md_alloc) Open_node(*file, _open_node_registry);
|
new (_md_alloc) Open_node(file->weak_ptr(), _open_node_registry);
|
||||||
|
|
||||||
return open_file->id();
|
return open_file->id();
|
||||||
};
|
};
|
||||||
@ -871,7 +888,7 @@ class Trace_fs::Session_component : public Session_rpc_object
|
|||||||
throw Invalid_name();
|
throw Invalid_name();
|
||||||
|
|
||||||
Open_node *open_dir =
|
Open_node *open_dir =
|
||||||
new (_md_alloc) Open_node(*dir, _open_node_registry);
|
new (_md_alloc) Open_node(dir->weak_ptr(), _open_node_registry);
|
||||||
|
|
||||||
return Dir_handle { open_dir->id().value };
|
return Dir_handle { open_dir->id().value };
|
||||||
}
|
}
|
||||||
@ -885,7 +902,7 @@ class Trace_fs::Session_component : public Session_rpc_object
|
|||||||
Node *node = _root_dir.lookup(path_str + 1);
|
Node *node = _root_dir.lookup(path_str + 1);
|
||||||
|
|
||||||
Open_node *open_node =
|
Open_node *open_node =
|
||||||
new (_md_alloc) Open_node(*node, _open_node_registry);
|
new (_md_alloc) Open_node(node->weak_ptr(), _open_node_registry);
|
||||||
|
|
||||||
return open_node->id();
|
return open_node->id();
|
||||||
}
|
}
|
||||||
@ -894,26 +911,29 @@ class Trace_fs::Session_component : public Session_rpc_object
|
|||||||
{
|
{
|
||||||
auto close_fn = [&] (Open_node &open_node) {
|
auto close_fn = [&] (Open_node &open_node) {
|
||||||
|
|
||||||
Node &node = open_node.node();
|
Locked_ptr<Node> node { open_node.node() };
|
||||||
|
|
||||||
|
if (!node.valid())
|
||||||
|
throw Invalid_handle();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Acknowledge the change of the content of files which may be
|
* Acknowledge the change of the content of files which may be
|
||||||
* modified by the user of the file system.
|
* modified by the user of the file system.
|
||||||
*/
|
*/
|
||||||
Changeable_content *changeable = dynamic_cast<Changeable_content*>(&node);
|
Changeable_content *changeable = dynamic_cast<Changeable_content*>(&*node);
|
||||||
if (changeable) {
|
if (changeable) {
|
||||||
if (changeable->changed()) {
|
if (changeable->changed()) {
|
||||||
changeable->acknowledge_change();
|
changeable->acknowledge_change();
|
||||||
|
|
||||||
/* let the trace fs perform the provoked actions */
|
/* let the trace fs perform the provoked actions */
|
||||||
_trace_fs->handle_changed_node(&node);
|
_trace_fs->handle_changed_node(&*node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Notify listeners about the changed file.
|
* Notify listeners about the changed file.
|
||||||
*/
|
*/
|
||||||
node.notify_listeners();
|
node->notify_listeners();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* De-allocate handle
|
* De-allocate handle
|
||||||
@ -931,7 +951,10 @@ class Trace_fs::Session_component : public Session_rpc_object
|
|||||||
Status status(Node_handle node_handle)
|
Status status(Node_handle node_handle)
|
||||||
{
|
{
|
||||||
auto status_fn = [&] (Open_node &open_node) {
|
auto status_fn = [&] (Open_node &open_node) {
|
||||||
return open_node.node().status();
|
Locked_ptr<Node> node { open_node.node() };
|
||||||
|
if (!node.valid())
|
||||||
|
throw Invalid_handle();
|
||||||
|
return node->status();
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -947,7 +970,10 @@ class Trace_fs::Session_component : public Session_rpc_object
|
|||||||
void truncate(File_handle handle, file_size_t size)
|
void truncate(File_handle handle, file_size_t size)
|
||||||
{
|
{
|
||||||
auto truncate_fn = [&] (Open_node &open_node) {
|
auto truncate_fn = [&] (Open_node &open_node) {
|
||||||
open_node.node().truncate(size);
|
Locked_ptr<Node> node { open_node.node() };
|
||||||
|
if (!node.valid())
|
||||||
|
throw Invalid_handle();
|
||||||
|
node->truncate(size);
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -26,7 +26,8 @@ namespace Trace_fs {
|
|||||||
class Node;
|
class Node;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Trace_fs::Node : public Node_base, public List<Node>::Element
|
class Trace_fs::Node : public Node_base, public Weak_object<Node>,
|
||||||
|
public List<Node>::Element
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -52,6 +53,8 @@ class Trace_fs::Node : public Node_base, public List<Node>::Element
|
|||||||
: _inode(_unique_inode())
|
: _inode(_unique_inode())
|
||||||
{ _name[0] = 0; }
|
{ _name[0] = 0; }
|
||||||
|
|
||||||
|
virtual ~Node() { lock_for_destruction(); }
|
||||||
|
|
||||||
unsigned long inode() const { return _inode; }
|
unsigned long inode() const { return _inode; }
|
||||||
char const *name() const { return _name; }
|
char const *name() const { return _name; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user