ソースを参照

DevPtsFS: Do not assume there is one of it

Unfortunately, that also means it can no longer inherit from SynthFS.
Sergey Bugaev 5 年 前
コミット
66a0a12435
5 ファイル変更187 行追加44 行削除
  1. 145 27
      Kernel/FileSystem/DevPtsFS.cpp
  2. 36 10
      Kernel/FileSystem/DevPtsFS.h
  3. 2 2
      Kernel/TTY/SlavePTY.cpp
  4. 0 4
      Kernel/TTY/SlavePTY.h
  5. 4 1
      Kernel/init.cpp

+ 145 - 27
Kernel/FileSystem/DevPtsFS.cpp

@@ -3,14 +3,6 @@
 #include <Kernel/FileSystem/VirtualFileSystem.h>
 #include <Kernel/TTY/SlavePTY.h>
 
-static DevPtsFS* s_the;
-
-DevPtsFS& DevPtsFS::the()
-{
-    ASSERT(s_the);
-    return *s_the;
-}
-
 NonnullRefPtr<DevPtsFS> DevPtsFS::create()
 {
     return adopt(*new DevPtsFS);
@@ -18,49 +10,175 @@ NonnullRefPtr<DevPtsFS> DevPtsFS::create()
 
 DevPtsFS::DevPtsFS()
 {
-    s_the = this;
 }
 
 DevPtsFS::~DevPtsFS()
 {
 }
 
+static HashTable<unsigned>* ptys;
+
 bool DevPtsFS::initialize()
 {
-    SynthFS::initialize();
+    if (ptys == nullptr) {
+        ptys = new HashTable<unsigned>();
+    }
+
+    m_root_inode = adopt(*new DevPtsFSInode(*this, 1));
+    m_root_inode->m_metadata.inode = { fsid(), 1 };
+    m_root_inode->m_metadata.mode = 0040555;
+    m_root_inode->m_metadata.uid = 0;
+    m_root_inode->m_metadata.gid = 0;
+    m_root_inode->m_metadata.size = 0;
+    m_root_inode->m_metadata.mtime = mepoch;
+
     return true;
 }
 
-const char* DevPtsFS::class_name() const
+static unsigned inode_index_to_pty_index(unsigned inode_index)
+{
+    ASSERT(inode_index > 1);
+    return inode_index - 2;
+}
+
+static unsigned pty_index_to_inode_index(unsigned pty_index)
+{
+    return pty_index + 2;
+}
+
+InodeIdentifier DevPtsFS::root_inode() const
+{
+    return { fsid(), 1 };
+}
+
+RefPtr<Inode> DevPtsFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, int& error)
+{
+    error = -EROFS;
+    return nullptr;
+}
+
+RefPtr<Inode> DevPtsFS::create_directory(InodeIdentifier, const String&, mode_t, int& error)
 {
-    return "DevPtsFS";
+    error = -EROFS;
+    return nullptr;
 }
 
