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