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:
parent
df66c28479
commit
6efbbcd4ba
9 changed files with 64 additions and 45 deletions
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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" };
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue