Browse Source

Kernel: Port mounts to reference inodes directly

...instead of going through their identifiers. See the previous commit for
reasoning.
Sergey Bugaev 5 năm trước cách đây
mục cha
commit
6efbbcd4ba

+ 1 - 1
Kernel/FileSystem/DevPtsFS.h

@@ -46,13 +46,13 @@ public:
     virtual const char* class_name() const override { return "DevPtsFS"; }
 
     virtual NonnullRefPtr<Inode> root_inode() const override;
-    virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
 
     static void register_slave_pty(SlavePTY&);
     static void unregister_slave_pty(SlavePTY&);
 
 private:
     DevPtsFS();
+    RefPtr<Inode> get_inode(InodeIdentifier) const;
 
     RefPtr<DevPtsFSInode> m_root_inode;
 };

+ 1 - 1
Kernel/FileSystem/Ext2FileSystem.h

@@ -130,9 +130,9 @@ private:
 
     virtual const char* class_name() const override;
     virtual NonnullRefPtr<Inode> root_inode() const override;
+    RefPtr<Inode> get_inode(InodeIdentifier) const;
     KResultOr<NonnullRefPtr<Inode>> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t);
     KResult create_directory(InodeIdentifier parent_inode, const String& name, mode_t, uid_t, gid_t);
-    virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
     virtual void flush_writes() override;
 
     BlockIndex first_block_index() const;

+ 0 - 2
Kernel/FileSystem/FileSystem.h

@@ -78,8 +78,6 @@ public:
         u8 file_type { 0 };
     };
 
-    virtual RefPtr<Inode> get_inode(InodeIdentifier) const = 0;
-
     virtual void flush_writes() { }
 
     size_t block_size() const { return m_block_size; }

+ 2 - 2
Kernel/FileSystem/ProcFS.cpp

@@ -716,10 +716,10 @@ Optional<KBuffer> procfs$mounts(InodeIdentifier)
     VFS::the().for_each_mount([&builder](auto& mount) {
         auto& fs = mount.guest_fs();
         builder.appendf("%s @ ", fs.class_name());
-        if (!mount.host().is_valid())
+        if (mount.host() == nullptr)
             builder.appendf("/");
         else {
-            builder.appendf("%u:%u", mount.host().fsid(), mount.host().index());
+            builder.appendf("%u:%u", mount.host()->fsid(), mount.host()->index());
             builder.append(' ');
             builder.append(mount.absolute_path());
         }

+ 1 - 1
Kernel/FileSystem/ProcFS.h

@@ -50,7 +50,6 @@ public:
     virtual const char* class_name() const override;
 
     virtual NonnullRefPtr<Inode> root_inode() const override;
-    virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
 
     static void add_sys_bool(String&&, Lockable<bool>&, Function<void()>&& notify_callback = nullptr);
     static void add_sys_string(String&&, Lockable<String>&, Function<void()>&& notify_callback = nullptr);
@@ -79,6 +78,7 @@ private:
         InodeIdentifier identifier(unsigned fsid) const;
     };
 
+    RefPtr<Inode> get_inode(InodeIdentifier) const;
     ProcFSDirectoryEntry* get_directory_entry(InodeIdentifier) const;
 
     Vector<ProcFSDirectoryEntry> m_entries;

+ 1 - 1
Kernel/FileSystem/TmpFS.h

@@ -49,7 +49,6 @@ public:
     virtual bool supports_watchers() const override { return true; }
 
     virtual NonnullRefPtr<Inode> root_inode() const override;
-    virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
 
 private:
     TmpFS();
@@ -57,6 +56,7 @@ private:
     RefPtr<TmpFSInode> m_root_inode;
 
     HashMap<unsigned, NonnullRefPtr<TmpFSInode>> m_inodes;
+    RefPtr<Inode> get_inode(InodeIdentifier identifier) const;
     void register_inode(TmpFSInode&);
     void unregister_inode(InodeIdentifier);
 

+ 44 - 25
Kernel/FileSystem/VirtualFileSystem.cpp

@@ -97,7 +97,7 @@ KResult VFS::remount(Custody& mount_point, int new_flags)
 
     dbg() << "VFS: Remounting " << mount_point.absolute_path();
 
-    Mount* mount = find_mount_for_guest(mount_point.inode().identifier());
+    Mount* mount = find_mount_for_guest(mount_point.inode());
     if (!mount)
         return KResult(-ENODEV);
 
@@ -105,14 +105,14 @@ KResult VFS::remount(Custody& mount_point, int new_flags)
     return KSuccess;
 }
 
