1
0
mirror of https://github.com/SerenityOS/serenity synced 2024-07-09 15:10:45 +00:00

Kernel: Use AK::Time for InodeMetadata timestamps instead of time_t

Before this change, we were truncating the nanosecond part of file
timestamps in many different places.
This commit is contained in:
Andreas Kling 2022-11-22 21:01:45 +01:00
parent f8290e1ad4
commit 10fa72d451
23 changed files with 56 additions and 58 deletions

View File

@ -19,9 +19,9 @@ void initialize()
s_boot_time = now();
}
time_t boot_time()
Time boot_time()
{
return s_boot_time;
return Time::from_timespec({ s_boot_time, 0 });
}
static bool update_in_progress()

View File

@ -12,6 +12,6 @@ namespace Kernel::RTC {
void initialize();
time_t now();
time_t boot_time();
Time boot_time();
}

View File

@ -38,7 +38,7 @@ InodeMetadata DevPtsFSInode::metadata() const
{
if (auto pty = m_pty.strong_ref()) {
auto metadata = m_metadata;
metadata.mtime = pty->time_of_last_write();
metadata.mtime = Time::from_timespec({ pty->time_of_last_write(), 0 });
return metadata;
}
return m_metadata;

View File

@ -477,10 +477,10 @@ InodeMetadata Ext2FSInode::metadata() const
metadata.uid = m_raw_inode.i_uid;
metadata.gid = m_raw_inode.i_gid;
metadata.link_count = m_raw_inode.i_links_count;
metadata.atime = m_raw_inode.i_atime;
metadata.ctime = m_raw_inode.i_ctime;
metadata.mtime = m_raw_inode.i_mtime;
metadata.dtime = m_raw_inode.i_dtime;
metadata.atime = Time::from_timespec({ m_raw_inode.i_atime, 0 });
metadata.ctime = Time::from_timespec({ m_raw_inode.i_ctime, 0 });
metadata.mtime = Time::from_timespec({ m_raw_inode.i_mtime, 0 });
metadata.dtime = Time::from_timespec({ m_raw_inode.i_dtime, 0 });
metadata.block_size = fs().block_size();
metadata.block_count = m_raw_inode.i_blocks;
@ -930,23 +930,23 @@ ErrorOr<NonnullLockRefPtr<Inode>> Ext2FSInode::lookup(StringView name)
return fs().get_inode({ fsid(), inode_index });
}
ErrorOr<void> Ext2FSInode::update_timestamps(Optional<time_t> atime, Optional<time_t> ctime, Optional<time_t> mtime)
ErrorOr<void> Ext2FSInode::update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime)
{
MutexLocker locker(m_inode_lock);
if (fs().is_readonly())
return EROFS;
if (atime.value_or(0) > INT32_MAX)
if (atime.value_or({}).to_timespec().tv_sec > INT32_MAX)
return EINVAL;
if (ctime.value_or(0) > INT32_MAX)
if (ctime.value_or({}).to_timespec().tv_sec > INT32_MAX)
return EINVAL;
if (mtime.value_or(0) > INT32_MAX)
if (mtime.value_or({}).to_timespec().tv_sec > INT32_MAX)
return EINVAL;
if (atime.has_value())
m_raw_inode.i_atime = atime.value();
m_raw_inode.i_atime = atime.value().to_timespec().tv_sec;
if (ctime.has_value())
m_raw_inode.i_ctime = ctime.value();
m_raw_inode.i_ctime = ctime.value().to_timespec().tv_sec;
if (mtime.has_value())
m_raw_inode.i_mtime = mtime.value();
m_raw_inode.i_mtime = mtime.value().to_timespec().tv_sec;
set_metadata_dirty(true);
return {};
}

View File

@ -36,7 +36,7 @@ private:
virtual ErrorOr<NonnullLockRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override;
virtual ErrorOr<void> add_child(Inode& child, StringView name, mode_t) override;
virtual ErrorOr<void> remove_child(StringView name) override;
virtual ErrorOr<void> update_timestamps(Optional<time_t> atime, Optional<time_t> ctime, Optional<time_t> mtime) override;
virtual ErrorOr<void> update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime) override;
virtual ErrorOr<void> increment_link_count() override;
virtual ErrorOr<void> decrement_link_count() override;
virtual ErrorOr<void> chmod(mode_t) override;

View File

