xref: /haiku/src/kits/storage/NodeMonitor.cpp (revision a7dde370f552f5376edbf25046ec9cf2ba8bbd1a)
1 /*
2  * Copyright 2001-2010, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Ingo Weinhold, bonefish@@users.sf.net
7  *		Axel Dörfler, axeld@pinc-software.de
8  *		Clemens Zeidler <haiku@clemens-zeidler.de>
9  */
10 
11 
12 #include <Messenger.h>
13 #include <NodeMonitor.h>
14 
15 #include <MessengerPrivate.h>
16 
17 #include <syscalls.h>
18 
19 #include "node_monitor_private.h"
20 
21 
22 // TODO: Tests!
23 
24 
25 // watch_volume
26 /*!	\brief Subscribes a target to watch node changes on a volume.
27 
28 	Depending of \a flags the action performed by this function varies:
29 	- \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT,
30 	  or \c B_WATCH_ATTR: The target is subscribed to
31 	  watching the specified aspects of any node on the volume.
32 
33 	\param volume dev_t referring to the volume to be watched.
34 	\param flags Flags indicating the actions to be performed.
35 	\param target Messenger referring to the target. Must be valid.
36 	\return \c B_OK, if everything went fine, another error code otherwise.
37 */
38 status_t
39 watch_volume(dev_t volume, uint32 flags, BMessenger target)
40 {
41 	if ((flags | B_WATCH_NAME) == 0 && (flags | B_WATCH_STAT)
42 		&& (flags | B_WATCH_ATTR))
43 		return B_BAD_VALUE;
44 
45 	flags |= B_WATCH_VOLUME;
46 
47 	BMessenger::Private messengerPrivate(target);
48 	port_id port = messengerPrivate.Port();
49 	int32 token = messengerPrivate.Token();
50 	return _kern_start_watching(volume, (ino_t)-1, flags, port, token);
51 }
52 
53 
54 status_t
55 watch_volume(dev_t volume, uint32 flags, const BHandler *handler,
56 	const BLooper *looper)
57 {
58 	return watch_volume(volume, flags, BMessenger(handler, looper));
59 }
60 
61 
62 // watch_node
63 /*!	\brief Subscribes a target to node and/or mount watching, or unsubscribes
64 		   it from node watching.
65 
66 	Depending of \a flags the action performed by this function varies:
67 	- \a flags is \c 0: The target is unsubscribed from watching the node.
68 	  \a node must not be \c NULL in this case.
69 	- \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount
70 	  watching.
71 	- \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT,
72 	  \c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to
73 	  watching the specified aspects of the node. \a node must not be \c NULL
74 	  in this case.
75 
76 	Note, that the latter two cases are not mutual exlusive, i.e. mount and
77 	node watching can be requested with a single call.
78 
79 	\param node node_ref referring to the node to be watched. May be \c NULL,
80 		   if only mount watching is requested.
81 	\param flags Flags indicating the actions to be performed.
82 	\param target Messenger referring to the target. Must be valid.
83 	\return \c B_OK, if everything went fine, another error code otherwise.
84 */
85 status_t
86 watch_node(const node_ref *node, uint32 flags, BMessenger target)
87 {
88 	if (!target.IsValid())
89 		return B_BAD_VALUE;
90 
91 	BMessenger::Private messengerPrivate(target);
92 	port_id port = messengerPrivate.Port();
93 	int32 token = messengerPrivate.Token();
94 
95 	if (flags == B_STOP_WATCHING) {
96 		// unsubscribe from node node watching
97 		if (node == NULL)
98 			return B_BAD_VALUE;
99 
100 		return _kern_stop_watching(node->device, node->node, port, token);
101 	}
102 
103 	// subscribe to...
104 	// mount watching
105 	if (flags & B_WATCH_MOUNT) {
106 		status_t status = _kern_start_watching((dev_t)-1, (ino_t)-1,
107 			B_WATCH_MOUNT, port, token);
108 		if (status < B_OK)
109 			return status;
110 
111 		flags &= ~B_WATCH_MOUNT;
112 	}
113 
114 	// node watching
115 	if (flags != 0) {
116 		if (node == NULL)
117 			return B_BAD_VALUE;
118 
119 		return _kern_start_watching(node->device, node->node, flags, port,
120 			token);
121 	}
122 
123 	return B_OK;
124 }
125 
126 // watch_node
127 /*!	\brief Subscribes a target to node and/or mount watching, or unsubscribes
128 		   it from node watching.
129 
130 	Depending of \a flags the action performed by this function varies:
131 	- \a flags is \c 0: The target is unsubscribed from watching the node.
132 	  \a node must not be \c NULL in this case.
133 	- \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount
134 	  watching.
135 	- \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT,
136 	  \c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to
137 	  watching the specified aspects of the node. \a node must not be \c NULL
138 	  in this case.
139 
140 	Note, that the latter two cases are not mutual exlusive, i.e. mount and
141 	node watching can be requested with a single call.
142 
143 	\param node node_ref referring to the node to be watched. May be \c NULL,
144 		   if only mount watching is requested.
145 	\param flags Flags indicating the actions to be performed.
146 	\param handler The target handler. May be \c NULL, if \a looper is not
147 		   \c NULL. Then the preferred handler of the looper is targeted.
148 	\param looper The target looper. May be \c NULL, if \a handler is not
149 		   \c NULL. Then the handler's looper is the target looper.
150 	\return \c B_OK, if everything went fine, another error code otherwise.
151 */
152 status_t
153 watch_node(const node_ref *node, uint32 flags, const BHandler *handler,
154 	const BLooper *looper)
155 {
156 	return watch_node(node, flags, BMessenger(handler, looper));
157 }
158 
159 
160 /*!	\brief Unsubscribes a target from node and mount monitoring.
161 	\param target Messenger referring to the target. Must be valid.
162 	\return \c B_OK, if everything went fine, another error code otherwise.
163 */
164 status_t
165 stop_watching(BMessenger target)
166 {
167 	if (!target.IsValid())
168 		return B_BAD_VALUE;
169 
170 	BMessenger::Private messengerPrivate(target);
171 	port_id port = messengerPrivate.Port();
172 	int32 token = messengerPrivate.Token();
173 
174 	return _kern_stop_notifying(port, token);
175 }
176 
177 
178 /*!	\brief Unsubscribes a target from node and mount monitoring.
179 	\param handler The target handler. May be \c NULL, if \a looper is not
180 		   \c NULL. Then the preferred handler of the looper is targeted.
181 	\param looper The target looper. May be \c NULL, if \a handler is not
182 		   \c NULL. Then the handler's looper is the target looper.
183 	\return \c B_OK, if everything went fine, another error code otherwise.
184 */
185 status_t
186 stop_watching(const BHandler *handler, const BLooper *looper)
187 {
188 	return stop_watching(BMessenger(handler, looper));
189 }
190 
191