-KResult VFS::unmount(InodeIdentifier guest_inode_id)
+KResult VFS::unmount(Inode& guest_inode)
 {
     LOCKER(m_lock);
-    dbg() << "VFS: unmount called with inode " << guest_inode_id;
+    dbg() << "VFS: unmount called with inode " << guest_inode.identifier();
 
     for (size_t i = 0; i < m_mounts.size(); ++i) {
         auto& mount = m_mounts.at(i);
-        if (mount.guest() == guest_inode_id) {
+        if (&mount.guest() == &guest_inode) {
             auto result = mount.guest_fs().prepare_to_unmount();
             if (result.is_error()) {
                 dbg() << "VFS: Failed to unmount!";
@@ -124,7 +124,7 @@ KResult VFS::unmount(InodeIdentifier guest_inode_id)
         }
     }
 
-    dbg() << "VFS: Nothing mounted on inode " << guest_inode_id;
+    dbg() << "VFS: Nothing mounted on inode " << guest_inode.identifier();
     return KResult(-ENODEV);
 }
 
@@ -150,19 +150,37 @@ bool VFS::mount_root(FS& file_system)
     return true;
 }
 
-auto VFS::find_mount_for_host(InodeIdentifier inode) -> Mount*
+auto VFS::find_mount_for_host(Inode& inode) -> Mount*
 {
     for (auto& mount : m_mounts) {
-        if (mount.host() == inode)
+        if (mount.host() == &inode)
             return &mount;
     }
     return nullptr;
 }
 
-auto VFS::find_mount_for_guest(InodeIdentifier inode) -> Mount*
+auto VFS::find_mount_for_host(InodeIdentifier id) -> Mount*
 {
     for (auto& mount : m_mounts) {
-        if (mount.guest() == inode)
+        if (mount.host() && mount.host()->identifier() == id)
+            return &mount;
+    }
+    return nullptr;
+}
+
+auto VFS::find_mount_for_guest(Inode& inode) -> Mount*
+{
+    for (auto& mount : m_mounts) {
+        if (&mount.guest() == &inode)
+            return &mount;
+    }
+    return nullptr;
+}
+
+auto VFS::find_mount_for_guest(InodeIdentifier id) -> Mount*
+{
+    for (auto& mount : m_mounts) {
+        if (mount.guest().identifier() == id)
             return &mount;
     }
     return nullptr;
@@ -178,7 +196,7 @@ void VFS::traverse_directory_inode(Inode& dir_inode, Function<bool(const FS::Dir
     dir_inode.traverse_as_directory([&](const FS::DirectoryEntry& entry) {
         InodeIdentifier resolved_inode;
         if (auto mount = find_mount_for_host(entry.inode))
-            resolved_inode = mount->guest();
+            resolved_inode = mount->guest().identifier();
         else
             resolved_inode = entry.inode;
 
@@ -187,7 +205,8 @@ void VFS::traverse_directory_inode(Inode& dir_inode, Function<bool(const FS::Dir
         if (is_root_inode && !is_vfs_root(dir_inode.identifier()) && !strcmp(entry.name, "..")) {
             auto mount = find_mount_for_guest(entry.inode);
             ASSERT(mount);
-            resolved_inode = mount->host();
+            ASSERT(mount->host());
+            resolved_inode = mount->host()->identifier();
         }
         callback(FS::DirectoryEntry(entry.name, entry.name_length, resolved_inode, entry.file_type));
         return true;
@@ -701,15 +720,8 @@ KResult VFS::rmdir(StringView path, Custody& base)
     return parent_inode.remove_child(LexicalPath(path).basename());
 }
 
-RefPtr<Inode> VFS::get_inode(InodeIdentifier inode_id)
-{
-    if (!inode_id.is_valid())
-        return nullptr;
-    return inode_id.fs()->get_inode(inode_id);
-}
-
 VFS::Mount::Mount(FS& guest_fs, Custody* host_custody, int flags)
-    : m_guest(guest_fs.root_inode()->identifier())
+    : m_guest(guest_fs.root_inode())
     , m_guest_fs(guest_fs)
     , m_host_custody(host_custody)
     , m_flags(flags)
@@ -717,7 +729,7 @@ VFS::Mount::Mount(FS& guest_fs, Custody* host_custody, int flags)
 }
 
 VFS::Mount::Mount(Inode& source, Custody& host_custody, int flags)
-    : m_guest(source.identifier())
+    : m_guest(source)
     , m_guest_fs(source.fs())
     , m_host_custody(host_custody)
     , m_flags(flags)
@@ -731,11 +743,18 @@ String VFS::Mount::absolute_path() const
     return m_host_custody->absolute_path();
 }
 
-InodeIdentifier VFS::Mount::host() const
+Inode* VFS::Mount::host()
 {
     if (!m_host_custody)
-        return {};
-    return m_host_custody->inode().identifier();
+        return nullptr;
+    return &m_host_custody->inode();
+}
+
+const Inode* VFS::Mount::host() const
+{
+    if (!m_host_custody)
+        return nullptr;
+    return &m_host_custody->inode();
 }
 
 void VFS::for_each_mount(Function<void(const Mount&)> callback) const
@@ -887,8 +906,8 @@ KResultOr<NonnullRefPtr<Custody>> VFS::resolve_path_without_veil(StringView path
 
         // See if there's something mounted on the child; in that case
         // we would need to return the guest inode, not the host inode.
-        if (auto mount = find_mount_for_host(child_inode->identifier())) {
-            child_inode = get_inode(mount->guest());
+        if (auto mount = find_mount_for_host(*child_inode)) {
+            child_inode = mount->guest();
             mount_flags_for_child = mount->flags();
         }
 

+ 9 - 7
Kernel/FileSystem/VirtualFileSystem.h

@@ -58,8 +58,11 @@ public:
         Mount(FS&, Custody* host_custody, int flags);
         Mount(Inode& source, Custody& host_custody, int flags);
 
-        InodeIdentifier host() const;
-        InodeIdentifier guest() const { return m_guest; }
+        const Inode* host() const;
+        Inode* host();
+
+        const Inode& guest() const { return *m_guest; }
+        Inode& guest() { return *m_guest; }
 
         const FS& guest_fs() const { return *m_guest_fs; }
 
@@ -69,8 +72,7 @@ public:
         void set_flags(int flags) { m_flags = flags; }
 
     private:
-        InodeIdentifier m_host;
-        InodeIdentifier m_guest;
+        NonnullRefPtr<Inode> m_guest;
         NonnullRefPtr<FS> m_guest_fs;
         RefPtr<Custody> m_host_custody;
         int m_flags;
@@ -85,7 +87,7 @@ public:
     KResult mount(FS&, Custody& mount_point, int flags);
     KResult bind_mount(Custody& source, Custody& mount_point, int flags);
     KResult remount(Custody& mount_point, int new_flags);
-    KResult unmount(InodeIdentifier guest_inode_id);
+    KResult unmount(Inode& guest_inode);
 
     KResultOr<NonnullRefPtr<FileDescription>> open(StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> = {});
     KResultOr<NonnullRefPtr<FileDescription>> create(StringView path, int options, mode_t mode, Custody& parent_custody, Optional<UidAndGid> = {});
@@ -122,13 +124,13 @@ private:
     const UnveiledPath* find_matching_unveiled_path(StringView path);
     KResult validate_path_against_process_veil(StringView path, int options);
 
-    RefPtr<Inode> get_inode(InodeIdentifier);
-
     bool is_vfs_root(InodeIdentifier) const;
 
     void traverse_directory_inode(Inode&, Function<bool(const FS::DirectoryEntry&)>);
 
+    Mount* find_mount_for_host(Inode&);
     Mount* find_mount_for_host(InodeIdentifier);
+    Mount* find_mount_for_guest(Inode&);
     Mount* find_mount_for_guest(InodeIdentifier);
 
     Lock m_lock { "VFSLock" };

+ 5 - 5
Kernel/Process.cpp

@@ -4309,12 +4309,12 @@ int Process::sys$umount(const char* user_mountpoint, size_t mountpoint_length)
     if (mountpoint.is_error())
         return mountpoint.error();
 
-    auto metadata_or_error = VFS::the().lookup_metadata(mountpoint.value(), current_directory());
-    if (metadata_or_error.is_error())
-        return metadata_or_error.error();
+    auto custody_or_error = VFS::the().resolve_path(mountpoint.value(), current_directory());
+    if (custody_or_error.is_error())
+        return custody_or_error.error();
 
-    auto guest_inode_id = metadata_or_error.value().inode;
-    return VFS::the().unmount(guest_inode_id);
+    auto& guest_inode = custody_or_error.value()->inode();
+    return VFS::the().unmount(guest_inode);
 }
 
 void Process::FileDescriptionAndFlags::clear()