diff options
-rw-r--r-- | Kernel/FileSystem/DevPtsFS.cpp | 27 | ||||
-rw-r--r-- | Kernel/FileSystem/DevPtsFS.h | 9 | ||||
-rw-r--r-- | Kernel/FileSystem/Ext2FileSystem.cpp | 37 | ||||
-rw-r--r-- | Kernel/FileSystem/Ext2FileSystem.h | 9 | ||||
-rw-r--r-- | Kernel/FileSystem/FileSystem.h | 10 | ||||
-rw-r--r-- | Kernel/FileSystem/Inode.h | 3 | ||||
-rw-r--r-- | Kernel/FileSystem/InodeIdentifier.h | 2 | ||||
-rw-r--r-- | Kernel/FileSystem/ProcFS.cpp | 38 | ||||
-rw-r--r-- | Kernel/FileSystem/ProcFS.h | 11 | ||||
-rw-r--r-- | Kernel/FileSystem/TmpFS.cpp | 113 | ||||
-rw-r--r-- | Kernel/FileSystem/TmpFS.h | 10 | ||||
-rw-r--r-- | Kernel/FileSystem/VirtualFileSystem.cpp | 24 |
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) |