mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 02:40:08 +00:00
parent
400039e1b6
commit
9a82bbb54d
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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_ */
|
||||
|
@ -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 **
|
||||
***************************/
|
||||
|
Loading…
Reference in New Issue
Block a user