1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 10:47:36 +00:00

Kernel: Port mounts to reference inodes directly

...instead of going through their identifiers. See the previous commit for
reasoning.
This commit is contained in:
Sergey Bugaev 2020-06-25 00:16:24 +03:00 committed by Andreas Kling
parent df66c28479
commit 6efbbcd4ba
9 changed files with 64 additions and 45 deletions

View file

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

View file

@ -130,9 +130,9 @@ private:
virtual const char* class_name() const override; virtual const char* class_name() const override;
virtual NonnullRefPtr<Inode> root_inode() 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); 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); 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; virtual void flush_writes() override;
BlockIndex first_block_index() const; BlockIndex first_block_index() const;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -58,8 +58,11 @@ public:
Mount(FS&, Custody* host_custody, int flags); Mount(FS&, Custody* host_custody, int flags);
Mount(Inode& source, Custody& host_custody, int flags); Mount(Inode& source, Custody& host_custody, int flags);
InodeIdentifier host() const; const Inode* host() const;
InodeIdentifier guest() const { return m_guest; } Inode* host();
const Inode& guest() const { return *m_guest; }
Inode& guest() { return *m_guest; }
const FS& guest_fs() const { return *m_guest_fs; } const FS& guest_fs() const { return *m_guest_fs; }
@ -69,8 +72,7 @@ public:
void set_flags(int flags) { m_flags = flags; } void set_flags(int flags) { m_flags = flags; }
private: private:
InodeIdentifier m_host; NonnullRefPtr<Inode> m_guest;
InodeIdentifier m_guest;
NonnullRefPtr<FS> m_guest_fs; NonnullRefPtr<FS> m_guest_fs;
RefPtr<Custody> m_host_custody; RefPtr<Custody> m_host_custody;
int m_flags; int m_flags;
@ -85,7 +87,7 @@ public:
KResult mount(FS&, Custody& mount_point, int flags); KResult mount(FS&, Custody& mount_point, int flags);
KResult bind_mount(Custody& source, Custody& mount_point, int flags); KResult bind_mount(Custody& source, Custody& mount_point, int flags);
KResult remount(Custody& mount_point, int new_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>> 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> = {}); 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); const UnveiledPath* find_matching_unveiled_path(StringView path);
KResult validate_path_against_process_veil(StringView path, int options); KResult validate_path_against_process_veil(StringView path, int options);
RefPtr<Inode> get_inode(InodeIdentifier);
bool is_vfs_root(InodeIdentifier) const; bool is_vfs_root(InodeIdentifier) const;
void traverse_directory_inode(Inode&, Function<bool(const FS::DirectoryEntry&)>); 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_host(InodeIdentifier);
Mount* find_mount_for_guest(Inode&);
Mount* find_mount_for_guest(InodeIdentifier); Mount* find_mount_for_guest(InodeIdentifier);
Lock m_lock { "VFSLock" }; Lock m_lock { "VFSLock" };

View file

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