diff --git a/repos/os/src/server/lx_fs/directory.h b/repos/os/src/server/lx_fs/directory.h index a71c1fca9..eefbf8eda 100644 --- a/repos/os/src/server/lx_fs/directory.h +++ b/repos/os/src/server/lx_fs/directory.h @@ -114,6 +114,17 @@ class Lx_fs::Directory : public Node closedir(_fd); } + void update_modification_time(Timestamp const time) override + { + struct timespec ts[2] = { + { .tv_sec = (time_t)0, .tv_nsec = 0 }, + { .tv_sec = (time_t)time.value, .tv_nsec = 0 } + }; + + /* silently ignore errors */ + futimens(dirfd(_fd), (const timespec*)&ts); + } + void rename(Directory &dir_to, char const *name_from, char const *name_to) { int ret = renameat(dirfd(_fd), name_from, @@ -217,10 +228,17 @@ class Lx_fs::Directory : public Node Status status() override { + struct stat st; + + int fd = dirfd(_fd); + if (fd == -1 || fstat(fd, &st) < 0) + st.st_mtime = 0; + Status s; s.inode = inode(); s.size = _num_entries() * sizeof(File_system::Directory_entry); s.mode = File_system::Status::MODE_DIRECTORY; + s.modification_time = { st.st_mtime }; return s; } }; diff --git a/repos/os/src/server/lx_fs/file.h b/repos/os/src/server/lx_fs/file.h index 0e4921a47..db33dd143 100644 --- a/repos/os/src/server/lx_fs/file.h +++ b/repos/os/src/server/lx_fs/file.h @@ -82,16 +82,6 @@ class Lx_fs::File : public Node return fd; } - file_size_t _length() const - { - struct stat s; - - if (fstat(_fd, &s) < 0) - return 0; - - return s.st_size; - } - public: File(int dir, @@ -118,6 +108,17 @@ class Lx_fs::File : public Node close(_fd); } + void update_modification_time(Timestamp const time) override + { + struct timespec ts[2] = { + { .tv_sec = (time_t)0, .tv_nsec = 0 }, + { .tv_sec = (time_t)time.value, .tv_nsec = 0 } + }; + + /* silently ignore errors */ + futimens(_fd, (const timespec*)&ts); + } + size_t read(char *dst, size_t len, seek_off_t seek_offset) override { int ret = pread(_fd, dst, len, seek_offset); @@ -142,10 +143,18 @@ class Lx_fs::File : public Node Status status() override { + struct stat st; + + if (fstat(_fd, &st) < 0) { + st.st_size = 0; + st.st_mtime = 0; + } + Status s; s.inode = inode(); - s.size = _length(); + s.size = st.st_size; s.mode = File_system::Status::MODE_FILE; + s.modification_time = { st.st_mtime }; return s; } diff --git a/repos/os/src/server/lx_fs/main.cc b/repos/os/src/server/lx_fs/main.cc index 77ac945a4..6c0373a58 100644 --- a/repos/os/src/server/lx_fs/main.cc +++ b/repos/os/src/server/lx_fs/main.cc @@ -97,6 +97,16 @@ class Lx_fs::Session_component : public Session_rpc_object } break; + case Packet_descriptor::WRITE_TIMESTAMP: + if (tx_sink()->packet_valid(packet) && (packet.length() <= packet.size())) { + + packet.with_timestamp([&] (File_system::Timestamp const time) { + open_node.node().update_modification_time(time); + succeeded = true; + }); + } + break; + case Packet_descriptor::CONTENT_CHANGED: open_node.register_notify(*tx_sink()); /* notify_listeners may bounce the packet back*/ diff --git a/repos/os/src/server/lx_fs/node.h b/repos/os/src/server/lx_fs/node.h index cacc610da..61e28f591 100644 --- a/repos/os/src/server/lx_fs/node.h +++ b/repos/os/src/server/lx_fs/node.h @@ -48,6 +48,8 @@ class Lx_fs::Node : public File_system::Node_base */ void name(char const *name) { Genode::strncpy(_name, name, sizeof(_name)); } + virtual void update_modification_time(Timestamp const) = 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;