file_system_session: add modification time
* add modification_time member * add WRITE_TIMESTAMP packet
This commit is contained in:
parent
ab5187d673
commit
2ec3aaf639
|
@ -71,6 +71,26 @@ namespace File_system {
|
||||||
typedef Genode::uint64_t seek_off_t;
|
typedef Genode::uint64_t seek_off_t;
|
||||||
typedef Genode::uint64_t file_size_t;
|
typedef Genode::uint64_t file_size_t;
|
||||||
|
|
||||||
|
struct Timestamp
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The INVALID value is used whenever the underlying file system
|
||||||
|
* session does not support modification timestamps. The value is
|
||||||
|
* chosen such that it is unlikely to occur, instead of simply '0',
|
||||||
|
* which would correspond to plausible time (see comment below).
|
||||||
|
* This allows for handling this case explicitly. In any case, an
|
||||||
|
* invalid timestamp should not be used for doing any calculations.
|
||||||
|
*/
|
||||||
|
static constexpr Genode::int64_t INVALID = 0x7fffffffffffffffLL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 'value' member contains the modification timestamp in seconds.
|
||||||
|
* Value '0' is defined as 1970-01-01T00:00:00Z, where a positive value
|
||||||
|
* covers all seconds after this date and a negative one all before.
|
||||||
|
*/
|
||||||
|
Genode::int64_t value;
|
||||||
|
};
|
||||||
|
|
||||||
typedef Genode::Out_of_ram Out_of_ram;
|
typedef Genode::Out_of_ram Out_of_ram;
|
||||||
typedef Genode::Out_of_caps Out_of_caps;
|
typedef Genode::Out_of_caps Out_of_caps;
|
||||||
|
|
||||||
|
@ -127,6 +147,7 @@ class File_system::Packet_descriptor : public Genode::Packet_descriptor
|
||||||
enum Opcode {
|
enum Opcode {
|
||||||
READ,
|
READ,
|
||||||
WRITE,
|
WRITE,
|
||||||
|
WRITE_TIMESTAMP,
|
||||||
CONTENT_CHANGED,
|
CONTENT_CHANGED,
|
||||||
READ_READY,
|
READ_READY,
|
||||||
|
|
||||||
|
@ -143,9 +164,16 @@ class File_system::Packet_descriptor : public Genode::Packet_descriptor
|
||||||
|
|
||||||
Node_handle _handle { 0 }; /* node handle */
|
Node_handle _handle { 0 }; /* node handle */
|
||||||
Opcode _op; /* requested operation */
|
Opcode _op; /* requested operation */
|
||||||
seek_off_t _position; /* file seek offset in bytes */
|
|
||||||
size_t _length; /* transaction length in bytes */
|
|
||||||
bool _success; /* indicates success of operation */
|
bool _success; /* indicates success of operation */
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
seek_off_t _position; /* file seek offset in bytes */
|
||||||
|
size_t _length; /* transaction length in bytes */
|
||||||
|
};
|
||||||
|
Timestamp _modification_time; /* seconds since the Unix epoch */
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -156,7 +184,7 @@ class File_system::Packet_descriptor : public Genode::Packet_descriptor
|
||||||
Genode::size_t buf_size = 0)
|
Genode::size_t buf_size = 0)
|
||||||
:
|
:
|
||||||
Genode::Packet_descriptor(buf_offset, buf_size),
|
Genode::Packet_descriptor(buf_offset, buf_size),
|
||||||
_op(READ), _position(0), _length(0), _success(false) { }
|
_op(READ), _success(false), _position(0), _length(0) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -172,8 +200,8 @@ class File_system::Packet_descriptor : public Genode::Packet_descriptor
|
||||||
seek_off_t position = SEEK_TAIL)
|
seek_off_t position = SEEK_TAIL)
|
||||||
:
|
:
|
||||||
Genode::Packet_descriptor(p.offset(), p.size()),
|
Genode::Packet_descriptor(p.offset(), p.size()),
|
||||||
_handle(handle), _op(op),
|
_handle(handle), _op(op), _success(false),
|
||||||
_position(position), _length(length), _success(false)
|
_position(position), _length(length)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -185,16 +213,33 @@ class File_system::Packet_descriptor : public Genode::Packet_descriptor
|
||||||
Packet_descriptor(Node_handle handle, Opcode op)
|
Packet_descriptor(Node_handle handle, Opcode op)
|
||||||
:
|
:
|
||||||
Genode::Packet_descriptor(0, 0),
|
Genode::Packet_descriptor(0, 0),
|
||||||
_handle(handle), _op(op),
|
_handle(handle), _op(op), _success(true),
|
||||||
_position(0), _length(0), _success(true)
|
_position(0), _length(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
Packet_descriptor(Packet_descriptor p, Node_handle handle, Opcode op, Timestamp const &mtime)
|
||||||
|
:
|
||||||
|
Genode::Packet_descriptor(p.offset(), p.size()),
|
||||||
|
_handle(handle), _op(op), _success(false),
|
||||||
|
_modification_time(mtime)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Node_handle handle() const { return _handle; }
|
Node_handle handle() const { return _handle; }
|
||||||
Opcode operation() const { return _op; }
|
Opcode operation() const { return _op; }
|
||||||
seek_off_t position() const { return _position; }
|
seek_off_t position() const { return _op != Opcode::WRITE_TIMESTAMP ? _position : 0; }
|
||||||
size_t length() const { return _length; }
|
size_t length() const { return _op != Opcode::WRITE_TIMESTAMP ? _length : 0; }
|
||||||
bool succeeded() const { return _success; }
|
bool succeeded() const { return _success; }
|
||||||
|
|
||||||
|
template <typename FN>
|
||||||
|
void with_timestamp(FN const &fn) const
|
||||||
|
{
|
||||||
|
if (_op == Opcode::WRITE_TIMESTAMP)
|
||||||
|
fn(_modification_time);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Accessors called at the server side
|
* Accessors called at the server side
|
||||||
*/
|
*/
|
||||||
|
@ -212,13 +257,13 @@ struct File_system::Status
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX add access time
|
|
||||||
* XXX add executable bit
|
* XXX add executable bit
|
||||||
*/
|
*/
|
||||||
|
|
||||||
file_size_t size;
|
file_size_t size;
|
||||||
unsigned mode;
|
unsigned mode;
|
||||||
unsigned long inode;
|
unsigned long inode;
|
||||||
|
Timestamp modification_time;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if node is a directory
|
* Return true if node is a directory
|
||||||
|
|
|
@ -228,6 +228,7 @@ class Ram_fs::Directory : public Node
|
||||||
s.inode = inode();
|
s.inode = inode();
|
||||||
s.size = _num_entries * sizeof(File_system::Directory_entry);
|
s.size = _num_entries * sizeof(File_system::Directory_entry);
|
||||||
s.mode = File_system::Status::MODE_DIRECTORY;
|
s.mode = File_system::Status::MODE_DIRECTORY;
|
||||||
|
s.modification_time = modification_time();
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -112,10 +112,11 @@ class Ram_fs::File : public Node
|
||||||
|
|
||||||
Status status() override
|
Status status() override
|
||||||
{
|
{
|
||||||
Status s;
|
Status s { };
|
||||||
s.inode = inode();
|
s.inode = inode();
|
||||||
s.size = _length;
|
s.size = _length;
|
||||||
s.mode = File_system::Status::MODE_FILE;
|
s.mode = File_system::Status::MODE_FILE;
|
||||||
|
s.modification_time = modification_time();
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,18 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
||||||
open_node.mark_as_written();
|
open_node.mark_as_written();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Packet_descriptor::WRITE_TIMESTAMP: {
|
||||||
|
Locked_ptr<Node> node { open_node.node() };
|
||||||
|
if (!node.valid())
|
||||||
|
break;
|
||||||
|
|
||||||
|
packet.with_timestamp([&] (File_system::Timestamp const time) {
|
||||||
|
node->update_modification_time(time);
|
||||||
|
succeeded = true;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Packet_descriptor::CONTENT_CHANGED:
|
case Packet_descriptor::CONTENT_CHANGED:
|
||||||
Genode::error("CONTENT_CHANGED packets from clients have no effect");
|
Genode::error("CONTENT_CHANGED packets from clients have no effect");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace Ram_fs {
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
using File_system::seek_off_t;
|
using File_system::seek_off_t;
|
||||||
using File_system::Status;
|
using File_system::Status;
|
||||||
|
using File_system::Timestamp;
|
||||||
class Node;
|
class Node;
|
||||||
class File;
|
class File;
|
||||||
class Symlink;
|
class Symlink;
|
||||||
|
@ -48,6 +49,7 @@ class Ram_fs::Node : public File_system::Node_base,
|
||||||
int _ref_count;
|
int _ref_count;
|
||||||
Name _name;
|
Name _name;
|
||||||
unsigned long const _inode;
|
unsigned long const _inode;
|
||||||
|
Timestamp _modification_time { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate unique inode number
|
* Generate unique inode number
|
||||||
|
@ -62,7 +64,10 @@ class Ram_fs::Node : public File_system::Node_base,
|
||||||
|
|
||||||
Node()
|
Node()
|
||||||
: _ref_count(0), _inode(_unique_inode())
|
: _ref_count(0), _inode(_unique_inode())
|
||||||
{ _name[0] = 0; }
|
{
|
||||||
|
_name[0] = 0;
|
||||||
|
_modification_time.value = File_system::Timestamp::INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~Node() { lock_for_destruction(); }
|
virtual ~Node() { lock_for_destruction(); }
|
||||||
|
|
||||||
|
@ -74,6 +79,13 @@ class Ram_fs::Node : public File_system::Node_base,
|
||||||
*/
|
*/
|
||||||
void name(char const *name) { strncpy(_name, name, sizeof(_name)); }
|
void name(char const *name) { strncpy(_name, name, sizeof(_name)); }
|
||||||
|
|
||||||
|
void update_modification_time(Timestamp const time)
|
||||||
|
{
|
||||||
|
_modification_time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
Timestamp modification_time() const { return _modification_time; }
|
||||||
|
|
||||||
virtual size_t read(char *dst, size_t len, seek_off_t) = 0;
|
virtual size_t read(char *dst, size_t len, seek_off_t) = 0;
|
||||||
virtual size_t write(char const *src, size_t len, seek_off_t) = 0;
|
virtual size_t write(char const *src, size_t len, seek_off_t) = 0;
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ class Ram_fs::Symlink : public Node
|
||||||
s.inode = inode();
|
s.inode = inode();
|
||||||
s.size = _len;
|
s.size = _len;
|
||||||
s.mode = File_system::Status::MODE_SYMLINK;
|
s.mode = File_system::Status::MODE_SYMLINK;
|
||||||
|
s.modification_time = modification_time();
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user