mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 18:02:05 -05:00
Kernel: Add "child added" and "child removed" InodeWatcher events
The child name is not yet accessible to userspace, but will be in a future patch.
This commit is contained in:
parent
ea17d2d3da
commit
0d577ab781
6 changed files with 47 additions and 3 deletions
|
@ -981,6 +981,8 @@ KResult Ext2FSInode::add_child(Inode& child, const StringView& name, mode_t mode
|
|||
bool success = write_directory(entries);
|
||||
if (success)
|
||||
m_lookup_cache.set(name, child.index());
|
||||
|
||||
did_add_child(name);
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
|
@ -1022,6 +1024,8 @@ KResult Ext2FSInode::remove_child(const StringView& name)
|
|||
|
||||
auto child_inode = fs().get_inode(child_id);
|
||||
child_inode->decrement_link_count();
|
||||
|
||||
did_remove_child(name);
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
|
|
|
@ -215,6 +215,22 @@ void Inode::set_metadata_dirty(bool metadata_dirty)
|
|||
}
|
||||
}
|
||||
|
||||
void Inode::did_add_child(const String& name)
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
for (auto& watcher : m_watchers) {
|
||||
watcher->notify_child_added({}, name);
|
||||
}
|
||||
}
|
||||
|
||||
void Inode::did_remove_child(const String& name)
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
for (auto& watcher : m_watchers) {
|
||||
watcher->notify_child_removed({}, name);
|
||||
}
|
||||
}
|
||||
|
||||
KResult Inode::prepare_to_write_data()
|
||||
{
|
||||
// FIXME: It's a poor design that filesystems are expected to call this before writing out data.
|
||||
|
|
|
@ -122,6 +122,9 @@ protected:
|
|||
void inode_size_changed(size_t old_size, size_t new_size);
|
||||
KResult prepare_to_write_data();
|
||||
|
||||
void did_add_child(const String& name);
|
||||
void did_remove_child(const String& name);
|
||||
|
||||
mutable Lock m_lock { "Inode" };
|
||||
|
||||
private:
|
||||
|
|
|
@ -59,6 +59,7 @@ bool InodeWatcher::can_write(const FileDescription&, size_t) const
|
|||
|
||||
ssize_t InodeWatcher::read(FileDescription&, size_t, u8* buffer, ssize_t buffer_size)
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
ASSERT(!m_queue.is_empty() || !m_inode);
|
||||
|
||||
if (!m_inode)
|
||||
|
@ -85,7 +86,20 @@ String InodeWatcher::absolute_path(const FileDescription&) const
|
|||
|
||||
void InodeWatcher::notify_inode_event(Badge<Inode>, Event::Type event_type)
|
||||
{
|
||||
m_queue.enqueue({ event_type });
|
||||
LOCKER(m_lock);
|
||||
m_queue.enqueue({ event_type, {} });
|
||||
}
|
||||
|
||||
void InodeWatcher::notify_child_added(Badge<Inode>, const String& child_name)
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
m_queue.enqueue({ Event::Type::ChildAdded, child_name });
|
||||
}
|
||||
|
||||
void InodeWatcher::notify_child_removed(Badge<Inode>, const String& child_name)
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
m_queue.enqueue({ Event::Type::ChildRemoved, child_name });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <AK/CircularQueue.h>
|
||||
#include <AK/WeakPtr.h>
|
||||
#include <Kernel/FileSystem/File.h>
|
||||
#include <Kernel/Lock.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
|
@ -44,9 +45,12 @@ public:
|
|||
enum class Type {
|
||||
Invalid = 0,
|
||||
Modified,
|
||||
ChildAdded,
|
||||
ChildRemoved,
|
||||
};
|
||||
|
||||
Type type { Type::Invalid };
|
||||
String string;
|
||||
};
|
||||
|
||||
virtual bool can_read(const FileDescription&, size_t) const override;
|
||||
|
@ -57,10 +61,13 @@ public:
|
|||
virtual const char* class_name() const override { return "InodeWatcher"; };
|
||||
|
||||
void notify_inode_event(Badge<Inode>, Event::Type);
|
||||
void notify_child_added(Badge<Inode>, const String& child_name);
|
||||
void notify_child_removed(Badge<Inode>, const String& child_name);
|
||||
|
||||
private:
|
||||
explicit InodeWatcher(Inode&);
|
||||
|
||||
Lock m_lock;
|
||||
WeakPtr<Inode> m_inode;
|
||||
CircularQueue<Event, 32> m_queue;
|
||||
};
|
||||
|
|
|
@ -297,7 +297,7 @@ KResult TmpFSInode::add_child(Inode& child, const StringView& name, mode_t)
|
|||
FS::DirectoryEntry entry = { owned_name.characters(), owned_name.length(), child.identifier(), 0 };
|
||||
|
||||
m_children.set(owned_name, { entry, static_cast<TmpFSInode&>(child) });
|
||||
notify_watchers();
|
||||
did_add_child(name);
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
|
@ -313,7 +313,7 @@ KResult TmpFSInode::remove_child(const StringView& name)
|
|||
if (it == m_children.end())
|
||||
return KResult(-ENOENT);
|
||||
m_children.remove(it);
|
||||
notify_watchers();
|
||||
did_remove_child(name);
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue