Procházet zdrojové kódy

Kernel/ProcFS: Provide a way to write to ProcFS inodes

ProcFSGlobalInode now calls `write_bytes()`, `truncate()` and
`set_mtime()` on its associated component. This allows us to write 0 or
1 to a ProcFSSystemBoolean component to toggle a boolean value.
SeekingBlues před 3 roky
rodič
revize
3d174e3ad2

+ 10 - 5
Kernel/FileSystem/ProcFS.cpp

@@ -99,11 +99,6 @@ KResult ProcFSInode::chown(UserID, GroupID)
     return EPERM;
 }
 
-KResult ProcFSInode::truncate(u64)
-{
-    return EPERM;
-}
-
 KResultOr<NonnullRefPtr<ProcFSGlobalInode>> ProcFSGlobalInode::try_create(const ProcFS& fs, const ProcFSExposedComponent& component)
 {
     return adopt_nonnull_ref_or_enomem(new (nothrow) ProcFSGlobalInode(fs, component));
@@ -151,6 +146,16 @@ KResultOr<NonnullRefPtr<Inode>> ProcFSGlobalInode::lookup(StringView)
     VERIFY_NOT_REACHED();
 }
 
+KResult ProcFSGlobalInode::truncate(u64 size)
+{
+    return m_associated_component->truncate(size);
+}
+
+KResult ProcFSGlobalInode::set_mtime(time_t time)
+{
+    return m_associated_component->set_mtime(time);
+}
+
 InodeMetadata ProcFSGlobalInode::metadata() const
 {
     MutexLocker locker(m_inode_lock);

+ 2 - 1
Kernel/FileSystem/ProcFS.h

@@ -62,7 +62,6 @@ protected:
     virtual KResult remove_child(const StringView& name) override final;
     virtual KResult chmod(mode_t) override final;
     virtual KResult chown(UserID, GroupID) override final;
-    virtual KResult truncate(u64) override final;
 };
 
 class ProcFSGlobalInode : public ProcFSInode {
@@ -84,6 +83,8 @@ protected:
     virtual InodeMetadata metadata() const override;
     virtual KResult traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
     virtual KResultOr<NonnullRefPtr<Inode>> lookup(StringView) override;
+    virtual KResult truncate(u64) override final;
+    virtual KResult set_mtime(time_t) override final;
 
     NonnullRefPtr<ProcFSExposedComponent> m_associated_component;
 };

+ 33 - 0
Kernel/ProcessExposed.cpp

@@ -153,6 +153,39 @@ KResult ProcFSGlobalInformation::refresh_data(OpenFileDescription& description)
     return KSuccess;
 }
 
+KResult ProcFSSystemBoolean::try_generate(KBufferBuilder& builder)
+{
+    return builder.appendff("{}\n", static_cast<int>(value()));
+}
+
+KResultOr<size_t> ProcFSSystemBoolean::write_bytes(off_t, size_t count, const UserOrKernelBuffer& buffer, OpenFileDescription*)
+{
+    if (count != 1)
+        return EINVAL;
+    MutexLocker locker(m_refresh_lock);
+    char value = 0;
+    TRY(buffer.read(&value, 1));
+    if (value == '0')
+        set_value(false);
+    else if (value == '1')
+        set_value(true);
+    else
+        return EINVAL;
+    return 1;
+}
+
+KResult ProcFSSystemBoolean::truncate(u64 size)
+{
+    if (size != 0)
+        return EPERM;
+    return KSuccess;
+}
+
+KResult ProcFSSystemBoolean::set_mtime(time_t)
+{
+    return KSuccess;
+}
+
 KResultOr<size_t> ProcFSExposedLink::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription*) const
 {
     VERIFY(offset == 0);

+ 13 - 5
Kernel/ProcessExposed.h

@@ -69,7 +69,9 @@ public:
     virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const { VERIFY_NOT_REACHED(); }
     virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const { VERIFY_NOT_REACHED(); }
     virtual KResultOr<NonnullRefPtr<ProcFSExposedComponent>> lookup(StringView) { VERIFY_NOT_REACHED(); };
-    virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer&, OpenFileDescription*) { return KResult(EROFS); }
+    virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer&, OpenFileDescription*) { return EROFS; }
+    virtual KResult truncate(u64) { return EPERM; }
+    virtual KResult set_mtime(time_t) { return ENOTIMPL; }
 
     virtual mode_t required_mode() const { return 0444; }
     virtual UserID owner_user() const { return 0; }
@@ -182,10 +184,16 @@ protected:
         : ProcFSGlobalInformation(name)
     {
     }
-    virtual KResult try_generate(KBufferBuilder& builder) override
-    {
-        return builder.appendff("{}\n", value());
-    }
+
+private:
+    // ^ProcFSGlobalInformation
+    virtual KResult try_generate(KBufferBuilder&) override final;
+
+    // ^ProcFSExposedComponent
+    virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer&, OpenFileDescription*) override final;
+    virtual mode_t required_mode() const override final { return 0644; }
+    virtual KResult truncate(u64) override final;
+    virtual KResult set_mtime(time_t) override final;
 };
 
 }