@ -34,7 +34,7 @@ FATInode::FATInode(FATFS& fs, FATEntry entry, NonnullOwnPtr<KString> filename)
.atime = fat_date_time(m_entry.last_accessed_date, { 0 }),
.ctime = fat_date_time(m_entry.creation_date, m_entry.creation_time),
.mtime = fat_date_time(m_entry.modification_date, m_entry.modification_time),
.dtime = 0,
.dtime = {},
.block_count = 0,
.block_size = 0,
.major_device = 0,
@ -167,12 +167,12 @@ ErrorOr<NonnullOwnPtr<KString>> FATInode::compute_filename(FATEntry& entry, Vect
VERIFY_NOT_REACHED();
}
time_t FATInode::fat_date_time(FATPackedDate date, FATPackedTime time)
Time FATInode::fat_date_time(FATPackedDate date, FATPackedTime time)
{
if (date.value == 0)
return 0;
return Time();
return Time::from_timestamp(first_fat_year + date.year, date.month, date.day, time.hour, time.minute, time.second * 2, 0).to_seconds();
return Time::from_timestamp(first_fat_year + date.year, date.month, date.day, time.hour, time.minute, time.second * 2, 0);
}
StringView FATInode::byte_terminated_string(StringView string, u8 fill_byte)

View File

@ -45,7 +45,7 @@ private:
static ErrorOr<NonnullOwnPtr<KString>> compute_filename(FATEntry&, Vector<FATLongFileNameEntry> const& = {});
static StringView byte_terminated_string(StringView, u8);
static time_t fat_date_time(FATPackedDate date, FATPackedTime time);
static Time fat_date_time(FATPackedDate, FATPackedTime);
ErrorOr<Vector<BlockBasedFileSystem::BlockIndex>> compute_block_list();
ErrorOr<NonnullOwnPtr<KBuffer>> read_block_list();

View File

