summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2021-09-17 11:52:51 +0300
committerAndreas Kling <kling@serenityos.org>2021-10-09 12:07:56 +0200
commitf8489da8ee7408d8a4a2dda163fb36867c16ad45 (patch)
tree399f0aa9a8fbd45a855994362ecf589a63ea2dd0 /Kernel
parent7269ce15fce8acdf6711dc3a67e16d6f9c8ba67f (diff)
downloadserenity-f8489da8ee7408d8a4a2dda163fb36867c16ad45.zip
Kernel/SysFS: Provide a way to "truncate" and "set" mtime on inodes
Normally, trying to truncate a SysFSInode should result in EPERM error. However, as suggested by Ali (@alimpfard), we can allow the PowerState node to be "truncated" so one can open that file with O_TRUNC option. Likewise, we also need to provide a way to set modified time on SysFS inodes. For most inodes, we should return ENOTIMPL error, but for the power state switch, we ignore the modified time setting and just return KSuccess. These fixes allow to do "echo -n 1 > /sys/firmware/power_state" in Shell after gaining root permissions, to switch the power state.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/FileSystem/SysFS.cpp9
-rw-r--r--Kernel/FileSystem/SysFS.h1
-rw-r--r--Kernel/FileSystem/SysFSComponent.h2
-rw-r--r--Kernel/Firmware/PowerStateSwitch.cpp9
-rw-r--r--Kernel/Firmware/PowerStateSwitch.h2
5 files changed, 21 insertions, 2 deletions
diff --git a/Kernel/FileSystem/SysFS.cpp b/Kernel/FileSystem/SysFS.cpp
index bedf3d6353..cc26614663 100644
--- a/Kernel/FileSystem/SysFS.cpp
+++ b/Kernel/FileSystem/SysFS.cpp
@@ -182,9 +182,14 @@ KResult SysFSInode::chown(UserID, GroupID)
return EPERM;
}
-KResult SysFSInode::truncate(u64)
+KResult SysFSInode::set_mtime(time_t time)
{
- return EPERM;
+ return m_associated_component->set_mtime(time);
+}
+
+KResult SysFSInode::truncate(u64 size)
+{
+ return m_associated_component->truncate(size);
}
KResultOr<NonnullRefPtr<SysFSDirectoryInode>> SysFSDirectoryInode::try_create(SysFS const& sysfs, SysFSComponent const& component)
diff --git a/Kernel/FileSystem/SysFS.h b/Kernel/FileSystem/SysFS.h
index 886c31eeb9..4b8bf05c94 100644
--- a/Kernel/FileSystem/SysFS.h
+++ b/Kernel/FileSystem/SysFS.h
@@ -146,6 +146,7 @@ protected:
virtual KResult chmod(mode_t) override;
virtual KResult chown(UserID, GroupID) override;
virtual KResult truncate(u64) override;
+ virtual KResult set_mtime(time_t);
virtual KResult attach(OpenFileDescription& description) override final;
virtual void did_seek(OpenFileDescription&, off_t) override final;
diff --git a/Kernel/FileSystem/SysFSComponent.h b/Kernel/FileSystem/SysFSComponent.h
index c6711a3c47..30f1c66ebb 100644
--- a/Kernel/FileSystem/SysFSComponent.h
+++ b/Kernel/FileSystem/SysFSComponent.h
@@ -30,6 +30,8 @@ public:
virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const { VERIFY_NOT_REACHED(); }
virtual RefPtr<SysFSComponent> lookup(StringView) { VERIFY_NOT_REACHED(); };
virtual mode_t permissions() const;
+ virtual KResult truncate(u64) { return EPERM; }
+ virtual KResult set_mtime(time_t) { return ENOTIMPL; }
virtual KResultOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) { return EROFS; }
virtual KResult refresh_data(OpenFileDescription&) const { return KSuccess; }
diff --git a/Kernel/Firmware/PowerStateSwitch.cpp b/Kernel/Firmware/PowerStateSwitch.cpp
index 16f9e07101..e0f9b53dbe 100644
--- a/Kernel/Firmware/PowerStateSwitch.cpp
+++ b/Kernel/Firmware/PowerStateSwitch.cpp
@@ -30,6 +30,15 @@ UNMAP_AFTER_INIT PowerStateSwitchNode::PowerStateSwitchNode(FirmwareSysFSDirecto
{
}
+KResult PowerStateSwitchNode::truncate(u64 size)
+{
+ // Note: This node doesn't store any useful data anyway, so we can safely
+ // truncate this to zero (essentially ignoring the request without failing).
+ if (size != 0)
+ return EPERM;
+ return KSuccess;
+}
+
KResultOr<size_t> PowerStateSwitchNode::write_bytes(off_t offset, size_t count, UserOrKernelBuffer const& data, OpenFileDescription*)
{
if (Checked<off_t>::addition_would_overflow(offset, count))
diff --git a/Kernel/Firmware/PowerStateSwitch.h b/Kernel/Firmware/PowerStateSwitch.h
index e96540f202..c35bd85ff4 100644
--- a/Kernel/Firmware/PowerStateSwitch.h
+++ b/Kernel/Firmware/PowerStateSwitch.h
@@ -25,6 +25,8 @@ public:
static NonnullRefPtr<PowerStateSwitchNode> must_create(FirmwareSysFSDirectory&);
virtual mode_t permissions() const override;
virtual KResultOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) override;
+ virtual KResult truncate(u64) override;
+ virtual KResult set_mtime(time_t) { return KSuccess; }
private:
PowerStateSwitchNode(FirmwareSysFSDirectory&);