diff --git a/repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc b/repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc index f45e8d54c1..3df9e29dfc 100644 --- a/repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc +++ b/repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc @@ -171,8 +171,13 @@ class Vfs::Rump_file_system : public File_system 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 } + { + .tv_sec = 0, + .tv_nsec = 0 + }, { + .tv_sec = time_t( time.ms_since_1970 / 1000), + .tv_nsec = time_t((time.ms_since_1970 % 1000)*1000*1000) + } }; /* silently igore error */ @@ -726,7 +731,9 @@ class Vfs::Rump_file_system : public File_system .inode = sb.st_ino, .device = sb.st_dev, - .modification_time = { sb.st_mtim.tv_sec } + .modification_time = { + .ms_since_1970 = uint64_t(sb.st_mtim.tv_sec*1000 + + sb.st_mtim.tv_nsec/1000000) } }; return STAT_OK; diff --git a/repos/libports/src/lib/libc/vfs_plugin.cc b/repos/libports/src/lib/libc/vfs_plugin.cc index d51db16ec4..bb33c597be 100644 --- a/repos/libports/src/lib/libc/vfs_plugin.cc +++ b/repos/libports/src/lib/libc/vfs_plugin.cc @@ -118,6 +118,10 @@ static void vfs_stat_to_libc_stat_struct(Vfs::Directory_service::Stat const &src *dst = { }; + timespec const mtime { + .tv_sec = time_t( src.modification_time.ms_since_1970 / 1000), + .tv_nsec = time_t((src.modification_time.ms_since_1970 % 1000)*1000*1000) }; + dst->st_uid = 0; dst->st_gid = 0; dst->st_mode = (src.rwx.readable ? readable_bits : 0) @@ -129,8 +133,7 @@ static void vfs_stat_to_libc_stat_struct(Vfs::Directory_service::Stat const &src dst->st_blocks = (dst->st_size + FS_BLOCK_SIZE - 1) / FS_BLOCK_SIZE; dst->st_ino = src.inode; dst->st_dev = src.device; - long long mtime = src.modification_time.value; - dst->st_mtime = mtime != Vfs::Timestamp::INVALID ? mtime : 0; + dst->st_mtim = mtime; dst->st_nlink = 1; } @@ -546,7 +549,7 @@ struct Sync enum { INITIAL, TIMESTAMP_UPDATED, QUEUED, COMPLETE } state { INITIAL }; Vfs::Vfs_handle &vfs_handle; - Vfs::Timestamp mtime { Vfs::Timestamp::INVALID }; + Vfs::Timestamp mtime { }; Sync(Vfs::Vfs_handle &vfs_handle, Libc::Vfs_plugin::Update_mtime update_mtime, Libc::Current_real_time ¤t_real_time) @@ -561,7 +564,9 @@ struct Sync } else { timespec const ts = current_real_time.current_real_time(); - mtime = { .value = (long long)ts.tv_sec }; + mtime.ms_since_1970 = ts.tv_sec >= 0 + ? ts.tv_sec*1000ull + ts.tv_nsec/1000000ull + : 0; } } diff --git a/repos/os/include/file_system_session/file_system_session.h b/repos/os/include/file_system_session/file_system_session.h index 29a8d1a8aa..285f771aab 100644 --- a/repos/os/include/file_system_session/file_system_session.h +++ b/repos/os/include/file_system_session/file_system_session.h @@ -86,25 +86,7 @@ namespace File_system { using seek_off_t = Genode::uint64_t; using file_size_t = Genode::uint64_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; - }; + struct Timestamp { Genode::uint64_t ms_since_1970; }; using Out_of_ram = Genode::Out_of_ram; using Out_of_caps = Genode::Out_of_caps; diff --git a/repos/os/include/vfs/dir_file_system.h b/repos/os/include/vfs/dir_file_system.h index f4ce033265..107a490926 100644 --- a/repos/os/include/vfs/dir_file_system.h +++ b/repos/os/include/vfs/dir_file_system.h @@ -451,7 +451,7 @@ class Vfs::Dir_file_system : public File_system .rwx = Node_rwx::rwx(), .inode = 1, .device = (Genode::addr_t)this, - .modification_time = { Vfs::Timestamp::INVALID }, + .modification_time = { }, }; return STAT_OK; } diff --git a/repos/os/include/vfs/types.h b/repos/os/include/vfs/types.h index fa4b90158e..130a792a57 100644 --- a/repos/os/include/vfs/types.h +++ b/repos/os/include/vfs/types.h @@ -50,11 +50,7 @@ namespace Vfs { using Genode::Byte_range_ptr; using Genode::Const_byte_range_ptr; - struct Timestamp - { - static constexpr Genode::int64_t INVALID = 0x7fffffffffffffffLL; - Genode::int64_t value; - }; + struct Timestamp { Genode::uint64_t ms_since_1970; }; enum class Node_type { DIRECTORY, diff --git a/repos/os/src/lib/vfs/fs_file_system.h b/repos/os/src/lib/vfs/fs_file_system.h index 2d25cf153a..7e14f57905 100644 --- a/repos/os/src/lib/vfs/fs_file_system.h +++ b/repos/os/src/lib/vfs/fs_file_system.h @@ -300,7 +300,8 @@ class Vfs::Fs_file_system : public File_system, private Remote_io Packet_descriptor p(source.alloc_packet(0), file_handle(), Packet_descriptor::WRITE_TIMESTAMP, - ::File_system::Timestamp { .value = time.value }); + ::File_system::Timestamp { + .ms_since_1970 = time.ms_since_1970 }); _vfs_fs._submit_packet(p); } catch (::File_system::Session::Tx::Source::Packet_alloc_failed) { @@ -617,7 +618,8 @@ class Vfs::Fs_file_system : public File_system, private Remote_io out.rwx = _node_rwx(status.rwx); out.inode = status.inode; out.device = (Genode::addr_t)this; - out.modification_time.value = status.modification_time.value; + out.modification_time = { + .ms_since_1970 = status.modification_time.ms_since_1970 }; return STAT_OK; } diff --git a/repos/os/src/lib/vfs/ram_file_system.h b/repos/os/src/lib/vfs/ram_file_system.h index a1719ce09a..2a1a811c99 100644 --- a/repos/os/src/lib/vfs/ram_file_system.h +++ b/repos/os/src/lib/vfs/ram_file_system.h @@ -126,7 +126,7 @@ class Vfs_ram::Node : private Genode::Avl_node return ++inode_count; } - Vfs::Timestamp _modification_time { Vfs::Timestamp::INVALID }; + Vfs::Timestamp _modification_time { }; bool _marked_as_unlinked = false; diff --git a/repos/os/src/lib/vfs/tar_file_system.h b/repos/os/src/lib/vfs/tar_file_system.h index ebc1d3cc54..a2beefcf23 100644 --- a/repos/os/src/lib/vfs/tar_file_system.h +++ b/repos/os/src/lib/vfs/tar_file_system.h @@ -626,6 +626,11 @@ class Vfs::Tar_file_system : public File_system return Node_type::DIRECTORY; }; + auto timestamp_from_mtime = [] (auto mtime) -> Timestamp + { + return { .ms_since_1970 = mtime >= 0 ? Genode::uint64_t(mtime*1000) : 0 }; + }; + out = { .size = record.size(), .type = node_type(), @@ -634,7 +639,7 @@ class Vfs::Tar_file_system : public File_system .executable = record.rwx().executable }, .inode = (Genode::addr_t)node_ptr, .device = (Genode::addr_t)this, - .modification_time = { record.mtime() } + .modification_time = timestamp_from_mtime(record.mtime()) }; return STAT_OK; diff --git a/repos/os/src/server/lx_fs/directory.h b/repos/os/src/server/lx_fs/directory.h index d6f793afbe..bfad95d111 100644 --- a/repos/os/src/server/lx_fs/directory.h +++ b/repos/os/src/server/lx_fs/directory.h @@ -116,10 +116,7 @@ class Lx_fs::Directory : public Node 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 } - }; + struct timespec ts[2] = { { }, timespec_from_timestamp(time) }; /* silently ignore errors */ futimens(dirfd(_fd), (const timespec*)&ts); @@ -258,7 +255,7 @@ class Lx_fs::Directory : public Node .writeable = (st.st_mode & S_IWUSR) != 0, .executable = (st.st_mode & S_IXUSR) != 0}, .inode = (unsigned long)inode(), - .modification_time = { st.st_mtime } + .modification_time = timestamp_from_timespec(st.st_mtim) }; } diff --git a/repos/os/src/server/lx_fs/file.h b/repos/os/src/server/lx_fs/file.h index dfacbc1801..0c8edecbc1 100644 --- a/repos/os/src/server/lx_fs/file.h +++ b/repos/os/src/server/lx_fs/file.h @@ -114,10 +114,7 @@ class Lx_fs::File : public Node 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 } - }; + struct timespec ts[2] = { { }, timespec_from_timestamp(time) }; /* silently ignore errors */ futimens(_fd, (const timespec*)&ts); @@ -167,7 +164,7 @@ class Lx_fs::File : public Node .writeable = (st.st_mode & S_IWUSR) != 0, .executable = (st.st_mode & S_IXUSR) != 0}, .inode = (unsigned long)inode(), - .modification_time = { st.st_mtime } + .modification_time = timestamp_from_timespec(st.st_mtim) }; } diff --git a/repos/os/src/server/lx_fs/lx_util.h b/repos/os/src/server/lx_fs/lx_util.h index 6a9276356a..b4f9a61a82 100644 --- a/repos/os/src/server/lx_fs/lx_util.h +++ b/repos/os/src/server/lx_fs/lx_util.h @@ -61,6 +61,17 @@ namespace Lx_fs { * */ Path_string absolute_root_dir(char const *root_path); + + static inline timespec timespec_from_timestamp(File_system::Timestamp t) + { + return { .tv_sec = time_t (t.ms_since_1970 * 1000), + .tv_nsec = time_t((t.ms_since_1970 % 1000)*1000*1000) }; + } + + static inline File_system::Timestamp timestamp_from_timespec(timespec ts) + { + return { .ms_since_1970 = Genode::uint64_t(ts.tv_sec*1000 + ts.tv_nsec/1000000) }; + } } #endif /* _LX_UTIL_H_ */ diff --git a/repos/os/src/server/vfs/main.cc b/repos/os/src/server/vfs/main.cc index edc0b898f2..8175faf747 100644 --- a/repos/os/src/server/vfs/main.cc +++ b/repos/os/src/server/vfs/main.cc @@ -684,7 +684,8 @@ class Vfs_server::Session_component : private Session_resources, .executable = vfs_stat.rwx.executable }, .inode = vfs_stat.inode, - .modification_time = { vfs_stat.modification_time.value } + .modification_time = { + .ms_since_1970 = vfs_stat.modification_time.ms_since_1970 } }; }); diff --git a/repos/os/src/server/vfs/node.h b/repos/os/src/server/vfs/node.h index 29bdad41ec..128ba16d49 100644 --- a/repos/os/src/server/vfs/node.h +++ b/repos/os/src/server/vfs/node.h @@ -447,7 +447,7 @@ class Vfs_server::Io_node : public Vfs_server::Node, void _execute_write_timestamp() { _packet.with_timestamp([&] (::File_system::Timestamp const time) { - Vfs::Timestamp ts { .value = time.value }; + Vfs::Timestamp ts { .ms_since_1970 = time.ms_since_1970 }; _handle.fs().update_modification_timestamp(&_handle, ts); }); _acknowledge_as_success(0);