kernel & file_systems: Overhaul query attribute change notifications.
* Introduce notify_query_entry_moved to the fs_interface API. axeld added a hook to the query parser (then in BFS) in hrev34317 to directly handle moves/renames, but just sent notifications for it as B_ENTRY_REMOVED + B_ENTRY_CREATED (which is in fact the same exact thing BeOS R5 did, I tested). We need to preserve that ABI/API, unless flags that didn't exist on BeOS R5 are set. * Rework notify_query_attr_changed to notify_query_attribute_changed. This method is Haiku-specific (it was added in hrev39131), but it wasn't very useful: it only sent the name of the file, not the name of the attribute that changed. It now sends the name of the attribute along with an "int32 cause", same as notify_attribute_changed does. * Rename the private flag B_ATTR_CHANGE_NOTIFICATION to B_QUERY_WATCH_ALL. This better describes what it does (it's analogous to the B_WATCH_ALL node_monitor flag). Probably we should make it public at some point... (although probably at a lower value.) * Overhaul QueryParser notifications logic to implement WATCH_ALL properly, make use of the new and improved notification methods, and to deduplify some logic. This makes it possible to use queries with B_QUERY_WATCH_ALL in a similar fashion to watching a directory node with B_WATCH_CHILDREN, avoiding the need to watch every single node individually.
This commit is contained in:
@@ -366,12 +366,16 @@ extern status_t notify_attribute_changed(dev_t device, ino_t directory,
|
||||
extern status_t notify_query_entry_created(port_id port, int32 token,
|
||||
dev_t device, ino_t directory, const char* name,
|
||||
ino_t node);
|
||||
extern status_t notify_query_entry_moved(port_id port, int32 token,
|
||||
dev_t device, ino_t fromDirectory,
|
||||
const char* fromName, ino_t toDirectory,
|
||||
const char* toName, ino_t node);
|
||||
extern status_t notify_query_entry_removed(port_id port, int32 token,
|
||||
dev_t device, ino_t directory, const char* name,
|
||||
ino_t node);
|
||||
extern status_t notify_query_attr_changed(port_id port, int32 token,
|
||||
dev_t device, ino_t directory, const char* name,
|
||||
ino_t node);
|
||||
extern status_t notify_query_attribute_changed(port_id port, int32 token,
|
||||
dev_t device, ino_t directory, ino_t node,
|
||||
const char* attribute, int32 cause);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
# include <fs_interface.h>
|
||||
# include <fs_query.h>
|
||||
# include <NodeMonitor.h>
|
||||
# include <TypeConstants.h>
|
||||
|
||||
# include <util/SinglyLinkedList.h>
|
||||
@@ -147,9 +148,13 @@ public:
|
||||
|
||||
private:
|
||||
status_t _GetNextEntry(struct dirent* dirent, size_t size);
|
||||
void _EvaluateLiveUpdate(Entry* entry, Node* node,
|
||||
const char* attribute, int32 type,
|
||||
const uint8* oldKey, size_t oldLength,
|
||||
const uint8* newKey, size_t newLength,
|
||||
int32& opcode);
|
||||
void _SendEntryNotification(Entry* entry,
|
||||
status_t (*notify)(port_id, int32, dev_t, ino_t,
|
||||
const char*, ino_t));
|
||||
int32 opcode, const char* attribute, int32 cause);
|
||||
|
||||
private:
|
||||
Context* fContext;
|
||||
@@ -1542,14 +1547,12 @@ Query<QueryPolicy>::LiveUpdate(Entry* entry, Node* node, const char* attribute,
|
||||
if (fPort < 0 || fExpression == NULL || attribute == NULL)
|
||||
return;
|
||||
|
||||
// TODO: check if the attribute is part of the query at all...
|
||||
|
||||
// If no entry has been supplied, but the we need one for the evaluation
|
||||
// (i.e. the "name" attribute is used), we invoke ourselves for all entries
|
||||
// referring to the given node.
|
||||
if (entry == NULL && fNeedsEntry) {
|
||||
entry = QueryPolicy::NodeGetFirstReferrer(node);
|
||||
while (entry) {
|
||||
while (entry != NULL) {
|
||||
LiveUpdate(entry, node, attribute, type, oldKey, oldLength, newKey,
|
||||
newLength);
|
||||
entry = QueryPolicy::NodeGetNextReferrer(node, entry);
|
||||
@@ -1557,45 +1560,27 @@ Query<QueryPolicy>::LiveUpdate(Entry* entry, Node* node, const char* attribute,
|
||||
return;
|
||||
}
|
||||
|
||||
status_t oldStatus = fExpression->Root()->Match(entry, node, attribute,
|
||||
type, oldKey, oldLength);
|
||||
status_t newStatus = fExpression->Root()->Match(entry, node, attribute,
|
||||
type, newKey, newLength);
|
||||
int32 opcode = -1;
|
||||
_EvaluateLiveUpdate(entry, node, attribute, type, oldKey, oldLength,
|
||||
newKey, newLength, opcode);
|
||||
|
||||
bool entryCreated = false;
|
||||
bool stillInQuery = false;
|
||||
|
||||
if (oldStatus != MATCH_OK) {
|
||||
if (newStatus != MATCH_OK) {
|
||||
// nothing has changed
|
||||
return;
|
||||
}
|
||||
entryCreated = true;
|
||||
} else if (newStatus != MATCH_OK) {
|
||||
// entry got removed
|
||||
entryCreated = false;
|
||||
} else if ((fFlags & B_ATTR_CHANGE_NOTIFICATION) != 0) {
|
||||
// The entry stays in the query
|
||||
stillInQuery = true;
|
||||
} else
|
||||
if (opcode <= 0)
|
||||
return;
|
||||
|
||||
// notify query listeners
|
||||
status_t (*notify)(port_id, int32, dev_t, ino_t, const char*, ino_t);
|
||||
|
||||
if (stillInQuery)
|
||||
notify = notify_query_attr_changed;
|
||||
else if (entryCreated)
|
||||
notify = notify_query_entry_created;
|
||||
else
|
||||
notify = notify_query_entry_removed;
|
||||
int32 cause = B_ATTR_CHANGED;
|
||||
if (opcode == B_ATTR_CHANGED) {
|
||||
if (oldKey == NULL && newKey != NULL)
|
||||
cause = B_ATTR_CREATED;
|
||||
else if (oldKey != NULL && newKey == NULL)
|
||||
cause = B_ATTR_REMOVED;
|
||||
}
|
||||
|
||||
if (entry != NULL) {
|
||||
_SendEntryNotification(entry, notify);
|
||||
_SendEntryNotification(entry, opcode, attribute, cause);
|
||||
} else {
|
||||
entry = QueryPolicy::NodeGetFirstReferrer(node);
|
||||
while (entry) {
|
||||
_SendEntryNotification(entry, notify);
|
||||
while (entry != NULL) {
|
||||
_SendEntryNotification(entry, opcode, attribute, cause);
|
||||
entry = QueryPolicy::NodeGetNextReferrer(node, entry);
|
||||
}
|
||||
}
|
||||
@@ -1611,31 +1596,66 @@ Query<QueryPolicy>::LiveUpdateRenameMove(Entry* entry, Node* node,
|
||||
if (fPort < 0 || fExpression == NULL)
|
||||
return;
|
||||
|
||||
// TODO: check if the attribute is part of the query at all...
|
||||
int32 opcode = -1;
|
||||
_EvaluateLiveUpdate(entry, node, "name", B_STRING_TYPE,
|
||||
(const uint8*)oldName, oldLength, (const uint8*)newName, newLength,
|
||||
opcode);
|
||||
|
||||
status_t oldStatus = fExpression->Root()->Match(entry, node, "name",
|
||||
B_STRING_TYPE, (const uint8*)oldName, oldLength);
|
||||
status_t newStatus = fExpression->Root()->Match(entry, node, "name",
|
||||
B_STRING_TYPE, (const uint8*)newName, newLength);
|
||||
|
||||
if (oldStatus != MATCH_OK || oldStatus != newStatus)
|
||||
if (opcode < 0)
|
||||
return;
|
||||
|
||||
// The entry stays in the query, notify query listeners about the rename
|
||||
// or move
|
||||
|
||||
// We send a notification for the given entry, if any, or otherwise for
|
||||
// all entries referring to the node;
|
||||
if (entry != NULL) {
|
||||
_SendEntryNotification(entry, notify_query_entry_removed);
|
||||
_SendEntryNotification(entry, notify_query_entry_created);
|
||||
} else {
|
||||
entry = QueryPolicy::NodeGetFirstReferrer(node);
|
||||
while (entry) {
|
||||
_SendEntryNotification(entry, notify_query_entry_removed);
|
||||
_SendEntryNotification(entry, notify_query_entry_created);
|
||||
entry = QueryPolicy::NodeGetNextReferrer(node, entry);
|
||||
if (opcode == 0 || opcode == B_ATTR_CHANGED) {
|
||||
if ((fFlags & B_QUERY_WATCH_ALL) != 0) {
|
||||
// In this case, we can send B_ENTRY_MOVED.
|
||||
notify_query_entry_moved(fPort, fToken, QueryPolicy::ContextGetVolumeID(fContext),
|
||||
oldDirectoryID, oldName, newDirectoryID, newName,
|
||||
QueryPolicy::EntryGetNodeID(entry));
|
||||
} else {
|
||||
// Just like BeOS, send B_ENTRY_REMOVED and then B_ENTRY_CREATED.
|
||||
notify_query_entry_removed(fPort, fToken, QueryPolicy::ContextGetVolumeID(fContext),
|
||||
oldDirectoryID, oldName, QueryPolicy::EntryGetNodeID(entry));
|
||||
notify_query_entry_created(fPort, fToken, QueryPolicy::ContextGetVolumeID(fContext),
|
||||
newDirectoryID, newName, QueryPolicy::EntryGetNodeID(entry));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
_SendEntryNotification(entry, opcode, NULL, B_ATTR_CHANGED);
|
||||
}
|
||||
|
||||
|
||||
template<typename QueryPolicy>
|
||||
void
|
||||
Query<QueryPolicy>::_EvaluateLiveUpdate(Entry* entry, Node* node, const char* attribute,
|
||||
int32 type, const uint8* oldKey, size_t oldLength, const uint8* newKey,
|
||||
size_t newLength, int32& opcode)
|
||||
{
|
||||
if (fPort < 0 || fExpression == NULL)
|
||||
return;
|
||||
|
||||
// TODO: check if the attribute is part of the query at all...
|
||||
|
||||
status_t oldStatus = fExpression->Root()->Match(entry, node, attribute,
|
||||
type, oldKey, oldLength);
|
||||
status_t newStatus = fExpression->Root()->Match(entry, node, attribute,
|
||||
type, newKey, newLength);
|
||||
|
||||
if (oldStatus != MATCH_OK) {
|
||||
if (newStatus != MATCH_OK) {
|
||||
// wasn't in query, and still isn't
|
||||
return;
|
||||
}
|
||||
// entry was added
|
||||
opcode = B_ENTRY_CREATED;
|
||||
} else if (newStatus != MATCH_OK) {
|
||||
// entry was removed
|
||||
opcode = B_ENTRY_REMOVED;
|
||||
} else if ((fFlags & B_QUERY_WATCH_ALL) != 0) {
|
||||
// still in query, all attribute changes watched
|
||||
opcode = B_ATTR_CHANGED;
|
||||
} else {
|
||||
// still in query, no change to notify
|
||||
opcode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1681,15 +1701,30 @@ Query<QueryPolicy>::_GetNextEntry(struct dirent* dirent, size_t size)
|
||||
|
||||
template<typename QueryPolicy>
|
||||
void
|
||||
Query<QueryPolicy>::_SendEntryNotification(Entry* entry,
|
||||
status_t (*notify)(port_id, int32, dev_t, ino_t, const char*, ino_t))
|
||||
Query<QueryPolicy>::_SendEntryNotification(Entry* entry, int32 opcode,
|
||||
const char* attribute, int32 cause)
|
||||
{
|
||||
NodeHolder nodeHolder;
|
||||
const char* name = QueryPolicy::EntryGetNameNoCopy(nodeHolder, entry);
|
||||
if (name != NULL) {
|
||||
notify(fPort, fToken, QueryPolicy::ContextGetVolumeID(fContext),
|
||||
QueryPolicy::EntryGetParentID(entry), name,
|
||||
QueryPolicy::EntryGetNodeID(entry));
|
||||
switch (opcode) {
|
||||
case B_ENTRY_CREATED:
|
||||
case B_ENTRY_REMOVED:
|
||||
{
|
||||
NodeHolder nodeHolder;
|
||||
const char* name = QueryPolicy::EntryGetNameNoCopy(nodeHolder, entry);
|
||||
if (name != NULL) {
|
||||
((opcode == B_ENTRY_CREATED) ?
|
||||
notify_query_entry_created : notify_query_entry_removed)
|
||||
(fPort, fToken, QueryPolicy::ContextGetVolumeID(fContext),
|
||||
QueryPolicy::EntryGetParentID(entry), name,
|
||||
QueryPolicy::EntryGetNodeID(entry));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case B_ATTR_CHANGED:
|
||||
notify_query_attribute_changed(fPort, fToken, QueryPolicy::ContextGetVolumeID(fContext),
|
||||
QueryPolicy::EntryGetParentID(entry), QueryPolicy::EntryGetNodeID(entry),
|
||||
attribute, cause);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -964,8 +964,9 @@
|
||||
#define notify_attribute_changed fssh_notify_attribute_changed
|
||||
|
||||
#define notify_query_entry_created fssh_notify_query_entry_created
|
||||
#define notify_query_entry_moved fssh_notify_query_entry_moved
|
||||
#define notify_query_entry_removed fssh_notify_query_entry_removed
|
||||
#define notify_query_attr_changed fssh_notify_query_attr_changed
|
||||
#define notify_query_attribute_changed fssh_notify_query_attribute_changed
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -404,14 +404,18 @@ extern fssh_status_t fssh_notify_query_entry_created(fssh_port_id port,
|
||||
int32_t token, fssh_mount_id device,
|
||||
fssh_vnode_id directory, const char *name,
|
||||
fssh_vnode_id node);
|
||||
extern fssh_status_t fssh_notify_query_entry_moved(fssh_port_id port, int32_t token,
|
||||
fssh_mount_id device, fssh_vnode_id fromDirectory,
|
||||
const char* fromName, fssh_vnode_id toDirectory,
|
||||
const char* toName, fssh_vnode_id node);
|
||||
extern fssh_status_t fssh_notify_query_entry_removed(fssh_port_id port,
|
||||
int32_t token, fssh_mount_id device,
|
||||
fssh_vnode_id directory, const char *name,
|
||||
fssh_vnode_id node);
|
||||
extern fssh_status_t fssh_notify_query_attr_changed(fssh_port_id port,
|
||||
extern fssh_status_t fssh_notify_query_attribute_changed(fssh_port_id port,
|
||||
int32_t token, fssh_mount_id device,
|
||||
fssh_vnode_id directory, const char *name,
|
||||
fssh_vnode_id node);
|
||||
fssh_vnode_id directory, fssh_vnode_id node,
|
||||
const char *attribute, int32_t cause);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
#define QUERY_PRIVATE_H
|
||||
|
||||
|
||||
// If an entry is already in a query and a attribute changed
|
||||
// B_ATTR_CHANGE_NOTIFICATION tells the query to send B_ATTR_CHANGED
|
||||
// notifications if the entry stays in the query.
|
||||
#define B_ATTR_CHANGE_NOTIFICATION 0x0000F000
|
||||
// Send node monitor (B_ATTR_CHANGED, etc.) events for all
|
||||
// attributes on all entries in the query.
|
||||
#define B_QUERY_WATCH_ALL 0x0000F000
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -221,46 +221,6 @@ class NodeMonitorService : public NotificationService {
|
||||
static NodeMonitorService sNodeMonitorService;
|
||||
|
||||
|
||||
/*! \brief Notifies the listener of a live query that an entry has been added
|
||||
to or removed from or updated and still in the query (for whatever
|
||||
reason).
|
||||
\param opcode \c B_ENTRY_CREATED or \c B_ENTRY_REMOVED or \c B_ATTR_CHANGED.
|
||||
\param port The target port of the listener.
|
||||
\param token The BHandler token of the listener.
|
||||
\param device The ID of the mounted FS, the entry lives in.
|
||||
\param directory The entry's parent directory ID.
|
||||
\param name The entry's name.
|
||||
\param node The ID of the node the entry refers to.
|
||||
\return
|
||||
- \c B_OK, if everything went fine,
|
||||
- another error code otherwise.
|
||||
*/
|
||||
static status_t
|
||||
notify_query_entry_event(int32 opcode, port_id port, int32 token,
|
||||
dev_t device, ino_t directory, const char *name, ino_t node)
|
||||
{
|
||||
if (!name)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// construct the message
|
||||
char messageBuffer[1024];
|
||||
KMessage message;
|
||||
message.SetTo(messageBuffer, sizeof(messageBuffer), B_QUERY_UPDATE);
|
||||
message.AddInt32("opcode", opcode);
|
||||
message.AddInt32("device", device);
|
||||
message.AddInt64("directory", directory);
|
||||
message.AddInt64("node", node);
|
||||
message.AddString("name", name);
|
||||
|
||||
// send the message
|
||||
messaging_target target;
|
||||
target.port = port;
|
||||
target.token = token;
|
||||
|
||||
return send_message(&message, &target, 1);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - NodeMonitorService
|
||||
|
||||
|
||||
@@ -1083,6 +1043,88 @@ NodeMonitorService::UpdateUserListener(io_context *context, dev_t device,
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
notify_query_entry_created_or_removed(int32 opcode, port_id port, int32 token,
|
||||
dev_t device, ino_t directory, const char *name, ino_t node)
|
||||
{
|
||||
if (!name)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// construct the message
|
||||
char messageBuffer[1024];
|
||||
KMessage message;
|
||||
message.SetTo(messageBuffer, sizeof(messageBuffer), B_QUERY_UPDATE);
|
||||
message.AddInt32("opcode", opcode);
|
||||
message.AddInt32("device", device);
|
||||
message.AddInt64("directory", directory);
|
||||
message.AddInt64("node", node);
|
||||
message.AddString("name", name);
|
||||
|
||||
// send the message
|
||||
messaging_target target;
|
||||
target.port = port;
|
||||
target.token = token;
|
||||
|
||||
return send_message(&message, &target, 1);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
notify_query_attr_changed(port_id port, int32 token,
|
||||
dev_t device, ino_t directory, ino_t node, const char *attr, int32 cause)
|
||||
{
|
||||
if (!attr)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// construct the message
|
||||
char messageBuffer[1024];
|
||||
KMessage message;
|
||||
message.SetTo(messageBuffer, sizeof(messageBuffer), B_QUERY_UPDATE);
|
||||
message.AddInt32("opcode", B_ATTR_CHANGED);
|
||||
message.AddInt32("device", device);
|
||||
message.AddInt64("directory", directory);
|
||||
message.AddInt64("node", node);
|
||||
message.AddString("attr", attr);
|
||||
message.AddInt32("cause", cause);
|
||||
|
||||
// send the message
|
||||
messaging_target target;
|
||||
target.port = port;
|
||||
target.token = token;
|
||||
|
||||
return send_message(&message, &target, 1);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
notify_query_entry_moved(int32 opcode, port_id port, int32 token,
|
||||
dev_t device, ino_t fromDirectory, const char *fromName,
|
||||
ino_t toDirectory, const char* toName, ino_t node)
|
||||
{
|
||||
if (!fromName || !toName)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// construct the message
|
||||
char messageBuffer[1024];
|
||||
KMessage message;
|
||||
message.SetTo(messageBuffer, sizeof(messageBuffer), B_QUERY_UPDATE);
|
||||
message.AddInt32("opcode", opcode);
|
||||
message.AddInt32("device", device);
|
||||
message.AddInt64("from directory", fromDirectory);
|
||||
message.AddInt64("to directory", toDirectory);
|
||||
message.AddInt64("node", node);
|
||||
message.AddString("from name", fromName); // Haiku only
|
||||
message.AddString("name", toName);
|
||||
|
||||
// send the message
|
||||
messaging_target target;
|
||||
target.port = port;
|
||||
target.token = token;
|
||||
|
||||
return send_message(&message, &target, 1);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - private kernel API
|
||||
|
||||
|
||||
@@ -1253,7 +1295,7 @@ status_t
|
||||
notify_query_entry_created(port_id port, int32 token, dev_t device,
|
||||
ino_t directory, const char *name, ino_t node)
|
||||
{
|
||||
return notify_query_entry_event(B_ENTRY_CREATED, port, token,
|
||||
return notify_query_entry_created_or_removed(B_ENTRY_CREATED, port, token,
|
||||
device, directory, name, node);
|
||||
}
|
||||
|
||||
@@ -1274,29 +1316,52 @@ status_t
|
||||
notify_query_entry_removed(port_id port, int32 token, dev_t device,
|
||||
ino_t directory, const char *name, ino_t node)
|
||||
{
|
||||
return notify_query_entry_event(B_ENTRY_REMOVED, port, token,
|
||||
return notify_query_entry_created_or_removed(B_ENTRY_REMOVED, port, token,
|
||||
device, directory, name, node);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Notifies the listener of a live query that an entry has been changed
|
||||
and is still in the query (for whatever reason).
|
||||
/*! \brief Notifies the listener of a live query that an entry has been moved.
|
||||
\param port The target port of the listener.
|
||||
\param token The BHandler token of the listener.
|
||||
\param device The ID of the mounted FS, the entry lives in.
|
||||
\param directory The entry's parent directory ID.
|
||||
\param name The entry's name.
|
||||
\param fromDirectory The old parent directory ID.
|
||||
\param toDirectory The new parent directory ID.
|
||||
\param fromName The entry's old name.
|
||||
\param toName The entry's new name.
|
||||
\param node The ID of the node the entry refers to.
|
||||
\return
|
||||
- \c B_OK, if everything went fine,
|
||||
- another error code otherwise.
|
||||
*/
|
||||
status_t
|
||||
notify_query_attr_changed(port_id port, int32 token, dev_t device,
|
||||
ino_t directory, const char* name, ino_t node)
|
||||
notify_query_entry_moved(port_id port, int32 token, dev_t device, ino_t fromDirectory,
|
||||
const char *fromName, ino_t toDirectory, const char *toName,
|
||||
ino_t node)
|
||||
{
|
||||
return notify_query_entry_event(B_ATTR_CHANGED, port, token,
|
||||
device, directory, name, node);
|
||||
return notify_query_entry_moved(B_ENTRY_MOVED, port, token,
|
||||
device, fromDirectory, fromName, toDirectory, toName, node);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Notifies the listener of a live query that an entry has been changed
|
||||
and is still in the query (for whatever reason).
|
||||
\param port The target port of the listener.
|
||||
\param token The BHandler token of the listener.
|
||||
\param device The ID of the mounted FS, the entry lives in.
|
||||
\param directory The entry's parent directory ID.
|
||||
\param name The entry's name.
|
||||
\param node The ID of the node the entry refers to.
|
||||
\return
|
||||
- \c B_OK, if everything went fine,
|
||||
- another error code otherwise.
|
||||
*/
|
||||
status_t
|
||||
notify_query_attribute_changed(port_id port, int32 token, dev_t device,
|
||||
ino_t directory, ino_t node, const char* attribute, int32 cause)
|
||||
{
|
||||
return notify_query_attr_changed(port, token,
|
||||
device, directory, node, attribute, cause);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -67,9 +67,18 @@ fssh_notify_query_entry_removed(fssh_port_id port, int32_t token,
|
||||
|
||||
|
||||
fssh_status_t
|
||||
fssh_notify_query_attr_changed(fssh_port_id port, int32_t token,
|
||||
fssh_mount_id device, fssh_vnode_id directory, const char *name,
|
||||
fssh_vnode_id node)
|
||||
fssh_notify_query_entry_moved(fssh_port_id port, int32_t token, fssh_mount_id device,
|
||||
fssh_vnode_id fromDirectory, const char* fromName, fssh_vnode_id toDirectory,
|
||||
const char* toName, fssh_vnode_id node)
|
||||
{
|
||||
return FSSH_B_OK;
|
||||
}
|
||||
|
||||
|
||||
fssh_status_t
|
||||
fssh_notify_query_attribute_changed(fssh_port_id port, int32_t token,
|
||||
fssh_mount_id device, fssh_vnode_id directory, fssh_vnode_id node,
|
||||
const char *attribute, int32_t cause)
|
||||
{
|
||||
return FSSH_B_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user