summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorSergey Bugaev <bugaevc@serenityos.org>2020-06-25 00:16:24 +0300
committerAndreas Kling <kling@serenityos.org>2020-06-25 15:49:04 +0200
commit6efbbcd4baf24a1fa599245a23012ef0ecc9441e (patch)
tree0b5aed2c7285451fb3ecc96bf33b407b62277f43 /Kernel
parentdf66c28479e9206adeef1f40f8c0e448c8aea77e (diff)
downloadserenity-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.h2
-rw-r--r--Kernel/FileSystem/Ext2FileSystem.h2
-rw-r--r--Kernel/FileSystem/FileSystem.h2
-rw-r--r--Kernel/FileSystem/ProcFS.cpp4
-rw-r--r--Kernel/FileSystem/ProcFS.h2
-rw-r--r--Kernel/FileSystem/TmpFS.h2
-rw-r--r--Kernel/FileSystem/VirtualFileSystem.cpp69
-rw-r--r--Kernel/FileSystem/VirtualFileSystem.h16
-rw-r--r--Kernel/Process.cpp10
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()