xref: /haiku/src/kits/storage/NodeMonitor.cpp (revision 90ae2e54f6ccaca73c011a2aa4cdd660417108ad)
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 | B_WATCH_STAT | B_WATCH_ATTR)) == 0)
42 		return B_BAD_VALUE;
43 
44 	flags |= B_WATCH_VOLUME;
45 
46 	BMessenger::Private messengerPrivate(target);
47 	port_id port = messengerPrivate.Port();
48 	int32 token = messengerPrivate.Token();
49 	return _kern_start_watching(volume, (ino_t)-1, flags, port, token);
50 }
51 
52 
53 status_t
54 watch_volume(dev_t volume, uint32 flags, const BHandler *handler,
55 	const BLooper *looper)
56 {
57 	return watch_volume(volume, flags, BMessenger(handler, looper));
58 }
59 
60 
61 // watch_node
62 /*!	\brief Subscribes a target to node and/or mount watching, or unsubscribes
63 		   it from node watching.
64 
65 	Depending of \a flags the action performed by this function varies:
66 	- \a flags is \c 0: The target is unsubscribed from watching the node.
67 	  \a node must not be \c NULL in this case.
68 	- \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount
69 	  watching.
70 	- \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT,
71 	  \c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to
72 	  watching the specified aspects of the node. \a node must not be \c NULL
73 	  in this case.
74 
75 	Note, that the latter two cases are not mutual exlusive, i.e. mount and
76 	node watching can be requested with a single call.
77 
78 	\param node node_ref referring to the node to be watched. May be \c NULL,
79 		   if only mount watching is requested.
80 	\param flags Flags indicating the actions to be performed.
81 	\param target Messenger referring to the target. Must be valid.
82 	\return \c B_OK, if everything went fine, another error code otherwise.
83 */
84 status_t
85 watch_node(const node_ref *node, uint32 flags, BMessenger target)
86 {
87 	if (!target.IsValid())
88 		return B_BAD_VALUE;
89 
90 	BMessenger::Private messengerPrivate(target);
91 	port_id port = messengerPrivate.Port();
92 	int32 token = messengerPrivate.Token();
93 
94 	if (flags == B_STOP_WATCHING) {
95 		// unsubscribe from node node watching
96 		if (node == NULL)
97 			return B_BAD_VALUE;
98 
99 		return _kern_stop_watching(node->device, node->node, port, token);
100 	}
101 
102 	// subscribe to...
103 	// mount watching
104 	if (flags & B_WATCH_MOUNT) {
105 		status_t status = _kern_start_watching((dev_t)-1, (ino_t)-1,
106 			B_WATCH_MOUNT, port, token);
107 		if (status < B_OK)
108 			return status;
109 
110 		flags &= ~B_WATCH_MOUNT;
111 	}
112 
113 	// node watching
114 	if (flags != 0) {
115 		if (node == NULL)
116 			return B_BAD_VALUE;
117 
118 		return _kern_start_watching(node->device, node->node, flags, port,
119 			token);
120 	}
121 
122 	return B_OK;
123 }
124 
125 // watch_node
126 /*!	\brief Subscribes a target to node and/or mount watching, or unsubscribes
127 		   it from node watching.
128 
129 	Depending of \a flags the action performed by this function varies:
130 	- \a flags is \c 0: The target is unsubscribed from watching the node.
131 	  \a node must not be \c NULL in this case.
132 	- \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount
133 	  watching.
134 	- \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT,
135 	  \c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to
136 	  watching the specified aspects of the node. \a node must not be \c NULL
137 	  in this case.
138 
139 	Note, that the latter two cases are not mutual exlusive, i.e. mount and
140 	node watching can be requested with a single call.
141 
142 	\param node node_ref referring to the node to be watched. May be \c NULL,
143 		   if only mount watching is requested.
144 	\param flags Flags indicating the actions to be performed.
145 	\param handler The target handler. May be \c NULL, if \a looper is not
146 		   \c NULL. Then the preferred handler of the looper is targeted.
147 	\param looper The target looper. May be \c NULL, if \a handler is not
148 		   \c NULL. Then the handler's looper is the target looper.
149 	\return \c B_OK, if everything went fine, another error code otherwise.
150 */
151 status_t
152 watch_node(const node_ref *node, uint32 flags, const BHandler *handler,
153 	const BLooper *looper)
154 {
155 	return watch_node(node, flags, BMessenger(handler, looper));
156 }
157 
158 
159 /*!	\brief Unsubscribes a target from node and mount monitoring.
160 	\param target Messenger referring to the target. Must be valid.
161 	\return \c B_OK, if everything went fine, another error code otherwise.
162 */
163 status_t
164 stop_watching(BMessenger target)
165 {
166 	if (!target.IsValid())
167 		return B_BAD_VALUE;
168 
169 	BMessenger::Private messengerPrivate(target);
170 	port_id port = messengerPrivate.Port();
171 	int32 token = messengerPrivate.Token();
172 
173 	return _kern_stop_notifying(port, token);
174 }
175 
176 
177 /*!	\brief Unsubscribes a target from node and mount monitoring.
178 	\param handler The target handler. May be \c NULL, if \a looper is not
179 		   \c NULL. Then the preferred handler of the looper is targeted.
180 	\param looper The target looper. May be \c NULL, if \a handler is not
181 		   \c NULL. Then the handler's looper is the target looper.
182 	\return \c B_OK, if everything went fine, another error code otherwise.
183 */
184 status_t
185 stop_watching(const BHandler *handler, const BLooper *looper)
186 {
187 	return stop_watching(BMessenger(handler, looper));
188 }
189 
190