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:
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user