-NonnullRefPtr<SynthFSInode> DevPtsFS::create_slave_pty_device_file(unsigned index)
+RefPtr<Inode> DevPtsFS::get_inode(InodeIdentifier inode_id) const
 {
-    auto file = adopt(*new SynthFSInode(*this, generate_inode_index()));
-    file->m_name = String::number(index);
+    if (inode_id.index() == 1)
+        return m_root_inode;
 
-    auto* device = VFS::the().get_device(11, index);
+    unsigned pty_index = inode_index_to_pty_index(inode_id.index());
+    auto* device = VFS::the().get_device(11, pty_index);
     ASSERT(device);
 
-    file->m_metadata.size = 0;
-    file->m_metadata.uid = device->uid();
-    file->m_metadata.gid = device->gid();
-    file->m_metadata.mode = 0020644;
-    file->m_metadata.major_device = device->major();
-    file->m_metadata.minor_device = device->minor();
-    file->m_metadata.mtime = mepoch;
-    return file;
+    auto inode = adopt(*new DevPtsFSInode(const_cast<DevPtsFS&>(*this), inode_id.index()));
+    inode->m_metadata.inode = inode_id;
+    inode->m_metadata.size = 0;
+    inode->m_metadata.uid = device->uid();
+    inode->m_metadata.gid = device->gid();
+    inode->m_metadata.mode = 0020644;
+    inode->m_metadata.major_device = device->major();
+    inode->m_metadata.minor_device = device->minor();
+    inode->m_metadata.mtime = mepoch;
+
+    return inode;
 }
 
 void DevPtsFS::register_slave_pty(SlavePTY& slave_pty)
 {
-    auto inode_id = add_file(create_slave_pty_device_file(slave_pty.index()));
-    slave_pty.set_devpts_inode_id(inode_id);
+    ptys->set(slave_pty.index());
 }
 
 void DevPtsFS::unregister_slave_pty(SlavePTY& slave_pty)
 {
-    remove_file(slave_pty.devpts_inode_id().index());
+    ptys->remove(slave_pty.index());
+}
+
+DevPtsFSInode::DevPtsFSInode(DevPtsFS& fs, unsigned index)
+    : Inode(fs, index)
+{
+}
+
+DevPtsFSInode::~DevPtsFSInode()
+{
+}
+
+ssize_t DevPtsFSInode::read_bytes(off_t, ssize_t, u8*, FileDescription*) const
+{
+    ASSERT_NOT_REACHED();
+}
+
+ssize_t DevPtsFSInode::write_bytes(off_t, ssize_t, const u8*, FileDescription*)
+{
+    ASSERT_NOT_REACHED();
+}
+
+InodeMetadata DevPtsFSInode::metadata() const
+{
+    return m_metadata;
+}
+
+bool DevPtsFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntry&)> callback) const
+{
+    if (identifier().index() > 1)
+        return false;
+
+    callback({ ".", 1, identifier(), 0 });
+    callback({ "..", 2, identifier(), 0 });
+
+    for (unsigned pty_index : *ptys) {
+        String name = String::number(pty_index);
+        InodeIdentifier identifier = { fsid(), pty_index_to_inode_index(pty_index) };
+        callback({ name.characters(), name.length(), identifier, 0 });
+    }
+
+    return true;
+}
+
+size_t DevPtsFSInode::directory_entry_count() const
+{
+    ASSERT(identifier().index() == 1);
+
+    return 2 + ptys->size();
+}
+
+InodeIdentifier DevPtsFSInode::lookup(StringView name)
+{
+    ASSERT(identifier().index() == 1);
+
+    if (name == "." || name == "..")
+        return identifier();
+
+    bool ok;
+    unsigned pty_index = name.to_uint(ok);
+    if (ok && ptys->contains(pty_index)) {
+        return { fsid(), pty_index_to_inode_index(pty_index) };
+    }
+
+    return {};
+}
+
+void DevPtsFSInode::flush_metadata()
+{
+}
+
+KResult DevPtsFSInode::add_child(InodeIdentifier, const StringView&, mode_t)
+{
+    return KResult(-EROFS);
+}
+
+KResult DevPtsFSInode::remove_child(const StringView&)
+{
+    return KResult(-EROFS);
+}
+
+KResult DevPtsFSInode::chmod(mode_t)
+{
+    return KResult(-EPERM);
+}
+
+KResult DevPtsFSInode::chown(uid_t, gid_t)
+{
+    return KResult(-EPERM);
 }

+ 36 - 10
Kernel/FileSystem/DevPtsFS.h

@@ -1,28 +1,54 @@
 #pragma once
 
 #include <AK/Types.h>
-#include <Kernel/FileSystem/SyntheticFileSystem.h>
+#include <Kernel/FileSystem/FileSystem.h>
+#include <Kernel/FileSystem/Inode.h>
 
-class Process;
 class SlavePTY;
+class DevPtsFSInode;
 
