From 0c5895120d95bd1ab01a6e2880fb887301471322 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Thu, 26 Feb 2026 14:49:46 -0500 Subject: [PATCH] ramfs: Send separate node monitor events for each Entry of a Node. This way, the node monitor system can send events to applications with B_WATCH_ALL set on parent directories, like Tracker. Part of #19910. --- .../kernel/file_systems/ramfs/Attribute.cpp | 45 ++++++++++--------- .../kernel/file_systems/ramfs/Attribute.h | 2 + .../file_systems/ramfs/kernel_interface.cpp | 16 ++++--- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/add-ons/kernel/file_systems/ramfs/Attribute.cpp b/src/add-ons/kernel/file_systems/ramfs/Attribute.cpp index b611ab205b..6a9d80919c 100644 --- a/src/add-ons/kernel/file_systems/ramfs/Attribute.cpp +++ b/src/add-ons/kernel/file_systems/ramfs/Attribute.cpp @@ -6,6 +6,7 @@ #include "AllocationInfo.h" #include "Attribute.h" +#include "Directory.h" #include "Misc.h" #include "Node.h" #include "Volume.h" @@ -121,32 +122,20 @@ Attribute::WriteAt(off_t offset, const void *buffer, size_t size, size_t *bytesW void Attribute::_NotifyAdded() { - // notify node monitor - notify_attribute_changed(GetVolume()->GetID(), -1, fNode->GetID(), GetName(), - B_ATTR_CREATED); - - // update live queries uint8 newKey[kMaxIndexKeyLength]; size_t newLength; GetKey(newKey, &newLength); - GetVolume()->UpdateLiveQueries(NULL, fNode, GetName(), - fType, NULL, 0, newKey, newLength); + _Notify(B_ATTR_CREATED, NULL, 0, newKey, newLength); } void Attribute::_NotifyRemoved() { - // notify node monitor - notify_attribute_changed(GetVolume()->GetID(), -1, fNode->GetID(), GetName(), - B_ATTR_REMOVED); - - // update live queries uint8 oldKey[kMaxIndexKeyLength]; size_t oldLength; GetKey(oldKey, &oldLength); - GetVolume()->UpdateLiveQueries(NULL, fNode, GetName(), - fType, oldKey, oldLength, NULL, 0); + _Notify(B_ATTR_REMOVED, oldKey, oldLength, NULL, 0); } @@ -155,22 +144,36 @@ Attribute::_Changed(uint8* oldKey, size_t oldLength, off_t changeOffset, ssize_t { // If there is an index and a change has been made within the key, notify // the index. - if (fIndex != NULL && changeOffset < (off_t)kMaxIndexKeyLength && changeSize != 0) + if (fIndex != NULL && changeOffset < (off_t)kMaxIndexKeyLength) fIndex->Changed(this, oldKey, oldLength); - // notify node monitor - notify_attribute_changed(GetVolume()->GetID(), -1, fNode->GetID(), GetName(), - B_ATTR_CHANGED); - - // update live queries uint8 newKey[kMaxIndexKeyLength]; size_t newLength; GetKey(newKey, &newLength); + _Notify(B_ATTR_CHANGED, oldKey, oldLength, newKey, newLength); +} + + +void +Attribute::_Notify(int32 cause, uint8* oldKey, size_t oldLength, + uint8* newKey, size_t newLength) +{ + // notify node monitor + for (Entry* entry = fNode->GetFirstReferrer(); entry != NULL; + entry = fNode->GetNextReferrer(entry)) { + ino_t parentID = -1; + if (entry->GetParent() != NULL) + parentID = entry->GetParent()->GetID(); + notify_attribute_changed(GetVolume()->GetID(), parentID, + fNode->GetID(), GetName(), cause); + } + + // update live queries GetVolume()->UpdateLiveQueries(NULL, fNode, GetName(), fType, oldKey, oldLength, newKey, newLength); // node has been changed - if (fNode != NULL && changeSize != 0) + if (fNode != NULL) fNode->MarkModified(B_STAT_MODIFICATION_TIME); } diff --git a/src/add-ons/kernel/file_systems/ramfs/Attribute.h b/src/add-ons/kernel/file_systems/ramfs/Attribute.h index 18ef240c8d..9645c430f9 100644 --- a/src/add-ons/kernel/file_systems/ramfs/Attribute.h +++ b/src/add-ons/kernel/file_systems/ramfs/Attribute.h @@ -59,6 +59,8 @@ private: void _NotifyRemoved(); void _Changed(uint8* oldKey, size_t oldLength, off_t changeOffset, ssize_t changeSize); + void _Notify(int32 cause, uint8* oldKey, size_t oldLength, + uint8* newKey, size_t newLength); private: Node *fNode; diff --git a/src/add-ons/kernel/file_systems/ramfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/ramfs/kernel_interface.cpp index 099976c9ac..48c626b8b2 100644 --- a/src/add-ons/kernel/file_systems/ramfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/ramfs/kernel_interface.cpp @@ -68,13 +68,19 @@ static const size_t kOptimalIOSize = 65536; static const bigtime_t kNotificationInterval = 1000000LL; -// notify_if_stat_changed -void +static void notify_if_stat_changed(Volume *volume, Node *node) { - if (volume && node && node->IsModified()) { - uint32 statFields = node->MarkUnmodified(); - notify_stat_changed(volume->GetID(), -1, node->GetID(), statFields); + if (volume == NULL || node == NULL || !node->IsModified()) + return; + + uint32 statFields = node->MarkUnmodified(); + for (Entry* entry = node->GetFirstReferrer(); entry != NULL; + entry = node->GetNextReferrer(entry)) { + ino_t parentID = -1; + if (entry->GetParent() != NULL) + parentID = entry->GetParent()->GetID(); + notify_stat_changed(volume->GetID(), parentID, node->GetID(), statFields); } }