diff options
author | sin-ack <sin-ack@users.noreply.github.com> | 2021-05-12 19:17:51 +0000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-12 22:38:20 +0200 |
commit | fe5ca6ca276ad452a16215031fb395b4f5bef048 (patch) | |
tree | 100ae8dbf8d2b1cee4125cf335017a021c63093f /Kernel/FileSystem/Inode.cpp | |
parent | 2de11b0dc8bbaa0c264a7e6dbb32b5481a337fb8 (diff) | |
download | serenity-fe5ca6ca276ad452a16215031fb395b4f5bef048.zip |
Kernel: Implement multi-watch InodeWatcher :^)
This patch modifies InodeWatcher to switch to a one watcher, multiple
watches architecture. The following changes have been made:
- The watch_file syscall is removed, and in its place the
create_iwatcher, iwatcher_add_watch and iwatcher_remove_watch calls
have been added.
- InodeWatcher now holds multiple WatchDescriptions for each file that
is being watched.
- The InodeWatcher file descriptor can be read from to receive events on
all watched files.
Co-authored-by: Gunnar Beutner <gunnar@beutner.name>
Diffstat (limited to 'Kernel/FileSystem/Inode.cpp')
-rw-r--r-- | Kernel/FileSystem/Inode.cpp | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/Kernel/FileSystem/Inode.cpp b/Kernel/FileSystem/Inode.cpp index 2adef0aa6e..e1fcee8eb2 100644 --- a/Kernel/FileSystem/Inode.cpp +++ b/Kernel/FileSystem/Inode.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2021, sin-ack <sin-ack@protonmail.com> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -109,6 +110,10 @@ Inode::~Inode() { ScopedSpinLock all_inodes_lock(s_all_inodes_lock); all_with_lock().remove(this); + + for (auto& watcher : m_watchers) { + watcher->unregister_by_inode({}, identifier()); + } } void Inode::will_be_destroyed() @@ -211,24 +216,47 @@ void Inode::set_metadata_dirty(bool metadata_dirty) // FIXME: Maybe we should hook into modification events somewhere else, I'm not sure where. // We don't always end up on this particular code path, for instance when writing to an ext2fs file. for (auto& watcher : m_watchers) { - watcher->notify_inode_event({}, InodeWatcherEvent::Type::Modified); + watcher->notify_inode_event({}, identifier(), InodeWatcherEvent::Type::MetadataModified); } } } -void Inode::did_add_child(const InodeIdentifier& child_id) +void Inode::did_add_child(InodeIdentifier const&, String const& name) +{ + Locker locker(m_lock); + + for (auto& watcher : m_watchers) { + watcher->notify_inode_event({}, identifier(), InodeWatcherEvent::Type::ChildCreated, name); + } +} + +void Inode::did_remove_child(InodeIdentifier const&, String const& name) +{ + Locker locker(m_lock); + + if (name == "." || name == "..") { + // These are just aliases and are not interesting to userspace. + return; + } + + for (auto& watcher : m_watchers) { + watcher->notify_inode_event({}, identifier(), InodeWatcherEvent::Type::ChildDeleted, name); + } +} + +void Inode::did_modify_contents() { Locker locker(m_lock); for (auto& watcher : m_watchers) { - watcher->notify_child_added({}, child_id); + watcher->notify_inode_event({}, identifier(), InodeWatcherEvent::Type::ContentModified); } } -void Inode::did_remove_child(const InodeIdentifier& child_id) +void Inode::did_delete_self() { Locker locker(m_lock); for (auto& watcher : m_watchers) { - watcher->notify_child_removed({}, child_id); + watcher->notify_inode_event({}, identifier(), InodeWatcherEvent::Type::Deleted); } } |