From 4a5a077ff79e1b1ffb2571fdfc5ea8218a64196c Mon Sep 17 00:00:00 2001 From: Clemens Zeidler Date: Sun, 24 Oct 2010 20:47:46 +0000 Subject: [PATCH] Add a private B_ATTR_CHANGE_NOTIFICATION flag to the open query syscall to tell the query to send notifications when an entry attribute changed and the entry stays in the query. Previously you only get created and removed messages, now you can also get updated messages. Only implement it for bfs. Fix copy right. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39131 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/drivers/fs_interface.h | 3 ++ headers/private/fs_shell/fssh_api_wrapper.h | 1 + headers/private/fs_shell/fssh_fs_interface.h | 4 +++ headers/private/storage/query_private.h | 10 ++++++ src/add-ons/kernel/file_systems/bfs/Query.cpp | 24 +++++++++----- src/kits/storage/NodeMonitor.cpp | 3 +- src/kits/storage/Query.cpp | 2 ++ src/system/kernel/fs/node_monitor.cpp | 32 ++++++++++++++++--- src/tools/bfs_shell/Jamfile | 2 ++ src/tools/fs_shell/node_monitor.cpp | 9 ++++++ 10 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 headers/private/storage/query_private.h 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