summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/FileSystem/DevPtsFS.cpp27
-rw-r--r--Kernel/FileSystem/DevPtsFS.h9
-rw-r--r--Kernel/FileSystem/Ext2FileSystem.cpp37
-rw-r--r--Kernel/FileSystem/Ext2FileSystem.h9
-rw-r--r--Kernel/FileSystem/FileSystem.h10
-rw-r--r--Kernel/FileSystem/Inode.h3
-rw-r--r--Kernel/FileSystem/InodeIdentifier.h2
-rw-r--r--Kernel/FileSystem/ProcFS.cpp38
-rw-r--r--Kernel/FileSystem/ProcFS.h11
-rw-r--r--Kernel/FileSystem/TmpFS.cpp113
-rw-r--r--Kernel/FileSystem/TmpFS.h10
-rw-r--r--Kernel/FileSystem/VirtualFileSystem.cpp24
12 files changed, 133 insertions, 160 deletions
diff --git a/Kernel/FileSystem/DevPtsFS.cpp b/Kernel/FileSystem/DevPtsFS.cpp
index 4b86dc6a1d..67e1e1525c 100644
--- a/Kernel/FileSystem/DevPtsFS.cpp
+++ b/Kernel/FileSystem/DevPtsFS.cpp
@@ -75,19 +75,9 @@ static unsigned pty_index_to_inode_index(unsigned pty_index)
return pty_index + 2;
}
-InodeIdentifier DevPtsFS::root_inode() const
+NonnullRefPtr<Inode> DevPtsFS::root_inode() const
{
- return { fsid(), 1 };
-}
-
-KResultOr<NonnullRefPtr<Inode>> DevPtsFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, uid_t, gid_t)
-{
- return KResult(-EROFS);
-}
-
-KResult DevPtsFS::create_directory(InodeIdentifier, const String&, mode_t, uid_t, gid_t)
-{
- return KResult(-EROFS);
+ return *m_root_inode;
}
RefPtr<Inode> DevPtsFS::get_inode(InodeIdentifier inode_id) const
@@ -175,11 +165,13 @@ RefPtr<Inode> DevPtsFSInode::lookup(StringView name)
ASSERT(identifier().index() == 1);
if (name == "." || name == "..")
- return fs().get_inode(identifier());
+ return this;
+
+ auto& fs = static_cast<DevPtsFS&>(this->fs());
auto pty_index = name.to_uint();
if (pty_index.has_value() && ptys->contains(pty_index.value())) {
- return fs().get_inode({ fsid(), pty_index_to_inode_index(pty_index.value()) });
+ return fs.get_inode({ fsid(), pty_index_to_inode_index(pty_index.value()) });
}
return {};
@@ -189,7 +181,12 @@ void DevPtsFSInode::flush_metadata()
{
}
-KResult DevPtsFSInode::add_child(InodeIdentifier, const StringView&, mode_t)
+KResult DevPtsFSInode::add_child(Inode&, const StringView&, mode_t)
+{
+ return KResult(-EROFS);
+}
+
+KResultOr<NonnullRefPtr<Inode>> DevPtsFSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t)
{
return KResult(-EROFS);
}
diff --git a/Kernel/FileSystem/DevPtsFS.h b/Kernel/FileSystem/DevPtsFS.h
index 2b97f105d7..083b1bdb98 100644
--- a/Kernel/FileSystem/DevPtsFS.h
+++ b/Kernel/FileSystem/DevPtsFS.h
@@ -36,6 +36,8 @@ class SlavePTY;
class DevPtsFSInode;
class DevPtsFS final : public FS {
+ friend class DevPtsFSInode;
+
public:
virtual ~DevPtsFS() override;
static NonnullRefPtr<DevPtsFS> create();
@@ -43,9 +45,7 @@ public:
virtual bool initialize() override;
virtual const char* class_name() const override { return "DevPtsFS"; }
- virtual InodeIdentifier root_inode() const override;
- virtual KResultOr<NonnullRefPtr<Inode>> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t) override;
- virtual KResult create_directory(InodeIdentifier parent_inode, const String& name, mode_t, uid_t, gid_t) override;
+ virtual NonnullRefPtr<Inode> root_inode() const override;
virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
static void register_slave_pty(SlavePTY&);
@@ -73,7 +73,8 @@ private:
virtual RefPtr<Inode> lookup(StringView name) override;
virtual void flush_metadata() override;
virtual ssize_t write_bytes(off_t, ssize_t, const u8* buffer, FileDescription*) override;
- virtual KResult add_child(InodeIdentifier child_id, const StringView& name, mode_t) override;
+ virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override;
+ virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
virtual KResult remove_child(const StringView& name) override;
virtual size_t directory_entry_count() const override;
virtual KResult chmod(mode_t) override;
diff --git a/Kernel/FileSystem/Ext2FileSystem.cpp b/Kernel/FileSystem/Ext2FileSystem.cpp
index e1533fc3a6..aa4b08eb41 100644
--- a/Kernel/FileSystem/Ext2FileSystem.cpp
+++ b/Kernel/FileSystem/Ext2FileSystem.cpp
@@ -150,9 +150,9 @@ const char* Ext2FS::class_name() const
return "Ext2FS";
}
-InodeIdentifier Ext2FS::root_inode() const
+NonnullRefPtr<Inode> Ext2FS::root_inode() const
{
- return { fsid(), EXT2_ROOT_INO };
+ return *get_inode({ fsid(), EXT2_ROOT_INO });
}
bool Ext2FS::find_block_containing_inode(unsigned inode, unsigned& block_index, unsigned& offset) const
@@ -935,7 +935,14 @@ bool Ext2FSInode::write_directory(const Vector<FS::DirectoryEntry>& entries)
return static_cast<size_t>(nwritten) == directory_data.size();
}
-KResult Ext2FSInode::add_child(InodeIdentifier child_id, const StringView& name, mode_t mode)
+KResultOr<NonnullRefPtr<Inode>> Ext2FSInode::create_child(const String& name, mode_t mode, dev_t dev, uid_t uid, gid_t gid)
+{
+ if (mode & S_IFDIR)
+ return fs().create_directory(identifier(), name, mode, uid, gid);
+ return fs().create_inode(identifier(), name, mode, 0, dev, uid, gid);
+}
+
+KResult Ext2FSInode::add_child(Inode& child, const StringView& name, mode_t mode)
{
LOCKER(m_lock);
ASSERT(is_directory());
@@ -944,7 +951,7 @@ KResult Ext2FSInode::add_child(InodeIdentifier child_id, const StringView& name,
return KResult(-ENAMETOOLONG);
#ifdef EXT2_DEBUG
- dbg() << "Ext2FSInode::add_child(): Adding inode " << child_id.index() << " with name '" << name << "' and mode " << mode << " to directory " << index();
+ dbg() << "Ext2FSInode::add_child(): Adding inode " << child.index() << " with name '" << name << "' and mode " << mode << " to directory " << index();
#endif
Vector<FS::DirectoryEntry> entries;
@@ -966,17 +973,14 @@ KResult Ext2FSInode::add_child(InodeIdentifier child_id, const StringView& name,
return KResult(-EEXIST);
}
- auto child_inode = fs().get_inode(child_id);
- if (child_inode) {
- result = child_inode->increment_link_count();
- if (result.is_error())
- return result;
- }
+ result = child.increment_link_count();
+ if (result.is_error())
+ return result;
- entries.empend(name.characters_without_null_termination(), name.length(), child_id, to_ext2_file_type(mode));
+ entries.empend(name.characters_without_null_termination(), name.length(), child.identifier(), to_ext2_file_type(mode));
bool success = write_directory(entries);
if (success)
- m_lookup_cache.set(name, child_id.index());
+ m_lookup_cache.set(name, child.index());
return KSuccess;
}
@@ -1405,11 +1409,6 @@ KResultOr<NonnullRefPtr<Inode>> Ext2FS::create_inode(InodeIdentifier parent_id,
return KResult(-ENOSPC);
}
- // Try adding it to the directory first, in case the name is already in use.
- auto result = parent_inode->add_child({ fsid(), inode_id }, name, mode);
- if (result.is_error())
- return result;
-
auto blocks = allocate_blocks(group_index_from_inode(inode_id), needed_blocks);
ASSERT(blocks.size() == needed_blocks);
@@ -1458,6 +1457,10 @@ KResultOr<NonnullRefPtr<Inode>> Ext2FS::create_inode(InodeIdentifier parent_id,
auto inode = get_inode({ fsid(), inode_id });
// If we've already computed a block list, no sense in throwing it away.
static_cast<Ext2FSInode&>(*inode).m_block_list = move(blocks);
+
+ auto result = parent_inode->add_child(*inode, name, mode);
+ ASSERT(result.is_success());
+
return inode.release_nonnull();
}
diff --git a/Kernel/FileSystem/Ext2FileSystem.h b/Kernel/FileSystem/Ext2FileSystem.h
index 1862a286b2..e1aad47093 100644
--- a/Kernel/FileSystem/Ext2FileSystem.h
+++ b/Kernel/FileSystem/Ext2FileSystem.h
@@ -63,7 +63,8 @@ private:
virtual RefPtr<Inode> lookup(StringView name) override;
virtual void flush_metadata() override;
virtual ssize_t write_bytes(off_t, ssize_t, const u8* data, FileDescription*) override;
- virtual KResult add_child(InodeIdentifier child_id, const StringView& name, mode_t) override;
+ virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override;
+ virtual KResult add_child(Inode& child, const StringView& name, mode_t) override;
virtual KResult remove_child(const StringView& name) override;
virtual int set_atime(time_t) override;
virtual int set_ctime(time_t) override;
@@ -128,9 +129,9 @@ private:
bool flush_super_block();
virtual const char* class_name() const override;
- virtual InodeIdentifier root_inode() const override;
- virtual KResultOr<NonnullRefPtr<Inode>> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t) override;
- virtual KResult create_directory(InodeIdentifier parent_inode, const String& name, mode_t, uid_t, gid_t) override;
+ virtual NonnullRefPtr<Inode> root_inode() const override;
+ 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;
diff --git a/Kernel/FileSystem/FileSystem.h b/Kernel/FileSystem/FileSystem.h
index fb33d9df95..b19507bef7 100644
--- a/Kernel/FileSystem/FileSystem.h
+++ b/Kernel/FileSystem/FileSystem.h
@@ -56,7 +56,7 @@ public:
virtual bool initialize() = 0;
virtual const char* class_name() const = 0;
- virtual InodeIdentifier root_inode() const = 0;
+ virtual NonnullRefPtr<Inode> root_inode() const = 0;
virtual bool supports_watchers() const { return false; }
bool is_readonly() const { return m_readonly; }
@@ -78,9 +78,6 @@ public:
u8 file_type { 0 };
};
- virtual KResultOr<NonnullRefPtr<Inode>> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t) = 0;
- virtual KResult create_directory(InodeIdentifier parent_inode, const String& name, mode_t, uid_t, gid_t) = 0;
-
virtual RefPtr<Inode> get_inode(InodeIdentifier) const = 0;
virtual void flush_writes() { }
@@ -112,11 +109,6 @@ inline const FS* InodeIdentifier::fs() const
return FS::from_fsid(m_fsid);
}
-inline bool InodeIdentifier::is_root_inode() const
-{
- return (*this) == fs()->root_inode();
-}
-
}
namespace AK {
diff --git a/Kernel/FileSystem/Inode.h b/Kernel/FileSystem/Inode.h
index b34f2cb208..60c5c5fc52 100644
--- a/Kernel/FileSystem/Inode.h
+++ b/Kernel/FileSystem/Inode.h
@@ -72,7 +72,8 @@ public:
virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntry&)>) const = 0;
virtual RefPtr<Inode> lookup(StringView name) = 0;
virtual ssize_t write_bytes(off_t, ssize_t, const u8* data, FileDescription*) = 0;
- virtual KResult add_child(InodeIdentifier child_id, const StringView& name, mode_t) = 0;
+ virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) = 0;
+ virtual KResult add_child(Inode&, const StringView& name, mode_t) = 0;
virtual KResult remove_child(const StringView& name) = 0;
virtual size_t directory_entry_count() const = 0;
virtual KResult chmod(mode_t) = 0;
diff --git a/Kernel/FileSystem/InodeIdentifier.h b/Kernel/FileSystem/InodeIdentifier.h
index 7152fca956..544e0faebd 100644
--- a/Kernel/FileSystem/InodeIdentifier.h
+++ b/Kernel/FileSystem/InodeIdentifier.h
@@ -62,8 +62,6 @@ public:
return m_fsid != other.m_fsid || m_index != other.m_index;
}
- bool is_root_inode() const;
-
String to_string() const { return String::format("%u:%u", m_fsid, m_index); }
private:
diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp
index 567774ccd6..604e279f30 100644
--- a/Kernel/FileSystem/ProcFS.cpp
+++ b/Kernel/FileSystem/ProcFS.cpp
@@ -1075,19 +1075,9 @@ const char* ProcFS::class_name() const
return "ProcFS";
}
-KResultOr<NonnullRefPtr<Inode>> ProcFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, uid_t, gid_t)
+NonnullRefPtr<Inode> ProcFS::root_inode() const
{
- return KResult(-EROFS);
-}
-
-KResult ProcFS::create_directory(InodeIdentifier, const String&, mode_t, uid_t, gid_t)
-{
- return KResult(-EROFS);
-}
-
-InodeIdentifier ProcFS::root_inode() const
-{
- return { fsid(), FI_Root };
+ return *m_root_inode;
}
RefPtr<Inode> ProcFS::get_inode(InodeIdentifier inode_id) const
@@ -1095,7 +1085,7 @@ RefPtr<Inode> ProcFS::get_inode(InodeIdentifier inode_id) const
#ifdef PROCFS_DEBUG
dbg() << "ProcFS::get_inode(" << inode_id.index() << ")";
#endif
- if (inode_id == root_inode())
+ if (inode_id == root_inode()->identifier())
return m_root_inode;
LOCKER(m_inodes_lock);
@@ -1340,7 +1330,7 @@ RefPtr<Inode> ProcFSInode::lookup(StringView name)
{
ASSERT(is_directory());
if (name == ".")
- return fs().get_inode(identifier());
+ return this;
if (name == "..")
return fs().get_inode(to_parent_id(identifier()));
@@ -1555,11 +1545,18 @@ InodeMetadata ProcFSProxyInode::metadata() const
return metadata;
}
-KResult ProcFSProxyInode::add_child(InodeIdentifier child_id, const StringView& name, mode_t mode)
+KResultOr<NonnullRefPtr<Inode>> ProcFSProxyInode::create_child(const String& name, mode_t mode, dev_t dev, uid_t uid, gid_t gid)
+{
+ if (!m_fd->inode())
+ return KResult(-EINVAL);
+ return m_fd->inode()->create_child(name, mode, dev, uid, gid);
+}
+
+KResult ProcFSProxyInode::add_child(Inode& child, const StringView& name, mode_t mode)
{
if (!m_fd->inode())
return KResult(-EINVAL);
- return m_fd->inode()->add_child(child_id, name, mode);
+ return m_fd->inode()->add_child(child, name, mode);
}
KResult ProcFSProxyInode::remove_child(const StringView& name)
@@ -1583,10 +1580,13 @@ size_t ProcFSProxyInode::directory_entry_count() const
return m_fd->inode()->directory_entry_count();
}
-KResult ProcFSInode::add_child(InodeIdentifier child_id, const StringView& name, mode_t)
+KResultOr<NonnullRefPtr<Inode>> ProcFSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t)
+{
+ return KResult(-EPERM);
+}
+
+KResult ProcFSInode::add_child(Inode&, const StringView&, mode_t)
{
- (void)child_id;
- (void)name;
return KResult(-EPERM);
}
diff --git a/Kernel/FileSystem/ProcFS.h b/Kernel/FileSystem/ProcFS.h
index d498c27b0a..280249897e 100644
--- a/Kernel/FileSystem/ProcFS.h
+++ b/Kernel/FileSystem/ProcFS.h
@@ -49,12 +49,9 @@ public:
virtual bool initialize() override;
virtual const char* class_name() const override;
- virtual InodeIdentifier root_inode() const override;
+ virtual NonnullRefPtr<Inode> root_inode() const override;
virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
- virtual KResultOr<NonnullRefPtr<Inode>> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t) override;
- virtual KResult create_directory(InodeIdentifier parent_id, const String& name, mode_t, uid_t, gid_t) 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);
@@ -105,7 +102,8 @@ private:
virtual RefPtr<Inode> lookup(StringView name) override;
virtual void flush_metadata() override;
virtual ssize_t write_bytes(off_t, ssize_t, const u8* buffer, FileDescription*) override;
- virtual KResult add_child(InodeIdentifier child_id, const StringView& name, mode_t) override;
+ virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override;
+ virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
virtual KResult remove_child(const StringView& name) override;
virtual size_t directory_entry_count() const override;
virtual KResult chmod(mode_t) override;
@@ -131,7 +129,8 @@ private:
virtual RefPtr<Inode> lookup(StringView name) override;
virtual void flush_metadata() override {};
virtual ssize_t write_bytes(off_t, ssize_t, const u8*, FileDescription*) override { ASSERT_NOT_REACHED(); }
- virtual KResult add_child(InodeIdentifier child_id, const StringView& name, mode_t) override;
+ virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override;
+ virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
virtual KResult remove_child(const StringView& name) override;
virtual size_t directory_entry_count() const override;
virtual KResult chmod(mode_t) override { return KResult(-EINVAL); }
diff --git a/Kernel/FileSystem/TmpFS.cpp b/Kernel/FileSystem/TmpFS.cpp
index 86d141010a..66dec6e272 100644
--- a/Kernel/FileSystem/TmpFS.cpp
+++ b/Kernel/FileSystem/TmpFS.cpp
@@ -49,10 +49,11 @@ bool TmpFS::initialize()
return true;
}
-InodeIdentifier TmpFS::root_inode() const
+NonnullRefPtr<Inode> TmpFS::root_inode() const
{
ASSERT(!m_root_inode.is_null());
- return m_root_inode->identifier();
+
+ return *m_root_inode;
}
void TmpFS::register_inode(TmpFSInode& inode)
@@ -90,49 +91,6 @@ RefPtr<Inode> TmpFS::get_inode(InodeIdentifier identifier) const
return it->value;
}
-KResultOr<NonnullRefPtr<Inode>> TmpFS::create_inode(InodeIdentifier parent_id, const String& name, mode_t mode, off_t size, dev_t dev, uid_t uid, gid_t gid)
-{
- LOCKER(m_lock);
- ASSERT(parent_id.fsid() == fsid());
-
- ASSERT(size == 0);
- ASSERT(dev == 0);
-
- struct timeval now;
- kgettimeofday(now);
-
- InodeMetadata metadata;
- metadata.mode = mode;
- metadata.uid = uid;
- metadata.gid = gid;
- metadata.atime = now.tv_sec;
- metadata.ctime = now.tv_sec;
- metadata.mtime = now.tv_sec;
-
- auto inode = TmpFSInode::create(*this, metadata, parent_id);
-
- auto it = m_inodes.find(parent_id.index());
- ASSERT(it != m_inodes.end());
- auto parent_inode = it->value;
-
- auto result = parent_inode->add_child(inode->identifier(), name, mode);
- if (result.is_error())
- return result;
-
- return inode;
-}
-
-KResult TmpFS::create_directory(InodeIdentifier parent_id, const String& name, mode_t mode, uid_t uid, gid_t gid)
-{
- // Ensure it's a directory.
- mode &= ~S_IFMT;
- mode |= S_IFDIR;
- auto result = create_inode(parent_id, name, mode, 0, 0, uid, gid);
- if (result.is_error())
- return result.error();
- return KSuccess;
-}
-
TmpFSInode::TmpFSInode(TmpFS& fs, InodeMetadata metadata, InodeIdentifier parent)
: Inode(fs, fs.next_inode_index())
, m_metadata(metadata)
@@ -251,7 +209,7 @@ RefPtr<Inode> TmpFSInode::lookup(StringView name)
ASSERT(is_directory());
if (name == ".")
- return fs().get_inode(identifier());
+ return this;
if (name == "..")
return fs().get_inode(m_parent);
@@ -268,6 +226,12 @@ size_t TmpFSInode::directory_entry_count() const
return 2 + m_children.size();
}
+void TmpFSInode::notify_watchers()
+{
+ set_metadata_dirty(true);
+ set_metadata_dirty(false);
+}
+
void TmpFSInode::flush_metadata()
{
// We don't really have any metadata that could become dirty.
@@ -283,8 +247,7 @@ KResult TmpFSInode::chmod(mode_t mode)
LOCKER(m_lock);
m_metadata.mode = mode;
- set_metadata_dirty(true);
- set_metadata_dirty(false);
+ notify_watchers();
return KSuccess;
}
@@ -294,25 +257,47 @@ KResult TmpFSInode::chown(uid_t uid, gid_t gid)
m_metadata.uid = uid;
m_metadata.gid = gid;
- set_metadata_dirty(true);
- set_metadata_dirty(false);
+ notify_watchers();
return KSuccess;
}
-KResult TmpFSInode::add_child(InodeIdentifier child_id, const StringView& name, mode_t)
+KResultOr<NonnullRefPtr<Inode>> TmpFSInode::create_child(const String& name, mode_t mode, dev_t dev, uid_t uid, gid_t gid)
+{
+ LOCKER(m_lock);
+
+ // TODO: Support creating devices on TmpFS.
+ if (dev != 0)
+ return KResult(-ENOTSUP);
+
+ struct timeval now;
+ kgettimeofday(now);
+
+ InodeMetadata metadata;
+ metadata.mode = mode;
+ metadata.uid = uid;
+ metadata.gid = gid;
+ metadata.atime = now.tv_sec;
+ metadata.ctime = now.tv_sec;
+ metadata.mtime = now.tv_sec;
+
+ auto child = TmpFSInode::create(fs(), metadata, identifier());
+ auto result = add_child(child, name, mode);
+ if (result.is_error())
+ return result;
+ return child;
+}
+
+KResult TmpFSInode::add_child(Inode& child, const StringView& name, mode_t)
{
LOCKER(m_lock);
ASSERT(is_directory());
- ASSERT(child_id.fsid() == fsid());
+ ASSERT(child.fsid() == fsid());
String owned_name = name;
- FS::DirectoryEntry entry = { owned_name.characters(), owned_name.length(), child_id, 0 };
- auto child_tmp = fs().get_inode(child_id);
- auto child = static_ptr_cast<TmpFSInode>(child_tmp.release_nonnull());
+ FS::DirectoryEntry entry = { owned_name.characters(), owned_name.length(), child.identifier(), 0 };
- m_children.set(owned_name, { entry, move(child) });
- set_metadata_dirty(true);
- set_metadata_dirty(false);
+ m_children.set(owned_name, { entry, static_cast<TmpFSInode&>(child) });
+ notify_watchers();
return KSuccess;
}
@@ -328,8 +313,7 @@ KResult TmpFSInode::remove_child(const StringView& name)
if (it == m_children.end())
return KResult(-ENOENT);
m_children.remove(it);
- set_metadata_dirty(true);
- set_metadata_dirty(false);
+ notify_watchers();
return KSuccess;
}
@@ -356,8 +340,7 @@ KResult TmpFSInode::truncate(u64 size)
size_t old_size = m_metadata.size;
m_metadata.size = size;
- set_metadata_dirty(true);
- set_metadata_dirty(false);
+ notify_watchers();
if (old_size != (size_t)size) {
inode_size_changed(old_size, size);
@@ -383,8 +366,7 @@ int TmpFSInode::set_ctime(time_t time)
LOCKER(m_lock);
m_metadata.ctime = time;
- set_metadata_dirty(true);
- set_metadata_dirty(false);
+ notify_watchers();
return KSuccess;
}
@@ -393,8 +375,7 @@ int TmpFSInode::set_mtime(time_t time)
LOCKER(m_lock);
m_metadata.mtime = time;
- set_metadata_dirty(true);
- set_metadata_dirty(false);
+ notify_watchers();
return KSuccess;
}
diff --git a/Kernel/FileSystem/TmpFS.h b/Kernel/FileSystem/TmpFS.h
index b90aac1f47..a2bc5d8181 100644
--- a/Kernel/FileSystem/TmpFS.h
+++ b/Kernel/FileSystem/TmpFS.h
@@ -48,12 +48,9 @@ public:
virtual bool supports_watchers() const override { return true; }
- virtual InodeIdentifier root_inode() const override;
+ virtual NonnullRefPtr<Inode> root_inode() const override;
virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
- virtual KResultOr<NonnullRefPtr<Inode>> create_inode(InodeIdentifier parent_id, const String& name, mode_t, off_t size, dev_t, uid_t, gid_t) override;
- virtual KResult create_directory(InodeIdentifier parent_id, const String& name, mode_t, uid_t, gid_t) override;
-
private:
TmpFS();
@@ -83,7 +80,8 @@ public:
virtual RefPtr<Inode> lookup(StringView name) override;
virtual void flush_metadata() override;
virtual ssize_t write_bytes(off_t, ssize_t, const u8* buffer, FileDescription*) override;
- virtual KResult add_child(InodeIdentifier child_id, const StringView& name, mode_t) override;
+ virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override;
+ virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
virtual KResult remove_child(const StringView& name) override;
virtual size_t directory_entry_count() const override;
virtual KResult chmod(mode_t) override;
@@ -99,6 +97,8 @@ private:
static NonnullRefPtr<TmpFSInode> create(TmpFS&, InodeMetadata metadata, InodeIdentifier parent);
static NonnullRefPtr<TmpFSInode> create_root(TmpFS&);
+ void notify_watchers();
+
InodeMetadata m_metadata;
InodeIdentifier m_parent;
diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp
index 29766e3557..b6d9a2cd0b 100644
--- a/Kernel/FileSystem/VirtualFileSystem.cpp
+++ b/Kernel/FileSystem/VirtualFileSystem.cpp
@@ -137,15 +137,14 @@ bool VFS::mount_root(FS& file_system)
Mount mount { file_system, nullptr, root_mount_flags };
- auto root_inode_id = mount.guest().fs()->root_inode();
- auto root_inode = mount.guest().fs()->get_inode(root_inode_id);
+ auto root_inode = file_system.root_inode();
if (!root_inode->is_directory()) {
- klog() << "VFS: root inode (" << String::format("%02u", root_inode_id.fsid()) << ":" << String::format("%08u", root_inode_id.index()) << ") for / is not a directory :(";
+ klog() << "VFS: root inode (" << String::format("%02u", file_system.fsid()) << ":" << String::format("%08u", root_inode->index()) << ") for / is not a directory :(";
return false;
}
m_root_inode = move(root_inode);
- klog() << "VFS: mounted root from " << m_root_inode->fs().class_name() << " (" << static_cast<FileBackedFS&>(m_root_inode->fs()).file_description().absolute_path() << ")";
+ klog() << "VFS: mounted root from " << file_system.class_name() << " (" << static_cast<FileBackedFS&>(file_system).file_description().absolute_path() << ")";
m_mounts.append(move(mount));
return true;
@@ -184,7 +183,8 @@ void VFS::traverse_directory_inode(Inode& dir_inode, Function<bool(const FS::Dir
resolved_inode = entry.inode;
// FIXME: This is now broken considering chroot and bind mounts.
- if (dir_inode.identifier().is_root_inode() && !is_vfs_root(dir_inode.identifier()) && !strcmp(entry.name, "..")) {
+ bool is_root_inode = dir_inode.identifier() == dir_inode.fs().root_inode()->identifier();
+ 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();
@@ -321,7 +321,7 @@ KResult VFS::mknod(StringView path, mode_t mode, dev_t dev, Custody& base)
LexicalPath p(path);
dbg() << "VFS::mknod: '" << p.basename() << "' mode=" << mode << " dev=" << dev << " in " << parent_inode.identifier();
- return parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), mode, 0, dev, Process::current->uid(), Process::current->gid()).result();
+ return parent_inode.create_child(p.basename(), mode, dev, Process::current->uid(), Process::current->gid()).result();
}
KResultOr<NonnullRefPtr<FileDescription>> VFS::create(StringView path, int options, mode_t mode, Custody& parent_custody, Optional<UidAndGid> owner)
@@ -347,7 +347,7 @@ KResultOr<NonnullRefPtr<FileDescription>> VFS::create(StringView path, int optio
#endif
uid_t uid = owner.has_value() ? owner.value().uid : Process::current->uid();
gid_t gid = owner.has_value() ? owner.value().gid : Process::current->gid();
- auto inode_or_error = parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), mode, 0, 0, uid, gid);
+ auto inode_or_error = parent_inode.create_child(p.basename(), mode, 0, uid, gid);
if (inode_or_error.is_error())
return inode_or_error.error();
@@ -386,7 +386,7 @@ KResult VFS::mkdir(StringView path, mode_t mode, Custody& base)
#ifdef VFS_DEBUG
dbg() << "VFS::mkdir: '" << p.basename() << "' in " << parent_inode.identifier();
#endif
- return parent_inode.fs().create_directory(parent_inode.identifier(), p.basename(), mode, Process::current->uid(), Process::current->gid());
+ return parent_inode.create_child(p.basename(), S_IFDIR | mode, 0, Process::current->uid(), Process::current->gid()).result();
}
KResult VFS::access(StringView path, int mode, Custody& base)
@@ -506,7 +506,7 @@ KResult VFS::rename(StringView old_path, StringView new_path, Custody& base)
return result;
}
- auto result = new_parent_inode.add_child(old_inode.identifier(), new_basename, old_inode.mode());
+ auto result = new_parent_inode.add_child(old_inode, new_basename, old_inode.mode());
if (result.is_error())
return result;
@@ -593,7 +593,7 @@ KResult VFS::link(StringView old_path, StringView new_path, Custody& base)
if (parent_custody->is_readonly())
return KResult(-EROFS);
- return parent_inode.add_child(old_inode.identifier(), LexicalPath(new_path).basename(), old_inode.mode());
+ return parent_inode.add_child(old_inode, LexicalPath(new_path).basename(), old_inode.mode());
}
KResult VFS::unlink(StringView path, Custody& base)
@@ -650,7 +650,7 @@ KResult VFS::symlink(StringView target, StringView linkpath, Custody& base)
LexicalPath p(linkpath);
dbg() << "VFS::symlink: '" << p.basename() << "' (-> '" << target << "') in " << parent_inode.identifier();
- auto inode_or_error = parent_inode.fs().create_inode(parent_inode.identifier(), p.basename(), 0120644, 0, 0, Process::current->uid(), Process::current->gid());
+ auto inode_or_error = parent_inode.create_child(p.basename(), S_IFLNK | 0644, 0, Process::current->uid(), Process::current->gid());
if (inode_or_error.is_error())
return inode_or_error.error();
auto& inode = inode_or_error.value();
@@ -709,7 +709,7 @@ RefPtr<Inode> VFS::get_inode(InodeIdentifier inode_id)
}
VFS::Mount::Mount(FS& guest_fs, Custody* host_custody, int flags)
- : m_guest(guest_fs.root_inode())
+ : m_guest(guest_fs.root_inode()->identifier())
, m_guest_fs(guest_fs)
, m_host_custody(host_custody)
, m_flags(flags)