diff --git a/headers/os/drivers/fs_interface.h b/headers/os/drivers/fs_interface.h index 86ad096eb8..fa5893cd23 100644 --- a/headers/os/drivers/fs_interface.h +++ b/headers/os/drivers/fs_interface.h @@ -356,6 +356,9 @@ extern status_t notify_query_entry_created(port_id port, int32 token, 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); #ifdef __cplusplus } diff --git a/headers/private/fs_shell/fssh_api_wrapper.h b/headers/private/fs_shell/fssh_api_wrapper.h index a7994eb36c..fabc9ea33c 100644 --- a/headers/private/fs_shell/fssh_api_wrapper.h +++ b/headers/private/fs_shell/fssh_api_wrapper.h @@ -945,6 +945,7 @@ #define notify_query_entry_created fssh_notify_query_entry_created #define notify_query_entry_removed fssh_notify_query_entry_removed +#define notify_query_attr_changed fssh_notify_query_attr_changed //////////////////////////////////////////////////////////////////////////////// diff --git a/headers/private/fs_shell/fssh_fs_interface.h b/headers/private/fs_shell/fssh_fs_interface.h index 5f23b1d366..b7c04d84b7 100644 --- a/headers/private/fs_shell/fssh_fs_interface.h +++ b/headers/private/fs_shell/fssh_fs_interface.h @@ -402,6 +402,10 @@ 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, + int32_t token, fssh_mount_id device, + fssh_vnode_id directory, const char *name, + fssh_vnode_id node); #ifdef __cplusplus } diff --git a/headers/private/storage/query_private.h b/headers/private/storage/query_private.h new file mode 100644 index 0000000000..d75fc08eb3 --- /dev/null +++ b/headers/private/storage/query_private.h @@ -0,0 +1,10 @@ +#ifndef QUERY_PRIVATE_H +#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 + +#endif diff --git a/src/add-ons/kernel/file_systems/bfs/Query.cpp b/src/add-ons/kernel/file_systems/bfs/Query.cpp index 2d3bab70e3..354c457edc 100644 --- a/src/add-ons/kernel/file_systems/bfs/Query.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Query.cpp @@ -1,5 +1,6 @@ /* * Copyright 2001-2009, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2010, Clemens Zeidler * This file may be used under the terms of the MIT License. */ @@ -11,13 +12,15 @@ */ #include "Query.h" + +#include + +#include "BPlusTree.h" #include "bfs.h" #include "Debug.h" -#include "Volume.h" -#include "Inode.h" -#include "BPlusTree.h" #include "Index.h" - +#include "Inode.h" +#include "Volume.h" // The parser has a very static design, but it will do what is required. // @@ -1620,7 +1623,8 @@ Query::LiveUpdate(Inode* inode, const char* attribute, int32 type, status_t newStatus = fExpression->Root()->Match(inode, attribute, type, newKey, newLength); - bool entryCreated; + bool entryCreated = false; + bool stillInQuery = false; if (oldStatus != MATCH_OK) { if (newStatus != MATCH_OK) { @@ -1631,10 +1635,11 @@ Query::LiveUpdate(Inode* inode, const char* attribute, int32 type, } else if (newStatus != MATCH_OK) { // entry got removed entryCreated = false; - } else { + } else if ((fFlags & B_ATTR_CHANGE_NOTIFICATION) != 0) { // The entry stays in the query + stillInQuery = true; + } else return; - } // we may need to get the name of the inode @@ -1652,7 +1657,10 @@ Query::LiveUpdate(Inode* inode, const char* attribute, int32 type, // notify query listeners - if (entryCreated) { + if (stillInQuery) + notify_query_attr_changed(fPort, fToken, fVolume->ID(), + fVolume->ToVnode(inode->Parent()), name, inode->ID()); + else if (entryCreated) { notify_query_entry_created(fPort, fToken, fVolume->ID(), fVolume->ToVnode(inode->Parent()), name, inode->ID()); } else { diff --git a/src/kits/storage/NodeMonitor.cpp b/src/kits/storage/NodeMonitor.cpp index b2eaa3805b..7870580ce5 100644 --- a/src/kits/storage/NodeMonitor.cpp +++ b/src/kits/storage/NodeMonitor.cpp @@ -1,10 +1,11 @@ /* - * Copyright 2001-2005, Haiku. + * Copyright 2001-2010, Haiku. * Distributed under the terms of the MIT License. * * Authors: * Ingo Weinhold, bonefish@@users.sf.net * Axel Dörfler, axeld@pinc-software.de + * Clemens Zeidler */ diff --git a/src/kits/storage/Query.cpp b/src/kits/storage/Query.cpp index ea65e5fe67..990331cea2 100644 --- a/src/kits/storage/Query.cpp +++ b/src/kits/storage/Query.cpp @@ -22,10 +22,12 @@ #include #include +#include #include "QueryPredicate.h" #include "storage_support.h" + using namespace std; using namespace BPrivate::Storage; diff --git a/src/system/kernel/fs/node_monitor.cpp b/src/system/kernel/fs/node_monitor.cpp index 9b6e056164..02b0715ab2 100644 --- a/src/system/kernel/fs/node_monitor.cpp +++ b/src/system/kernel/fs/node_monitor.cpp @@ -219,8 +219,9 @@ static NodeMonitorService sNodeMonitorService; /*! \brief Notifies the listener of a live query that an entry has been added - to or removed from the query (for whatever reason). - \param opcode \c B_ENTRY_CREATED or \c B_ENTRY_REMOVED. + 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. @@ -232,7 +233,7 @@ static NodeMonitorService sNodeMonitorService; - another error code otherwise. */ static status_t -notify_query_entry_created_or_removed(int32 opcode, port_id port, int32 token, +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) @@ -1195,7 +1196,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_created_or_removed(B_ENTRY_CREATED, port, token, + return notify_query_entry_event(B_ENTRY_CREATED, port, token, device, directory, name, node); } @@ -1216,7 +1217,28 @@ 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_created_or_removed(B_ENTRY_REMOVED, port, token, + return notify_query_entry_event(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). + \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_attr_changed(port_id port, int32 token, dev_t device, + ino_t directory, const char* name, ino_t node) +{ + return notify_query_entry_event(B_ATTR_CHANGED, port, token, device, directory, name, node); } diff --git a/src/tools/bfs_shell/Jamfile b/src/tools/bfs_shell/Jamfile index 069b776e40..ccde44d9c3 100644 --- a/src/tools/bfs_shell/Jamfile +++ b/src/tools/bfs_shell/Jamfile @@ -33,6 +33,8 @@ if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) { fsShellCommandLibs = $(HOST_NETWORK_LIBS) ; } +UsePrivateHeaders storage ; + UsePrivateHeaders fs_shell ; local bfsSource = diff --git a/src/tools/fs_shell/node_monitor.cpp b/src/tools/fs_shell/node_monitor.cpp index 40a103b306..cd36536eea 100644 --- a/src/tools/fs_shell/node_monitor.cpp +++ b/src/tools/fs_shell/node_monitor.cpp @@ -64,3 +64,12 @@ fssh_notify_query_entry_removed(fssh_port_id port, int32_t token, { return FSSH_B_OK; } + + +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) +{ + return FSSH_B_OK; +} \ No newline at end of file