@ -140,7 +140,7 @@ ErrorOr<void> ISO9660Inode::truncate(u64)
return EROFS;
}
ErrorOr<void> ISO9660Inode::update_timestamps(Optional<time_t>, Optional<time_t>, Optional<time_t>)
ErrorOr<void> ISO9660Inode::update_timestamps(Optional<Time>, Optional<Time>, Optional<Time>)
{
return EROFS;
}
@ -164,7 +164,7 @@ void ISO9660Inode::create_metadata()
{
u32 data_length = LittleEndian { m_record.data_length.little };
bool is_directory = has_flag(m_record.file_flags, ISO::FileFlags::Directory);
time_t recorded_at = parse_numerical_date_time(m_record.recording_date_and_time);
auto recorded_at = Time::from_timespec({ parse_numerical_date_time(m_record.recording_date_and_time), 0 });
m_metadata = {
.inode = identifier(),
@ -176,7 +176,7 @@ void ISO9660Inode::create_metadata()
.atime = recorded_at,
.ctime = recorded_at,
.mtime = recorded_at,
.dtime = 0,
.dtime = {},
.block_count = 0,
.block_size = 0,
.major_device = 0,

View File

@ -31,7 +31,7 @@ public:
virtual ErrorOr<void> chmod(mode_t) override;
virtual ErrorOr<void> chown(UserID, GroupID) override;
virtual ErrorOr<void> truncate(u64) override;
virtual ErrorOr<void> update_timestamps(Optional<time_t> atime, Optional<time_t> ctime, Optional<time_t> mtime) override;
virtual ErrorOr<void> update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime) override;
private:
// HACK: The base ISO 9660 standard says the maximum filename length is 37

View File

@ -119,7 +119,7 @@ ErrorOr<size_t> Inode::read_bytes(off_t offset, size_t length, UserOrKernelBuffe
return read_bytes_locked(offset, length, buffer, open_description);
}
ErrorOr<void> Inode::update_timestamps([[maybe_unused]] Optional<time_t> atime, [[maybe_unused]] Optional<time_t> ctime, [[maybe_unused]] Optional<time_t> mtime)
ErrorOr<void> Inode::update_timestamps([[maybe_unused]] Optional<Time> atime, [[maybe_unused]] Optional<Time> ctime, [[maybe_unused]] Optional<Time> mtime)
{
return ENOTIMPL;
}
@ -238,8 +238,8 @@ void Inode::did_modify_contents()
{
// FIXME: What happens if this fails?
// ENOTIMPL would be a meaningless error to return here
auto time = kgettimeofday().to_truncated_seconds();
(void)update_timestamps({}, time, time);
auto now = kgettimeofday();
(void)update_timestamps({}, now, now);
m_watchers.for_each([&](auto& watcher) {
watcher->notify_inode_event({}, identifier(), InodeWatcherEvent::Type::ContentModified);

View File

@ -80,7 +80,7 @@ public:
bool is_metadata_dirty() const { return m_metadata_dirty; }
virtual ErrorOr<void> update_timestamps(Optional<time_t> atime, Optional<time_t> ctime, Optional<time_t> mtime);
virtual ErrorOr<void> update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime);
virtual ErrorOr<void> increment_link_count();
virtual ErrorOr<void> decrement_link_count();

View File

@ -44,7 +44,7 @@ ErrorOr<size_t> InodeFile::write(OpenFileDescription& description, u64 offset, U
size_t nwritten = TRY(m_inode->write_bytes(offset, count, data, &description));
if (nwritten > 0) {
auto mtime_result = m_inode->update_timestamps({}, {}, kgettimeofday().to_truncated_seconds());
auto mtime_result = m_inode->update_timestamps({}, {}, kgettimeofday());
Thread::current()->did_file_write(nwritten);
evaluate_block_conditions();
if (mtime_result.is_error())
@ -96,7 +96,7 @@ ErrorOr<NonnullOwnPtr<KString>> InodeFile::pseudo_path(OpenFileDescription const
ErrorOr<void> InodeFile::truncate(u64 size)
{
TRY(m_inode->truncate(size));
TRY(m_inode->update_timestamps({}, {}, kgettimeofday().to_truncated_seconds()));
TRY(m_inode->update_timestamps({}, {}, kgettimeofday()));
return {};
}

View File

@ -8,6 +8,7 @@
#include <AK/Error.h>
#include <AK/Span.h>
#include <AK/Time.h>
#include <Kernel/FileSystem/DeviceFileTypes.h>
#include <Kernel/FileSystem/InodeIdentifier.h>
#include <Kernel/Forward.h>
@ -106,12 +107,9 @@ struct InodeMetadata {
buffer.st_size = size;
buffer.st_blksize = block_size;
buffer.st_blocks = block_count;
buffer.st_atim.tv_sec = atime;
buffer.st_atim.tv_nsec = 0;
buffer.st_mtim.tv_sec = mtime;
buffer.st_mtim.tv_nsec = 0;
buffer.st_ctim.tv_sec = ctime;
buffer.st_ctim.tv_nsec = 0;
buffer.st_atim = atime.to_timespec();
buffer.st_mtim = mtime.to_timespec();
buffer.st_ctim = ctime.to_timespec();
return buffer;
}
@ -121,10 +119,10 @@ struct InodeMetadata {
UserID uid { 0 };
GroupID gid { 0 };
nlink_t link_count { 0 };
time_t atime { 0 };
time_t ctime { 0 };
time_t mtime { 0 };
time_t dtime { 0 };
Time atime {};
Time ctime {};
Time mtime {};
Time dtime {};
blkcnt_t block_count { 0 };
blksize_t block_size { 0 };
MajorNumber major_device { 0 };

View File

@ -62,7 +62,7 @@ ErrorOr<void> ProcFSGlobalInode::truncate(u64 size)
return m_associated_component->truncate(size);
}
ErrorOr<void> ProcFSGlobalInode::update_timestamps(Optional<time_t>, Optional<time_t>, Optional<time_t>)
ErrorOr<void> ProcFSGlobalInode::update_timestamps(Optional<Time>, Optional<Time>, Optional<Time>)
{
return {};
}

View File

@ -32,7 +32,7 @@ protected:
virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> lookup(StringView) override;
virtual ErrorOr<void> truncate(u64) override final;
virtual ErrorOr<void> update_timestamps(Optional<time_t> atime, Optional<time_t> ctime, Optional<time_t> mtime) override;
virtual ErrorOr<void> update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime) override;
NonnullLockRefPtr<ProcFSExposedComponent> m_associated_component;
};

View File

@ -105,7 +105,7 @@ ErrorOr<void> SysFSInode::truncate(u64 size)
return m_associated_component->truncate(size);
}
ErrorOr<void> SysFSInode::update_timestamps(Optional<time_t>, Optional<time_t>, Optional<time_t>)
ErrorOr<void> SysFSInode::update_timestamps(Optional<Time>, Optional<Time>, Optional<Time>)
{
return {};
}

View File

@ -34,7 +34,7 @@ protected:
virtual ErrorOr<void> chmod(mode_t) override;
virtual ErrorOr<void> chown(UserID, GroupID) override;
virtual ErrorOr<void> truncate(u64) override;
virtual ErrorOr<void> update_timestamps(Optional<time_t> atime, Optional<time_t> ctime, Optional<time_t> mtime) override;
virtual ErrorOr<void> update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime) override;
virtual ErrorOr<void> attach(OpenFileDescription& description) override final;
virtual void did_seek(OpenFileDescription&, off_t) override final;

View File

@ -28,7 +28,7 @@ ErrorOr<NonnullLockRefPtr<TmpFSInode>> TmpFSInode::try_create(TmpFS& fs, InodeMe
ErrorOr<NonnullLockRefPtr<TmpFSInode>> TmpFSInode::try_create_root(TmpFS& fs)
{
InodeMetadata metadata;
auto now = kgettimeofday().to_truncated_seconds();
auto now = kgettimeofday();
metadata.atime = now;
metadata.ctime = now;
metadata.mtime = now;
@ -266,7 +266,7 @@ ErrorOr<void> TmpFSInode::chown(UserID uid, GroupID gid)
ErrorOr<NonnullLockRefPtr<Inode>> TmpFSInode::create_child(StringView name, mode_t mode, dev_t dev, UserID uid, GroupID gid)
{
MutexLocker locker(m_inode_lock);
time_t now = kgettimeofday().to_truncated_seconds();
auto now = kgettimeofday();
InodeMetadata metadata;
metadata.mode = mode;
@ -352,7 +352,7 @@ ErrorOr<void> TmpFSInode::truncate(u64 size)
return {};
}
ErrorOr<void> TmpFSInode::update_timestamps(Optional<time_t> atime, Optional<time_t> ctime, Optional<time_t> mtime)
ErrorOr<void> TmpFSInode::update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime)
{
MutexLocker locker(m_inode_lock);

View File

@ -33,7 +33,7 @@ public:
virtual ErrorOr<void> chmod(mode_t) override;
virtual ErrorOr<void> chown(UserID, GroupID) override;
virtual ErrorOr<void> truncate(u64) override;
virtual ErrorOr<void> update_timestamps(Optional<time_t> atime, Optional<time_t> ctime, Optional<time_t> mtime) override;
virtual ErrorOr<void> update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime) override;
private:
TmpFSInode(TmpFS& fs, InodeMetadata const& metadata, LockWeakPtr<TmpFSInode> parent);

View File

@ -281,7 +281,7 @@ ErrorOr<void> VirtualFileSystem::utime(Credentials const& credentials, StringVie
if (custody->is_readonly())
return EROFS;
TRY(inode.update_timestamps(atime, {}, mtime));
TRY(inode.update_timestamps(Time::from_timespec({ atime, 0 }), {}, Time::from_timespec({ mtime, 0 })));
return {};
}
@ -296,9 +296,9 @@ ErrorOr<void> VirtualFileSystem::utimensat(Credentials const& credentials, Strin
// NOTE: A standard ext2 inode cannot store nanosecond timestamps.
TRY(inode.update_timestamps(
(atime.tv_nsec != UTIME_OMIT) ? atime.tv_sec : Optional<time_t> {},
(atime.tv_nsec != UTIME_OMIT) ? Time::from_timespec(atime) : Optional<Time> {},
{},
(mtime.tv_nsec != UTIME_OMIT) ? mtime.tv_sec : Optional<time_t> {}));
(mtime.tv_nsec != UTIME_OMIT) ? Time::from_timespec(mtime) : Optional<Time> {}));
return {};
}
@ -412,7 +412,7 @@ ErrorOr<NonnullLockRefPtr<OpenFileDescription>> VirtualFileSystem::open(Credenti
if (should_truncate_file) {
TRY(inode.truncate(0));
TRY(inode.update_timestamps({}, {}, kgettimeofday().to_truncated_seconds()));
TRY(inode.update_timestamps({}, {}, kgettimeofday()));
}
auto description = TRY(OpenFileDescription::try_create(custody));
description->set_rw_mode(options);

View File

@ -78,7 +78,7 @@ public:
virtual mode_t required_mode() const { return 0444; }
virtual UserID owner_user() const { return 0; }
virtual GroupID owner_group() const { return 0; }
static time_t modified_time() { return TimeManagement::now().to_timeval().tv_sec; }
static Time modified_time() { return TimeManagement::now(); }
virtual void prepare_for_deletion() { }
virtual ErrorOr<void> refresh_data(OpenFileDescription&) const

View File

@ -227,7 +227,7 @@ time_t TimeManagement::ticks_per_second() const
return m_time_keeper_timer->ticks_per_second();
}
time_t TimeManagement::boot_time()
Time TimeManagement::boot_time()
{
#if ARCH(I386) || ARCH(X86_64)
return RTC::boot_time();
@ -246,14 +246,14 @@ UNMAP_AFTER_INIT TimeManagement::TimeManagement()
if (ACPI::is_enabled()) {
if (!ACPI::Parser::the()->x86_specific_flags().cmos_rtc_not_present) {
RTC::initialize();
m_epoch_time.tv_sec += boot_time();
m_epoch_time.tv_sec += boot_time().to_timespec().tv_sec;
} else {
dmesgln("ACPI: RTC CMOS Not present");
}
} else {
// We just assume that we can access RTC CMOS, if ACPI isn't usable.
RTC::initialize();
m_epoch_time.tv_sec += boot_time();
m_epoch_time.tv_sec += boot_time().to_timespec().tv_sec;
}
if (probe_non_legacy_hardware_timers) {
if (!probe_and_set_x86_non_legacy_hardware_timers())

View File

@ -51,7 +51,7 @@ public:
Time epoch_time(TimePrecision = TimePrecision::Precise) const;
void set_epoch_time(Time);
time_t ticks_per_second() const;
static time_t boot_time();
static Time boot_time();
bool is_system_timer(HardwareTimerBase const&) const;