vfs: add modification time member to directory_service

Issue #1784.
This commit is contained in:
Josef Söntgen 2019-03-20 15:01:34 +01:00 committed by Christian Helmuth
parent 400039e1b6
commit 9a82bbb54d
7 changed files with 117 additions and 1 deletions

View File

@ -91,6 +91,8 @@ class Vfs::Rump_file_system : public File_system
Genode::error("Rump_vfs_handle::write() called");
return WRITE_ERR_INVALID;
}
virtual void update_modification_timestamp(Vfs::Timestamp) { }
};
class Rump_vfs_file_handle :
@ -163,6 +165,17 @@ class Vfs::Rump_file_system : public File_system
out_count = n;
return WRITE_OK;
}
void update_modification_timestamp(Vfs::Timestamp time) override
{
struct timespec ts[2] = {
{ .tv_sec = 0, .tv_nsec = 0 },
{ .tv_sec = time.value, .tv_nsec = 0 }
};
/* silently igore error */
rump_sys_futimens(_fd, (const timespec*)&ts);
}
};
class Rump_vfs_dir_handle : public Rump_vfs_handle
@ -806,6 +819,12 @@ class Vfs::Rump_file_system : public File_system
_notify_files();
return SYNC_OK;
}
bool update_modification_timestamp(Vfs_handle *vfs_handle,
Vfs::Timestamp ts)
{
return true;
}
};

View File

@ -462,6 +462,7 @@ class Vfs::Dir_file_system : public File_system
out.gid = 0;
out.inode = 1;
out.device = (Genode::addr_t)this;
out.modification_time = { Vfs::Timestamp::INVALID };
return STAT_OK;
}

View File

@ -160,6 +160,7 @@ struct Vfs::Directory_service : Interface
unsigned gid = 0;
unsigned long inode = 0;
unsigned long device = 0;
Timestamp modification_time { Timestamp::INVALID };
};
enum Stat_result { STAT_ERR_NO_ENTRY = NUM_GENERAL_ERRORS,

View File

@ -172,6 +172,20 @@ struct Vfs::File_io_service : Interface
virtual bool queue_sync(Vfs_handle *) { return true; }
virtual Sync_result complete_sync(Vfs_handle *) { return SYNC_OK; }
/***********************
** Modification time **
***********************/
/**
* Update the modification time of a file
*
* \return true if update attempt was successful
*/
virtual bool update_modification_timestamp(Vfs_handle *, Vfs::Timestamp)
{
return true;
}
};
#endif /* _INCLUDE__VFS__FILE_IO_SERVICE_H_ */

View File

@ -49,6 +49,12 @@ namespace Vfs {
using Genode::Interface;
using Genode::String;
struct Timestamp
{
static constexpr long long INVALID = (1LL << 63) + 1;
long long value;
};
typedef Genode::Path<MAX_PATH_LEN> Absolute_path;
}

View File

@ -225,6 +225,35 @@ class Vfs::Fs_file_system : public File_system
return result;
}
bool update_modification_timestamp(Vfs::Timestamp time)
{
::File_system::Session::Tx::Source &source = *_fs.tx();
using ::File_system::Packet_descriptor;
if (!source.ready_to_submit()) {
Genode::error(__func__, ":", __LINE__, " Insufficient_buffer");
return false;
}
try {
Packet_descriptor p(source.alloc_packet(0),
file_handle(),
Packet_descriptor::WRITE_TIMESTAMP,
::File_system::Timestamp { .value = time.value });
/* pass packet to server side */
source.submit_packet(p);
} catch (::File_system::Session::Tx::Source::Packet_alloc_failed) {
Genode::error(__func__, ":", __LINE__, " Insufficient_buffer");
return false;
} catch (...) {
Genode::error("unhandled exception");
return false;
}
return true;
}
};
struct Fs_vfs_file_handle : Fs_vfs_handle
@ -517,6 +546,10 @@ class Vfs::Fs_file_system : public File_system
case Packet_descriptor::CONTENT_CHANGED:
/* previously handled */
break;
case Packet_descriptor::WRITE_TIMESTAMP:
/* previously handled */
break;
}
};
@ -535,6 +568,11 @@ class Vfs::Fs_file_system : public File_system
Lock::Guard guard(_lock);
source.release_packet(packet);
}
if (packet.operation() == Packet_descriptor::WRITE_TIMESTAMP) {
Lock::Guard guard(_lock);
source.release_packet(packet);
}
}
}
@ -621,6 +659,7 @@ class Vfs::Fs_file_system : public File_system
out.gid = 0;
out.inode = status.inode;
out.device = (Genode::addr_t)this;
out.modification_time.value = status.modification_time.value;
return STAT_OK;
}
@ -1011,6 +1050,15 @@ class Vfs::Fs_file_system : public File_system
return handle->complete_sync();
}
bool update_modification_timestamp(Vfs_handle *vfs_handle, Vfs::Timestamp time) override
{
Lock::Guard guard(_lock);
Fs_vfs_handle *handle = static_cast<Fs_vfs_handle *>(vfs_handle);
return handle->update_modification_timestamp(time);
}
};
#endif /* _INCLUDE__VFS__FS_FILE_SYSTEM_H_ */

View File

@ -119,6 +119,8 @@ class Vfs_ram::Node : private Genode::Avl_node<Node>, private Genode::Lock
return ++inode_count;
}
Vfs::Timestamp _modification_time { Vfs::Timestamp::INVALID };
public:
using Lock::lock;
@ -127,7 +129,10 @@ class Vfs_ram::Node : private Genode::Avl_node<Node>, private Genode::Lock
unsigned inode;
Node(char const *node_name)
: inode(_unique_inode()) { name(node_name); }
: inode(_unique_inode())
{
name(node_name);
}
virtual ~Node() { }
@ -156,6 +161,14 @@ class Vfs_ram::Node : private Genode::Avl_node<Node>, private Genode::Lock
void unlink() { inode = 0; }
bool unlinked() const { return inode == 0; }
bool update_modification_timestamp(Vfs::Timestamp time)
{
_modification_time = time;
return true;
}
Vfs::Timestamp modification_time() const { return _modification_time; }
virtual size_t read(char*, size_t, file_size)
{
Genode::error("Vfs_ram::Node::read() called");
@ -774,6 +787,7 @@ class Vfs::Ram_file_system : public Vfs::File_system
stat.size = node->length();
stat.inode = node->inode;
stat.device = (Genode::addr_t)this;
stat.modification_time = node->modification_time();
File *file = dynamic_cast<File *>(node);
if (file) {
@ -1004,6 +1018,19 @@ class Vfs::Ram_file_system : public Vfs::File_system
return SYNC_OK;
}
bool update_modification_timestamp(Vfs_handle *vfs_handle, Vfs::Timestamp time) override
{
if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY)
return false;
Vfs_ram::Io_handle *handle =
static_cast<Vfs_ram::Io_handle *>(vfs_handle);
handle->modifying = true;
Vfs_ram::Node::Guard guard(&handle->node);
return handle->node.update_modification_timestamp(time);
}
/***************************
** File_system interface **
***************************/