-class DevPtsFS final : public SynthFS {
+class DevPtsFS final : public FS {
 public:
-    static DevPtsFS& the();
-
     virtual ~DevPtsFS() override;
     static NonnullRefPtr<DevPtsFS> create();
 
     virtual bool initialize() override;
-    virtual const char* class_name() const override;
+    virtual const char* class_name() const override { return "DevPtsFS"; }
+
+    virtual InodeIdentifier root_inode() const override;
+    virtual RefPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) override;
+    virtual RefPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) override;
+    virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
 
-    void register_slave_pty(SlavePTY&);
-    void unregister_slave_pty(SlavePTY&);
+    static void register_slave_pty(SlavePTY&);
+    static void unregister_slave_pty(SlavePTY&);
 
 private:
     DevPtsFS();
 
-    NonnullRefPtr<SynthFSInode> create_slave_pty_device_file(unsigned index);
+    RefPtr<DevPtsFSInode> m_root_inode;
+};
+
+class DevPtsFSInode final : public Inode {
+    friend class DevPtsFS;
+public:
+    virtual ~DevPtsFSInode() override;
 
-    HashTable<SlavePTY*> m_slave_ptys;
+private:
+    DevPtsFSInode(DevPtsFS&, unsigned index);
+
+    // ^Inode
+    virtual ssize_t read_bytes(off_t, ssize_t, u8* buffer, FileDescription*) const override;
+    virtual InodeMetadata metadata() const override;
+    virtual bool traverse_as_directory(Function<bool(const FS::DirectoryEntry&)>) const override;
+    virtual InodeIdentifier lookup(StringView name) override;
+    virtual void flush_metadata() override;
+    virtual ssize_t write_bytes(off_t, ssize_t, const u8* buffer, FileDescription*) override;
+    virtual KResult add_child(InodeIdentifier child_id, const StringView& name, mode_t) override;
+    virtual KResult remove_child(const StringView& name) override;
+    virtual size_t directory_entry_count() const override;
+    virtual KResult chmod(mode_t) override;
+    virtual KResult chown(uid_t, gid_t) override;
+
+    InodeMetadata m_metadata;
 };

+ 2 - 2
Kernel/TTY/SlavePTY.cpp

@@ -13,7 +13,7 @@ SlavePTY::SlavePTY(MasterPTY& master, unsigned index)
     m_tty_name = String::format("/dev/pts/%u", m_index);
     set_uid(current->process().uid());
     set_gid(current->process().gid());
-    DevPtsFS::the().register_slave_pty(*this);
+    DevPtsFS::register_slave_pty(*this);
     set_size(80, 25);
 }
 
@@ -22,7 +22,7 @@ SlavePTY::~SlavePTY()
 #ifdef SLAVEPTY_DEBUG
     dbgprintf("~SlavePTY(%u)\n", m_index);
 #endif
-    DevPtsFS::the().unregister_slave_pty(*this);
+    DevPtsFS::unregister_slave_pty(*this);
 }
 
 String SlavePTY::tty_name() const

+ 0 - 4
Kernel/TTY/SlavePTY.h

@@ -12,9 +12,6 @@ public:
     void on_master_write(const u8*, ssize_t);
     unsigned index() const { return m_index; }
 
-    InodeIdentifier devpts_inode_id() const { return m_devpts_inode_id; }
-    void set_devpts_inode_id(InodeIdentifier inode_id) { m_devpts_inode_id = inode_id; }
-
 private:
     // ^TTY
     virtual String tty_name() const override;
@@ -32,6 +29,5 @@ private:
 
     RefPtr<MasterPTY> m_master;
     unsigned m_index;
-    InodeIdentifier m_devpts_inode_id;
     String m_tty_name;
 };

+ 4 - 1
Kernel/init.cpp

@@ -122,7 +122,10 @@ VFS* vfs;
     auto procfs = ProcFS::create();
     procfs->initialize();
     vfs->mount(procfs, "/proc");
-    vfs->mount(DevPtsFS::the(), "/dev/pts");
+
+    auto devptsfs = DevPtsFS::create();
+    devptsfs->initialize();
+    vfs->mount(devptsfs, "/dev/pts");
 
     auto tmpfs = TmpFS::create();
     if (!tmpfs->initialize())