ramfs: Consolidate attribute notifications logic.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold, [email protected].
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
* Copyright 2026, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
#include "AllocationInfo.h"
|
||||
@@ -9,7 +10,7 @@
|
||||
#include "Node.h"
|
||||
#include "Volume.h"
|
||||
|
||||
// constructor
|
||||
|
||||
Attribute::Attribute(Volume *volume, Node *node, const char *name,
|
||||
uint32 type)
|
||||
: DataContainer(volume),
|
||||
@@ -22,35 +23,61 @@ Attribute::Attribute(Volume *volume, Node *node, const char *name,
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
|
||||
Attribute::~Attribute()
|
||||
{
|
||||
ASSERT(fIndex == NULL);
|
||||
ASSERT(fNode == NULL && fIndex == NULL);
|
||||
}
|
||||
|
||||
// InitCheck
|
||||
|
||||
status_t
|
||||
Attribute::InitCheck() const
|
||||
{
|
||||
return (fName.GetString() ? B_OK : B_NO_INIT);
|
||||
return fName.GetString() ? B_OK : B_NO_INIT;
|
||||
}
|
||||
|
||||
// SetType
|
||||
|
||||
void
|
||||
Attribute::SetType(uint32 type)
|
||||
Attribute::SetNode(Node *node)
|
||||
{
|
||||
if (type != fType) {
|
||||
if (fIndex)
|
||||
if (fNode != NULL) {
|
||||
if (fIndex != NULL)
|
||||
fIndex->Removed(this);
|
||||
fType = type;
|
||||
if (AttributeIndex *index = GetVolume()->FindAttributeIndex(GetName(),
|
||||
fType)) {
|
||||
|
||||
_NotifyRemoved();
|
||||
}
|
||||
|
||||
fNode = node;
|
||||
|
||||
if (fNode != NULL) {
|
||||
AttributeIndex* index = GetVolume()->FindAttributeIndex(GetName(), fType);
|
||||
if (index != NULL)
|
||||
index->Added(this);
|
||||
}
|
||||
|
||||
_NotifyAdded();
|
||||
}
|
||||
}
|
||||
|
||||
// SetSize
|
||||
|
||||
void
|
||||
Attribute::SetType(uint32 type)
|
||||
{
|
||||
if (type == fType)
|
||||
return;
|
||||
|
||||
if (fIndex != NULL)
|
||||
fIndex->Removed(this);
|
||||
_NotifyRemoved();
|
||||
|
||||
fType = type;
|
||||
|
||||
AttributeIndex *index = GetVolume()->FindAttributeIndex(GetName(), fType);
|
||||
if (index != NULL)
|
||||
index->Added(this);
|
||||
_NotifyAdded();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Attribute::SetSize(off_t newSize)
|
||||
{
|
||||
@@ -71,7 +98,7 @@ Attribute::SetSize(off_t newSize)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// WriteAt
|
||||
|
||||
status_t
|
||||
Attribute::WriteAt(off_t offset, const void *buffer, size_t size, size_t *bytesWritten)
|
||||
{
|
||||
@@ -85,12 +112,44 @@ Attribute::WriteAt(off_t offset, const void *buffer, size_t size, size_t *bytesW
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// update index and live queries
|
||||
// update index and send notifications
|
||||
_Changed(oldKey, oldLength, offset, size);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// _Changed
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Attribute::_Changed(uint8* oldKey, size_t oldLength, off_t changeOffset, ssize_t changeSize)
|
||||
{
|
||||
@@ -99,6 +158,10 @@ Attribute::_Changed(uint8* oldKey, size_t oldLength, off_t changeOffset, ssize_t
|
||||
if (fIndex != NULL && changeOffset < (off_t)kMaxIndexKeyLength && changeSize != 0)
|
||||
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;
|
||||
@@ -111,7 +174,7 @@ Attribute::_Changed(uint8* oldKey, size_t oldLength, off_t changeOffset, ssize_t
|
||||
fNode->MarkModified(B_STAT_MODIFICATION_TIME);
|
||||
}
|
||||
|
||||
// SetIndex
|
||||
|
||||
void
|
||||
Attribute::SetIndex(AttributeIndex *index, bool inIndex)
|
||||
{
|
||||
@@ -122,14 +185,14 @@ Attribute::SetIndex(AttributeIndex *index, bool inIndex)
|
||||
fInIndex = inIndex;
|
||||
}
|
||||
|
||||
// GetKey
|
||||
|
||||
void
|
||||
Attribute::GetKey(uint8 key[kMaxIndexKeyLength], size_t *length)
|
||||
{
|
||||
ReadAt(0, key, kMaxIndexKeyLength, length);
|
||||
}
|
||||
|
||||
// AttachAttributeIterator
|
||||
|
||||
void
|
||||
Attribute::AttachAttributeIterator(AttributeIterator *iterator)
|
||||
{
|
||||
@@ -137,7 +200,7 @@ Attribute::AttachAttributeIterator(AttributeIterator *iterator)
|
||||
fIterators.Insert(iterator);
|
||||
}
|
||||
|
||||
// DetachAttributeIterator
|
||||
|
||||
void
|
||||
Attribute::DetachAttributeIterator(AttributeIterator *iterator)
|
||||
{
|
||||
@@ -145,7 +208,7 @@ Attribute::DetachAttributeIterator(AttributeIterator *iterator)
|
||||
fIterators.Remove(iterator);
|
||||
}
|
||||
|
||||
// GetAllocationInfo
|
||||
|
||||
void
|
||||
Attribute::GetAllocationInfo(AllocationInfo &info)
|
||||
{
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
void SetNode(Node *node) { fNode = node; }
|
||||
void SetNode(Node *node);
|
||||
Node *GetNode() const { return fNode; }
|
||||
|
||||
const char *GetName() { return fName.GetString(); }
|
||||
@@ -55,6 +55,8 @@ public:
|
||||
void GetAllocationInfo(AllocationInfo &info);
|
||||
|
||||
private:
|
||||
void _NotifyAdded();
|
||||
void _NotifyRemoved();
|
||||
void _Changed(uint8* oldKey, size_t oldLength,
|
||||
off_t changeOffset, ssize_t changeSize);
|
||||
|
||||
|
||||
@@ -181,12 +181,9 @@ Node::AddAttribute(Attribute *attribute)
|
||||
{
|
||||
status_t error = (attribute && !attribute->GetNode() ? B_OK : B_BAD_VALUE);
|
||||
if (error == B_OK) {
|
||||
error = GetVolume()->NodeAttributeAdded(GetID(), attribute);
|
||||
if (error == B_OK) {
|
||||
fAttributes.Insert(attribute);
|
||||
attribute->SetNode(this);
|
||||
MarkModified(B_STAT_MODIFICATION_TIME);
|
||||
}
|
||||
fAttributes.Insert(attribute);
|
||||
attribute->SetNode(this);
|
||||
MarkModified(B_STAT_MODIFICATION_TIME);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
@@ -223,13 +220,11 @@ Node::RemoveAttribute(Attribute *attribute)
|
||||
locker.Unlock();
|
||||
|
||||
// remove the attribute
|
||||
status_t error = GetVolume()->NodeAttributeRemoved(GetID(), attribute);
|
||||
if (error == B_OK) {
|
||||
fAttributes.Remove(attribute);
|
||||
attribute->SetNode(NULL);
|
||||
MarkModified(B_STAT_MODIFICATION_TIME);
|
||||
}
|
||||
return error;
|
||||
fAttributes.Remove(attribute);
|
||||
attribute->SetNode(NULL);
|
||||
MarkModified(B_STAT_MODIFICATION_TIME);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -612,46 +612,6 @@ Volume::RemoveEntryListener(EntryListener *listener, Entry *entry)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Volume::NodeAttributeAdded(ino_t id, Attribute *attribute)
|
||||
{
|
||||
status_t error = (attribute ? B_OK : B_BAD_VALUE);
|
||||
if (error == B_OK) {
|
||||
// notify the respective attribute index
|
||||
if (error == B_OK) {
|
||||
if (AttributeIndex *index = FindAttributeIndex(
|
||||
attribute->GetName(), attribute->GetType())) {
|
||||
index->Added(attribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Volume::NodeAttributeRemoved(ino_t id, Attribute *attribute)
|
||||
{
|
||||
if (attribute == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// notify the attribute index
|
||||
if (AttributeIndex *index = attribute->GetIndex())
|
||||
index->Removed(attribute);
|
||||
|
||||
// update live queries
|
||||
if (attribute->GetNode() != NULL) {
|
||||
uint8 oldKey[kMaxIndexKeyLength];
|
||||
size_t oldLength;
|
||||
attribute->GetKey(oldKey, &oldLength);
|
||||
UpdateLiveQueries(NULL, attribute->GetNode(), attribute->GetName(),
|
||||
attribute->GetType(), oldKey, oldLength, NULL, 0);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
NameIndex *
|
||||
Volume::GetNameIndex() const
|
||||
{
|
||||
|
||||
@@ -133,10 +133,6 @@ public:
|
||||
uint32 flags);
|
||||
status_t RemoveEntryListener(EntryListener *listener, Entry *entry);
|
||||
|
||||
// node attributes
|
||||
status_t NodeAttributeAdded(ino_t id, Attribute *attribute);
|
||||
status_t NodeAttributeRemoved(ino_t id, Attribute *attribute);
|
||||
|
||||
// indices
|
||||
IndexDirectory *GetIndexDirectory() const { return fIndexDirectory; }
|
||||
NameIndex *GetNameIndex() const;
|
||||
|
||||
@@ -1626,17 +1626,11 @@ ramfs_create_attr(fs_volume* _volume, fs_vnode* _node, const char *name,
|
||||
|
||||
attribute->SetType(type);
|
||||
|
||||
notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
|
||||
B_ATTR_CREATED);
|
||||
|
||||
// else truncate if requested
|
||||
} else if (openMode & O_TRUNC) {
|
||||
error = attribute->SetSize(0);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
|
||||
B_ATTR_CHANGED);
|
||||
}
|
||||
NodeMTimeUpdater mTimeUpdater(node);
|
||||
|
||||
@@ -1687,14 +1681,8 @@ ramfs_open_attr(fs_volume* _volume, fs_vnode* _node, const char *name,
|
||||
}
|
||||
|
||||
// truncate if requested
|
||||
if (error == B_OK && (openMode & O_TRUNC)) {
|
||||
if (error == B_OK && (openMode & O_TRUNC))
|
||||
error = attribute->SetSize(0);
|
||||
|
||||
if (error == B_OK) {
|
||||
notify_attribute_changed(volume->GetID(), -1, node->GetID(),
|
||||
name, B_ATTR_CHANGED);
|
||||
}
|
||||
}
|
||||
NodeMTimeUpdater mTimeUpdater(node);
|
||||
|
||||
// set result / cleanup on failure
|
||||
@@ -1810,12 +1798,6 @@ ramfs_write_attr(fs_volume* _volume, fs_vnode* _node, void* _cookie,
|
||||
if (error == B_OK)
|
||||
error = attribute->WriteAt(pos, buffer, *bufferSize, bufferSize);
|
||||
|
||||
// notify listeners
|
||||
if (error == B_OK) {
|
||||
notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
|
||||
B_ATTR_CHANGED);
|
||||
}
|
||||
|
||||
RETURN_ERROR(error);
|
||||
}
|
||||
|
||||
@@ -1890,12 +1872,6 @@ ramfs_remove_attr(fs_volume* _volume, fs_vnode* _node, const char *name)
|
||||
if (error == B_OK)
|
||||
error = node->DeleteAttribute(attribute);
|
||||
|
||||
// notify listeners
|
||||
if (error == B_OK) {
|
||||
notify_attribute_changed(volume->GetID(), -1, node->GetID(), name,
|
||||
B_ATTR_REMOVED);
|
||||
}
|
||||
|
||||
RETURN_ERROR(error);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user