* Finally implemented B_WATCH_MOUNT, ie. Tracker now shows newly mounted volumes
(mounting still only works from the Terminal). * Shuffled functions in node_monitor.cpp around to clearly differentiate between private, private kernel, and public kernel functions. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16575 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
f1fb383d6f
commit
bb674499f8
@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_NODE_MONITOR_H
|
||||
#define _KERNEL_NODE_MONITOR_H
|
||||
/*
|
||||
** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
#include <fs_interface.h>
|
||||
|
||||
|
||||
struct io_context;
|
||||
@ -18,6 +18,9 @@ extern "C" {
|
||||
// private kernel API
|
||||
extern status_t remove_node_monitors(struct io_context *context);
|
||||
extern status_t node_monitor_init(void);
|
||||
extern status_t notify_unmount(mount_id device);
|
||||
extern status_t notify_mount(mount_id device, mount_id parentDevice,
|
||||
vnode_id parentDirectory);
|
||||
|
||||
// user-space exported calls
|
||||
extern status_t _user_stop_notifying(port_id port, uint32 token);
|
||||
|
@ -62,8 +62,8 @@ watch_node(const node_ref *node, uint32 flags, BMessenger target)
|
||||
// subscribe to...
|
||||
// mount watching
|
||||
if (flags & B_WATCH_MOUNT) {
|
||||
status_t status = _kern_start_watching((dev_t)-1, (ino_t)-1, 0, port,
|
||||
token);
|
||||
status_t status = _kern_start_watching((dev_t)-1, (ino_t)-1,
|
||||
B_WATCH_MOUNT, port, token);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <drivers/node_monitor.h>
|
||||
@ -21,8 +21,8 @@
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
#define TRACE_MONITOR 0
|
||||
#if TRACE_MONITOR
|
||||
//#define TRACE_MONITOR
|
||||
#ifdef TRACE_MONITOR
|
||||
# define TRACE(x) dprintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
@ -325,8 +325,203 @@ remove_node_monitors_by_target(struct io_context *context, port_id port, uint32
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// Exported private kernel API
|
||||
/** \brief Given device and node ID and a node monitoring event mask, the
|
||||
* function checks whether there are listeners interested in any of
|
||||
* the events for that node and, if so, adds the respective listener
|
||||
* list to a supplied array of listener lists.
|
||||
*
|
||||
* Note, that in general not all of the listeners in an appended list will be
|
||||
* interested in the events, but it is guaranteed that
|
||||
* interested_monitor_listener_list::first_listener is indeed
|
||||
* the first listener in the list, that is interested.
|
||||
*
|
||||
* \param device The ID of the mounted FS, the node lives in.
|
||||
* \param node The ID of the node.
|
||||
* \param flags The mask specifying the events occurred for the given node
|
||||
* (a combination of \c B_WATCH_* constants).
|
||||
* \param interestedListeners An array of listener lists. If there are
|
||||
* interested listeners for the node, the list will be appended to
|
||||
* this array.
|
||||
* \param interestedListenerCount The number of elements in the
|
||||
* \a interestedListeners array. Will be incremented, if a list is
|
||||
* appended.
|
||||
*/
|
||||
|
||||
static void
|
||||
get_interested_monitor_listeners(mount_id device, vnode_id node,
|
||||
uint32 flags, interested_monitor_listener_list *interestedListeners,
|
||||
int32 &interestedListenerCount)
|
||||
{
|
||||
// get the monitor for the node
|
||||
node_monitor *monitor = get_monitor_for(device, node);
|
||||
if (!monitor)
|
||||
return;
|
||||
|
||||
// iterate through the listeners until we find one with matching flags
|
||||
monitor_listener *listener = NULL;
|
||||
while ((listener = (monitor_listener*)list_get_next_item(
|
||||
&monitor->listeners, listener)) != NULL) {
|
||||
if (listener->flags & flags) {
|
||||
interested_monitor_listener_list &list
|
||||
= interestedListeners[interestedListenerCount++];
|
||||
list.listeners = &monitor->listeners;
|
||||
list.first_listener = listener;
|
||||
list.flags = flags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** \brief Sends a notifcation message to the given listeners.
|
||||
* \param message The message to be sent.
|
||||
* \param interestedListeners An array of listener lists.
|
||||
* \param interestedListenerCount The number of elements in the
|
||||
* \a interestedListeners array.
|
||||
* \return
|
||||
* - \c B_OK, if everything went fine,
|
||||
* - another error code otherwise.
|
||||
*/
|
||||
|
||||
static status_t
|
||||
send_notification_message(KMessage &message,
|
||||
interested_monitor_listener_list *interestedListeners,
|
||||
int32 interestedListenerCount)
|
||||
{
|
||||
// Since the messaging service supports broadcasting and that is more
|
||||
// efficient than sending the messages individually, we collect the
|
||||
// listener targets in an array and send the message to them at once.
|
||||
const int32 maxTargetCount = 16;
|
||||
messaging_target targets[maxTargetCount];
|
||||
int32 targetCount = 0;
|
||||
|
||||
// iterate through the lists
|
||||
interested_monitor_listener_list *list = interestedListeners;
|
||||
for (int32 i = 0; i < interestedListenerCount; i++, list++) {
|
||||
// iterate through the listeners
|
||||
monitor_listener *listener = list->first_listener;
|
||||
do {
|
||||
if (listener->flags & list->flags) {
|
||||
// the listener's flags match: add it to the targets
|
||||
messaging_target &target = targets[targetCount++];
|
||||
target.port = listener->port;
|
||||
target.token = listener->token;
|
||||
|
||||
// if the target array is full, send the message
|
||||
if (targetCount == maxTargetCount) {
|
||||
status_t error = send_message(&message, targets,
|
||||
targetCount);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
targetCount = 0;
|
||||
}
|
||||
}
|
||||
} while ((listener = (monitor_listener*)list_get_next_item(
|
||||
list->listeners, listener)) != NULL);
|
||||
}
|
||||
|
||||
// if any targets are left (the usual case, unless the target array got
|
||||
// full early), send the message
|
||||
if (targetCount > 0)
|
||||
return send_message(&message, targets, targetCount);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Notifies all interested listeners that an entry has been created
|
||||
* or removed.
|
||||
* \param opcode \c B_ENTRY_CREATED or \c B_ENTRY_REMOVED.
|
||||
* \param device The ID of the mounted FS, the entry lives/lived 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/referred to.
|
||||
* \return
|
||||
* - \c B_OK, if everything went fine,
|
||||
* - another error code otherwise.
|
||||
*/
|
||||
|
||||
static status_t
|
||||
notify_entry_created_or_removed(int32 opcode, mount_id device,
|
||||
vnode_id directory, const char *name, vnode_id node)
|
||||
{
|
||||
if (!name)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
MutexLocker locker(gMonitorMutex);
|
||||
|
||||
// get the lists of all interested listeners
|
||||
interested_monitor_listener_list interestedListeners[3];
|
||||
int32 interestedListenerCount = 0;
|
||||
// ... for the node
|
||||
if (opcode != B_ENTRY_CREATED) {
|
||||
get_interested_monitor_listeners(device, node, B_WATCH_NAME,
|
||||
interestedListeners, interestedListenerCount);
|
||||
}
|
||||
// ... for the directory
|
||||
get_interested_monitor_listeners(device, directory, B_WATCH_DIRECTORY,
|
||||
interestedListeners, interestedListenerCount);
|
||||
|
||||
if (interestedListenerCount == 0)
|
||||
return B_OK;
|
||||
|
||||
// there are interested listeners: construct the message and send it
|
||||
char messageBuffer[1024];
|
||||
KMessage message;
|
||||
message.SetTo(messageBuffer, sizeof(messageBuffer), B_NODE_MONITOR);
|
||||
message.AddInt32("opcode", opcode);
|
||||
message.AddInt32("device", device);
|
||||
message.AddInt64("directory", directory);
|
||||
message.AddInt64("node", node);
|
||||
message.AddString("name", name); // for "removed" Haiku only
|
||||
|
||||
return send_notification_message(message, interestedListeners,
|
||||
interestedListenerCount);
|
||||
}
|
||||
|
||||
|
||||
/** \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.
|
||||
* \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_created_or_removed(int32 opcode, port_id port, int32 token,
|
||||
mount_id device, vnode_id directory, const char *name, vnode_id 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 - private kernel API
|
||||
|
||||
|
||||
status_t
|
||||
@ -358,8 +553,70 @@ node_monitor_init(void)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// Exported public kernel API
|
||||
status_t
|
||||
notify_unmount(mount_id device)
|
||||
{
|
||||
TRACE(("unmounted device: %ld\n", device));
|
||||
|
||||
MutexLocker locker(gMonitorMutex);
|
||||
|
||||
// get the lists of all interested listeners
|
||||
interested_monitor_listener_list interestedListeners[3];
|
||||
int32 interestedListenerCount = 0;
|
||||
get_interested_monitor_listeners(-1, -1, B_WATCH_MOUNT,
|
||||
interestedListeners, interestedListenerCount);
|
||||
|
||||
if (interestedListenerCount == 0)
|
||||
return B_OK;
|
||||
|
||||
// there are interested listeners: construct the message and send it
|
||||
char messageBuffer[96];
|
||||
KMessage message;
|
||||
message.SetTo(messageBuffer, sizeof(messageBuffer), B_NODE_MONITOR);
|
||||
message.AddInt32("opcode", B_DEVICE_UNMOUNTED);
|
||||
message.AddInt32("device", device);
|
||||
|
||||
return send_notification_message(message, interestedListeners,
|
||||
interestedListenerCount);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
notify_mount(mount_id device, mount_id parentDevice, vnode_id parentDirectory)
|
||||
{
|
||||
TRACE(("mounted device: %ld, parent %ld:%Ld\n", device, parentDevice,
|
||||
parentDirectory));
|
||||
|
||||
MutexLocker locker(gMonitorMutex);
|
||||
|
||||
// get the lists of all interested listeners
|
||||
interested_monitor_listener_list interestedListeners[3];
|
||||
int32 interestedListenerCount = 0;
|
||||
get_interested_monitor_listeners(-1, -1, B_WATCH_MOUNT,
|
||||
interestedListeners, interestedListenerCount);
|
||||
|
||||
if (interestedListenerCount == 0)
|
||||
return B_OK;
|
||||
|
||||
// there are interested listeners: construct the message and send it
|
||||
char messageBuffer[128];
|
||||
KMessage message;
|
||||
message.SetTo(messageBuffer, sizeof(messageBuffer), B_NODE_MONITOR);
|
||||
message.AddInt32("opcode", B_DEVICE_MOUNTED);
|
||||
message.AddInt32("new device", device);
|
||||
message.AddInt32("device", parentDevice);
|
||||
message.AddInt64("directory", parentDirectory);
|
||||
|
||||
return send_notification_message(message, interestedListeners,
|
||||
interestedListenerCount);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - public kernel API
|
||||
|
||||
|
||||
/** \brief Subscribes a target to node and/or mount watching.
|
||||
@ -505,170 +762,16 @@ notify_listener(int op, mount_id device, vnode_id parentNode, vnode_id toParentN
|
||||
}
|
||||
|
||||
|
||||
/** \brief Given device and node ID and a node monitoring event mask, the
|
||||
function checks whether there are listeners interested in any of
|
||||
the events for that node and, if so, adds the respective listener
|
||||
list to a supplied array of listener lists.
|
||||
|
||||
Note, that in general not all of the listeners in an appended list will be
|
||||
interested in the events, but it is guaranteed that
|
||||
interested_monitor_listener_list::first_listener is indeed
|
||||
the first listener in the list, that is interested.
|
||||
|
||||
\param device The ID of the mounted FS, the node lives in.
|
||||
\param node The ID of the node.
|
||||
\param flags The mask specifying the events occurred for the given node
|
||||
(a combination of \c B_WATCH_* constants).
|
||||
\param interestedListeners An array of listener lists. If there are
|
||||
interested listeners for the node, the list will be appended to
|
||||
this array.
|
||||
\param interestedListenerCount The number of elements in the
|
||||
\a interestedListeners array. Will be incremented, if a list is
|
||||
appended.
|
||||
*/
|
||||
static
|
||||
void
|
||||
get_interested_monitor_listeners(mount_id device, vnode_id node,
|
||||
uint32 flags, interested_monitor_listener_list *interestedListeners,
|
||||
int32 &interestedListenerCount)
|
||||
{
|
||||
// get the monitor for the node
|
||||
node_monitor *monitor = get_monitor_for(device, node);
|
||||
if (!monitor)
|
||||
return;
|
||||
|
||||
// iterate through the listeners until we find one with matching flags
|
||||
monitor_listener *listener = NULL;
|
||||
while ((listener = (monitor_listener*)list_get_next_item(
|
||||
&monitor->listeners, listener)) != NULL) {
|
||||
if (listener->flags & flags) {
|
||||
interested_monitor_listener_list &list
|
||||
= interestedListeners[interestedListenerCount++];
|
||||
list.listeners = &monitor->listeners;
|
||||
list.first_listener = listener;
|
||||
list.flags = flags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** \brief Sends a notifcation message to the given listeners.
|
||||
\param message The message to be sent.
|
||||
\param interestedListeners An array of listener lists.
|
||||
\param interestedListenerCount The number of elements in the
|
||||
\a interestedListeners array.
|
||||
\return
|
||||
- \c B_OK, if everything went fine,
|
||||
- another error code otherwise.
|
||||
*/
|
||||
static
|
||||
status_t
|
||||
send_notification_message(KMessage &message,
|
||||
interested_monitor_listener_list *interestedListeners,
|
||||
int32 interestedListenerCount)
|
||||
{
|
||||
// Since the messaging service supports broadcasting and that is more
|
||||
// efficient than sending the messages individually, we collect the
|
||||
// listener targets in an array and send the message to them at once.
|
||||
const int32 maxTargetCount = 16;
|
||||
messaging_target targets[maxTargetCount];
|
||||
int32 targetCount = 0;
|
||||
|
||||
// iterate through the lists
|
||||
interested_monitor_listener_list *list = interestedListeners;
|
||||
for (int32 i = 0; i < interestedListenerCount; i++, list++) {
|
||||
// iterate through the listeners
|
||||
monitor_listener *listener = list->first_listener;
|
||||
do {
|
||||
if (listener->flags & list->flags) {
|
||||
// the listener's flags match: add it to the targets
|
||||
messaging_target &target = targets[targetCount++];
|
||||
target.port = listener->port;
|
||||
target.token = listener->token;
|
||||
|
||||
// if the target array is full, send the message
|
||||
if (targetCount == maxTargetCount) {
|
||||
status_t error = send_message(&message, targets,
|
||||
targetCount);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
targetCount = 0;
|
||||
}
|
||||
}
|
||||
} while ((listener = (monitor_listener*)list_get_next_item(
|
||||
list->listeners, listener)) != NULL);
|
||||
}
|
||||
|
||||
// if any targets are left (the usual case, unless the target array got
|
||||
// full early), send the message
|
||||
if (targetCount > 0)
|
||||
return send_message(&message, targets, targetCount);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Notifies all interested listeners that an entry has been created
|
||||
or removed.
|
||||
\param opcode \c B_ENTRY_CREATED or \c B_ENTRY_REMOVED.
|
||||
\param device The ID of the mounted FS, the entry lives/lived 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/referred to.
|
||||
\return
|
||||
- \c B_OK, if everything went fine,
|
||||
- another error code otherwise.
|
||||
*/
|
||||
static status_t
|
||||
notify_entry_created_or_removed(int32 opcode, mount_id device,
|
||||
vnode_id directory, const char *name, vnode_id node)
|
||||
{
|
||||
if (!name)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
MutexLocker locker(gMonitorMutex);
|
||||
|
||||
// get the lists of all interested listeners
|
||||
interested_monitor_listener_list interestedListeners[3];
|
||||
int32 interestedListenerCount = 0;
|
||||
// ... for the node
|
||||
if (opcode != B_ENTRY_CREATED) {
|
||||
get_interested_monitor_listeners(device, node, B_WATCH_NAME,
|
||||
interestedListeners, interestedListenerCount);
|
||||
}
|
||||
// ... for the directory
|
||||
get_interested_monitor_listeners(device, directory, B_WATCH_DIRECTORY,
|
||||
interestedListeners, interestedListenerCount);
|
||||
|
||||
if (interestedListenerCount == 0)
|
||||
return B_OK;
|
||||
|
||||
// there are interested listeners: construct the message and send it
|
||||
char messageBuffer[1024];
|
||||
KMessage message;
|
||||
message.SetTo(messageBuffer, sizeof(messageBuffer), B_NODE_MONITOR);
|
||||
message.AddInt32("opcode", opcode);
|
||||
message.AddInt32("device", device);
|
||||
message.AddInt64("directory", directory);
|
||||
message.AddInt64("node", node);
|
||||
message.AddString("name", name); // for "removed" Haiku only
|
||||
|
||||
return send_notification_message(message, interestedListeners,
|
||||
interestedListenerCount);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Notifies all interested listeners that an entry has been created.
|
||||
\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.
|
||||
* \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_entry_created(mount_id device, vnode_id directory, const char *name,
|
||||
vnode_id node)
|
||||
@ -679,14 +782,15 @@ notify_entry_created(mount_id device, vnode_id directory, const char *name,
|
||||
|
||||
|
||||
/** \brief Notifies all interested listeners that an entry has been removed.
|
||||
\param device The ID of the mounted FS, the entry lived in.
|
||||
\param directory The entry's former parent directory ID.
|
||||
\param name The entry's name.
|
||||
\param node The ID of the node the entry referred to.
|
||||
\return
|
||||
- \c B_OK, if everything went fine,
|
||||
- another error code otherwise.
|
||||
* \param device The ID of the mounted FS, the entry lived in.
|
||||
* \param directory The entry's former parent directory ID.
|
||||
* \param name The entry's name.
|
||||
* \param node The ID of the node the entry referred to.
|
||||
* \return
|
||||
* - \c B_OK, if everything went fine,
|
||||
* - another error code otherwise.
|
||||
*/
|
||||
|
||||
status_t
|
||||
notify_entry_removed(mount_id device, vnode_id directory, const char *name,
|
||||
vnode_id node)
|
||||
@ -697,16 +801,17 @@ notify_entry_removed(mount_id device, vnode_id directory, const char *name,
|
||||
|
||||
|
||||
/** \brief Notifies all interested listeners that an entry has been moved.
|
||||
\param device The ID of the mounted FS, the entry lives in.
|
||||
\param fromDirectory The entry's previous parent directory ID.
|
||||
\param fromName The entry's previous name.
|
||||
\param toDirectory The entry's new parent directory ID.
|
||||
\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.
|
||||
* \param device The ID of the mounted FS, the entry lives in.
|
||||
* \param fromDirectory The entry's previous parent directory ID.
|
||||
* \param fromName The entry's previous name.
|
||||
* \param toDirectory The entry's new parent directory ID.
|
||||
* \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_entry_moved(mount_id device, vnode_id fromDirectory,
|
||||
const char *fromName, vnode_id toDirectory, const char *toName,
|
||||
@ -757,16 +862,17 @@ notify_entry_moved(mount_id device, vnode_id fromDirectory,
|
||||
|
||||
|
||||
/** \brief Notifies all interested listeners that a node's stat data have
|
||||
changed.
|
||||
\param device The ID of the mounted FS, the node lives in.
|
||||
\param node The ID of the node.
|
||||
\param statFields A bitwise combination of one or more of the \c B_STAT_*
|
||||
constants defined in <NodeMonitor.h>, indicating what fields of the
|
||||
stat data have changed.
|
||||
\return
|
||||
- \c B_OK, if everything went fine,
|
||||
- another error code otherwise.
|
||||
* changed.
|
||||
* \param device The ID of the mounted FS, the node lives in.
|
||||
* \param node The ID of the node.
|
||||
* \param statFields A bitwise combination of one or more of the \c B_STAT_*
|
||||
* constants defined in <NodeMonitor.h>, indicating what fields of the
|
||||
* stat data have changed.
|
||||
* \return
|
||||
* - \c B_OK, if everything went fine,
|
||||
* - another error code otherwise.
|
||||
*/
|
||||
|
||||
status_t
|
||||
notify_stat_changed(mount_id device, vnode_id node, uint32 statFields)
|
||||
{
|
||||
@ -797,15 +903,16 @@ notify_stat_changed(mount_id device, vnode_id node, uint32 statFields)
|
||||
|
||||
|
||||
/** \brief Notifies all interested listeners that a node attribute has changed.
|
||||
\param device The ID of the mounted FS, the node lives in.
|
||||
\param node The ID of the node.
|
||||
\param attribute The attribute's name.
|
||||
\param cause Either of \c B_ATTR_CREATED, \c B_ATTR_REMOVED, or
|
||||
\c B_ATTR_CHANGED, indicating what exactly happened to the attribute.
|
||||
\return
|
||||
- \c B_OK, if everything went fine,
|
||||
- another error code otherwise.
|
||||
* \param device The ID of the mounted FS, the node lives in.
|
||||
* \param node The ID of the node.
|
||||
* \param attribute The attribute's name.
|
||||
* \param cause Either of \c B_ATTR_CREATED, \c B_ATTR_REMOVED, or
|
||||
* \c B_ATTR_CHANGED, indicating what exactly happened to the attribute.
|
||||
* \return
|
||||
* - \c B_OK, if everything went fine,
|
||||
* - another error code otherwise.
|
||||
*/
|
||||
|
||||
status_t
|
||||
notify_attribute_changed(mount_id device, vnode_id node, const char *attribute,
|
||||
int32 cause)
|
||||
@ -841,56 +948,18 @@ notify_attribute_changed(mount_id device, vnode_id node, const char *attribute,
|
||||
|
||||
|
||||
/** \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.
|
||||
\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.
|
||||
* to 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.
|
||||
*/
|
||||
static status_t
|
||||
notify_query_entry_created_or_removed(int32 opcode, port_id port, int32 token,
|
||||
mount_id device, vnode_id directory, const char *name, vnode_id 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);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Notifies the listener of a live query that an entry has been added
|
||||
to 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_entry_created(port_id port, int32 token, mount_id device,
|
||||
vnode_id directory, const char *name, vnode_id node)
|
||||
@ -901,17 +970,18 @@ notify_query_entry_created(port_id port, int32 token, mount_id device,
|
||||
|
||||
|
||||
/** \brief Notifies the listener of a live query that an entry has been removed
|
||||
from 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.
|
||||
* from 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_entry_removed(port_id port, int32 token,
|
||||
mount_id device, vnode_id directory, const char *name, vnode_id node)
|
||||
@ -921,9 +991,7 @@ notify_query_entry_removed(port_id port, int32 token,
|
||||
}
|
||||
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// Userland syscalls
|
||||
// #pragma mark - User syscalls
|
||||
|
||||
|
||||
status_t
|
||||
|
@ -5061,6 +5061,9 @@ fs_mount(char *path, const char *device, const char *fsName, uint32 flags,
|
||||
fileDeviceDeleter.id = -1;
|
||||
}
|
||||
|
||||
notify_mount(mount->id, mount->covers_vnode ? mount->covers_vnode->device : -1,
|
||||
mount->covers_vnode ? mount->covers_vnode->id : -1);
|
||||
|
||||
return mount->id;
|
||||
|
||||
err7:
|
||||
@ -5295,6 +5298,7 @@ fs_unmount(char *path, uint32 flags, bool kernel)
|
||||
mountOpLocker.Unlock();
|
||||
|
||||
FS_MOUNT_CALL(mount, unmount)(mount->cookie);
|
||||
notify_unmount(mount->id);
|
||||
|
||||
// release the file system
|
||||
put_file_system(mount->fs);
|
||||
|
Loading…
Reference in New Issue
Block a user