xref: /haiku/src/kits/storage/NodeMonitor.cpp (revision 25a7b01d15612846f332751841da3579db313082)
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 // Subscribes a target to watch node changes on a volume.
26 status_t
27 watch_volume(dev_t volume, uint32 flags, BMessenger target)
28 {
29 	if ((flags & (B_WATCH_NAME | B_WATCH_STAT | B_WATCH_ATTR)) == 0)
30 		return B_BAD_VALUE;
31 
32 	flags |= B_WATCH_VOLUME;
33 
34 	BMessenger::Private messengerPrivate(target);
35 	port_id port = messengerPrivate.Port();
36 	int32 token = messengerPrivate.Token();
37 	return _kern_start_watching(volume, (ino_t)-1, flags, port, token);
38 }
39 
40 
41 status_t
42 watch_volume(dev_t volume, uint32 flags, const BHandler *handler,
43 	const BLooper *looper)
44 {
45 	return watch_volume(volume, flags, BMessenger(handler, looper));
46 }
47 
48 
49 // Subscribes or unsubscribes a target to node and/or mount watching.
50 status_t
51 watch_node(const node_ref *node, uint32 flags, BMessenger target)
52 {
53 	if (!target.IsValid())
54 		return B_BAD_VALUE;
55 
56 	BMessenger::Private messengerPrivate(target);
57 	port_id port = messengerPrivate.Port();
58 	int32 token = messengerPrivate.Token();
59 
60 	if (flags == B_STOP_WATCHING) {
61 		// unsubscribe from node node watching
62 		if (node == NULL)
63 			return B_BAD_VALUE;
64 
65 		return _kern_stop_watching(node->device, node->node, port, token);
66 	}
67 
68 	// subscribe to...
69 	// mount watching
70 	if (flags & B_WATCH_MOUNT) {
71 		status_t status = _kern_start_watching((dev_t)-1, (ino_t)-1,
72 			B_WATCH_MOUNT, port, token);
73 		if (status < B_OK)
74 			return status;
75 
76 		flags &= ~B_WATCH_MOUNT;
77 	}
78 
79 	// node watching
80 	if (flags != 0) {
81 		if (node == NULL)
82 			return B_BAD_VALUE;
83 
84 		return _kern_start_watching(node->device, node->node, flags, port,
85 			token);
86 	}
87 
88 	return B_OK;
89 }
90 
91 
92 // Subscribes or unsubscribes a handler or looper to node and/or mount
93 // watching.
94 status_t
95 watch_node(const node_ref *node, uint32 flags, const BHandler *handler,
96 	const BLooper *looper)
97 {
98 	return watch_node(node, flags, BMessenger(handler, looper));
99 }
100 
101 
102 // Unsubscribes a target from node and mount monitoring.
103 status_t
104 stop_watching(BMessenger target)
105 {
106 	if (!target.IsValid())
107 		return B_BAD_VALUE;
108 
109 	BMessenger::Private messengerPrivate(target);
110 	port_id port = messengerPrivate.Port();
111 	int32 token = messengerPrivate.Token();
112 
113 	return _kern_stop_notifying(port, token);
114 }
115 
116 
117 // Unsubscribes a target from node and mount monitoring.
118 status_t
119 stop_watching(const BHandler *handler, const BLooper *looper)
120 {
121 	return stop_watching(BMessenger(handler, looper));
122 }
123 
124