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.
This commit is contained in:
Augustin Cavalier
2026-02-26 16:11:50 -05:00
parent c271a5e7f9
commit 0c5895120d
3 changed files with 37 additions and 26 deletions
@@ -6,6 +6,7 @@
#include "AllocationInfo.h" #include "AllocationInfo.h"
#include "Attribute.h" #include "Attribute.h"
#include "Directory.h"
#include "Misc.h" #include "Misc.h"
#include "Node.h" #include "Node.h"
#include "Volume.h" #include "Volume.h"
@@ -121,32 +122,20 @@ Attribute::WriteAt(off_t offset, const void *buffer, size_t size, size_t *bytesW
void void
Attribute::_NotifyAdded() Attribute::_NotifyAdded()
{ {
// notify node monitor
notify_attribute_changed(GetVolume()->GetID(), -1, fNode->GetID(), GetName(),
B_ATTR_CREATED);
// update live queries
uint8 newKey[kMaxIndexKeyLength]; uint8 newKey[kMaxIndexKeyLength];
size_t newLength; size_t newLength;
GetKey(newKey, &newLength); GetKey(newKey, &newLength);
GetVolume()->UpdateLiveQueries(NULL, fNode, GetName(), _Notify(B_ATTR_CREATED, NULL, 0, newKey, newLength);
fType, NULL, 0, newKey, newLength);
} }
void void
Attribute::_NotifyRemoved() Attribute::_NotifyRemoved()
{ {
// notify node monitor
notify_attribute_changed(GetVolume()->GetID(), -1, fNode->GetID(), GetName(),
B_ATTR_REMOVED);
// update live queries
uint8 oldKey[kMaxIndexKeyLength]; uint8 oldKey[kMaxIndexKeyLength];
size_t oldLength; size_t oldLength;
GetKey(oldKey, &oldLength); GetKey(oldKey, &oldLength);
GetVolume()->UpdateLiveQueries(NULL, fNode, GetName(), _Notify(B_ATTR_REMOVED, oldKey, oldLength, NULL, 0);
fType, 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 // If there is an index and a change has been made within the key, notify
// the index. // the index.
if (fIndex != NULL && changeOffset < (off_t)kMaxIndexKeyLength && changeSize != 0) if (fIndex != NULL && changeOffset < (off_t)kMaxIndexKeyLength)
fIndex->Changed(this, oldKey, oldLength); 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]; uint8 newKey[kMaxIndexKeyLength];
size_t newLength; size_t newLength;
GetKey(newKey, &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, GetVolume()->UpdateLiveQueries(NULL, fNode, GetName(), fType, oldKey,
oldLength, newKey, newLength); oldLength, newKey, newLength);
// node has been changed // node has been changed
if (fNode != NULL && changeSize != 0) if (fNode != NULL)
fNode->MarkModified(B_STAT_MODIFICATION_TIME); fNode->MarkModified(B_STAT_MODIFICATION_TIME);
} }
@@ -59,6 +59,8 @@ private:
void _NotifyRemoved(); void _NotifyRemoved();
void _Changed(uint8* oldKey, size_t oldLength, void _Changed(uint8* oldKey, size_t oldLength,
off_t changeOffset, ssize_t changeSize); off_t changeOffset, ssize_t changeSize);
void _Notify(int32 cause, uint8* oldKey, size_t oldLength,
uint8* newKey, size_t newLength);
private: private:
Node *fNode; Node *fNode;
@@ -68,13 +68,19 @@ static const size_t kOptimalIOSize = 65536;
static const bigtime_t kNotificationInterval = 1000000LL; static const bigtime_t kNotificationInterval = 1000000LL;
// notify_if_stat_changed static void
void
notify_if_stat_changed(Volume *volume, Node *node) notify_if_stat_changed(Volume *volume, Node *node)
{ {
if (volume && node && node->IsModified()) { if (volume == NULL || node == NULL || !node->IsModified())
uint32 statFields = node->MarkUnmodified(); return;
notify_stat_changed(volume->GetID(), -1, node->GetID(), statFields);
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);
} }
} }