diff options
author | Sergey Bugaev <bugaevc@serenityos.org> | 2020-06-25 00:16:24 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-06-25 15:49:04 +0200 |
commit | 6efbbcd4baf24a1fa599245a23012ef0ecc9441e (patch) | |
tree | 0b5aed2c7285451fb3ecc96bf33b407b62277f43 /Kernel | |
parent | df66c28479e9206adeef1f40f8c0e448c8aea77e (diff) | |
download | serenity-6efbbcd4baf24a1fa599245a23012ef0ecc9441e.zip |
Kernel: Port mounts to reference inodes directly
...instead of going through their identifiers. See the previous commit for
reasoning.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/FileSystem/DevPtsFS.h | 2 | ||||
-rw-r--r-- | Kernel/FileSystem/Ext2FileSystem.h | 2 | ||||
-rw-r--r-- | Kernel/FileSystem/FileSystem.h | 2 | ||||
-rw-r--r-- | Kernel/FileSystem/ProcFS.cpp | 4 | ||||
-rw-r--r-- | Kernel/FileSystem/ProcFS.h | 2 | ||||
-rw-r--r-- | Kernel/FileSystem/TmpFS.h | 2 | ||||
-rw-r--r-- | Kernel/FileSystem/VirtualFileSystem.cpp | 69 | ||||
-rw-r--r-- | Kernel/FileSystem/VirtualFileSystem.h | 16 | ||||
-rw-r--r-- | Kernel/Process.cpp | 10 |
9 files changed, 64 insertions, 45 deletions
diff --git a/Kernel/FileSystem/DevPtsFS.h b/Kernel/FileSystem/DevPtsFS.h index 083b1bdb98..214f3d3866 100644 --- a/Kernel/FileSystem/DevPtsFS.h +++ b/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; }; diff --git a/Kernel/FileSystem/Ext2FileSystem.h b/Kernel/FileSystem/Ext2FileSystem.h index e1aad47093..9073f46a21 100644 --- a/Kernel/FileSystem/Ext2FileSystem.h +++ b/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; diff --git a/Kernel/FileSystem/FileSystem.h b/Kernel/FileSystem/FileSystem.h index b19507bef7..8a7f3581da 100644 --- a/Kernel/FileSystem/FileSystem.h +++ b/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; } diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index 604e279f30..c06795aab5 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/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()); } diff --git a/Kernel/FileSystem/ProcFS.h b/Kernel/FileSystem/ProcFS.h index 280249897e..e57b45d85c 100644 --- a/Kernel/FileSystem/ProcFS.h +++ b/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; diff --git a/Kernel/FileSystem/TmpFS.h b/Kernel/FileSystem/TmpFS.h index a2bc5d8181..738851b369 100644 --- a/Kernel/FileSystem/TmpFS.h +++ b/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); diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index b6d9a2cd0b..3b3d0670ba 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/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(); } diff --git a/Kernel/FileSystem/VirtualFileSystem.h b/Kernel/FileSystem/VirtualFileSystem.h index ad7cfa5d85..3ca075431e 100644 --- a/Kernel/FileSystem/VirtualFileSystem.h +++ b/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" }; diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 687aa25025..dc773828d4 100644 --- a/Kernel/Process.cpp +++ b/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() |