mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
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 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_caps Out_of_caps;
|
||||
|
||||
@ -127,6 +147,7 @@ class File_system::Packet_descriptor : public Genode::Packet_descriptor
|
||||
enum Opcode {
|
||||
READ,
|
||||
WRITE,
|
||||
WRITE_TIMESTAMP,
|
||||
CONTENT_CHANGED,
|
||||
READ_READY,
|
||||
|
||||
@ -143,9 +164,16 @@ class File_system::Packet_descriptor : public Genode::Packet_descriptor
|
||||
|
||||
Node_handle _handle { 0 }; /* node handle */
|
||||
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 */
|
||||
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:
|
||||
|
||||
@ -156,7 +184,7 @@ class File_system::Packet_descriptor : public Genode::Packet_descriptor
|
||||
Genode::size_t buf_size = 0)
|
||||
:
|
||||
Genode::Packet_descriptor(buf_offset, buf_size),
|
||||
_op(READ), _position(0), _length(0), _success(false) { }
|
||||
_op(READ), _success(false), _position(0), _length(0) { }
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -172,8 +200,8 @@ class File_system::Packet_descriptor : public Genode::Packet_descriptor
|
||||
seek_off_t position = SEEK_TAIL)
|
||||
:
|
||||
Genode::Packet_descriptor(p.offset(), p.size()),
|
||||
_handle(handle), _op(op),
|
||||
_position(position), _length(length), _success(false)
|
||||
_handle(handle), _op(op), _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)
|
||||
:
|
||||
Genode::Packet_descriptor(0, 0),
|
||||
_handle(handle), _op(op),
|
||||
_position(0), _length(0), _success(true)
|
||||
_handle(handle), _op(op), _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; }
|
||||
Opcode operation() const { return _op; }
|
||||
seek_off_t position() const { return _position; }
|
||||
size_t length() const { return _length; }
|
||||
seek_off_t position() const { return _op != Opcode::WRITE_TIMESTAMP ? _position : 0; }
|
||||
size_t length() const { return _op != Opcode::WRITE_TIMESTAMP ? _length : 0; }
|
||||
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
|
||||
*/
|
||||
@ -212,13 +257,13 @@ struct File_system::Status
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX add access time
|
||||
* XXX add executable bit
|
||||
*/
|
||||
|
||||
file_size_t size;
|
||||
unsigned mode;
|
||||
unsigned long inode;
|
||||
Timestamp modification_time;
|
||||
|
||||
/**
|
||||
* Return true if node is a directory
|
||||
|
@ -228,6 +228,7 @@ class Ram_fs::Directory : public Node
|
||||
s.inode = inode();
|
||||
s.size = _num_entries * sizeof(File_system::Directory_entry);
|
||||
s.mode = File_system::Status::MODE_DIRECTORY;
|
||||
s.modification_time = modification_time();
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
@ -112,10 +112,11 @@ class Ram_fs::File : public Node
|
||||
|
||||
Status status() override
|
||||
{
|
||||
Status s;
|
||||
Status s { };
|
||||
s.inode = inode();
|
||||
s.size = _length;
|
||||
s.mode = File_system::Status::MODE_FILE;
|
||||
s.modification_time = modification_time();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -108,6 +108,18 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
|
||||
open_node.mark_as_written();
|
||||
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:
|
||||
Genode::error("CONTENT_CHANGED packets from clients have no effect");
|
||||
return;
|
||||
|
@ -23,6 +23,7 @@ namespace Ram_fs {
|
||||
using namespace Genode;
|
||||
using File_system::seek_off_t;
|
||||
using File_system::Status;
|
||||
using File_system::Timestamp;
|
||||
class Node;
|
||||
class File;
|
||||
class Symlink;
|
||||
@ -48,6 +49,7 @@ class Ram_fs::Node : public File_system::Node_base,
|
||||
int _ref_count;
|
||||
Name _name;
|
||||
unsigned long const _inode;
|
||||
Timestamp _modification_time { };
|
||||
|
||||
/**
|
||||
* Generate unique inode number
|
||||
@ -62,7 +64,10 @@ class Ram_fs::Node : public File_system::Node_base,
|
||||
|
||||
Node()
|
||||
: _ref_count(0), _inode(_unique_inode())
|
||||
{ _name[0] = 0; }
|
||||
{
|
||||
_name[0] = 0;
|
||||
_modification_time.value = File_system::Timestamp::INVALID;
|
||||
}
|
||||
|
||||
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 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 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.size = _len;
|
||||
s.mode = File_system::Status::MODE_SYMLINK;
|
||||
s.modification_time = modification_time();
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user