1// beos_kernel_emu.cpp
2
3#include "beos_kernel_emu.h"
4
5#include <stdarg.h>
6#include <stdio.h>
7#include <stdlib.h>
8
9#include <AppDefs.h>
10#include <NodeMonitor.h>
11
12#include <legacy/cache.h>
13#include <legacy/fsproto.h>
14#include <legacy/lock.h>
15
16#include "Debug.h"
17
18#include "../kernel_emu.h"
19
20#include "fs_cache.h"
21#include "lock.h"
22
23
24// #pragma mark - Paths
25
26
27// new_path
28int
29new_path(const char *path, char **copy)
30{
31	return UserlandFS::KernelEmu::new_path(path, copy);
32}
33
34// free_path
35void
36free_path(char *p)
37{
38	UserlandFS::KernelEmu::free_path(p);
39}
40
41
42// #pragma mark - Notifications
43
44
45// notify_listener
46int
47notify_listener(int op, nspace_id nsid, ino_t vnida, ino_t vnidb,
48	ino_t vnidc, const char *name)
49{
50	switch (op) {
51		case B_ENTRY_CREATED:
52		case B_ENTRY_REMOVED:
53			if (!name)
54				name = "";
55			return UserlandFS::KernelEmu::notify_listener(op, 0, nsid, 0,
56				vnida, vnidc, NULL, name);
57
58		case B_ENTRY_MOVED:
59			if (!name)
60				name = "";
61			// the old entry name is not available with the old interface
62			return UserlandFS::KernelEmu::notify_listener(op, 0, nsid, vnida,
63				vnidb, vnidc, "", name);
64
65		case B_STAT_CHANGED:
66		{
67			// we don't know what stat field changed, so we mark them all
68			uint32 statFields = B_STAT_MODE | B_STAT_UID | B_STAT_GID
69				| B_STAT_SIZE | B_STAT_ACCESS_TIME | B_STAT_MODIFICATION_TIME
70				| B_STAT_CREATION_TIME | B_STAT_CHANGE_TIME;
71			return UserlandFS::KernelEmu::notify_listener(op, statFields, nsid,
72				0, vnida, vnidc, NULL, NULL);
73		}
74
75		case B_ATTR_CHANGED:
76			if (!name)
77				name = "";
78			return UserlandFS::KernelEmu::notify_listener(op, B_ATTR_CHANGED,
79				nsid, 0, vnida, vnidc, NULL, name);
80
81		default:
82			return B_BAD_VALUE;
83	}
84}
85
86// notify_select_event
87void
88notify_select_event(selectsync *sync, uint32 ref)
89{
90	UserlandFS::KernelEmu::notify_select_event(sync, 0, true);
91}
92
93// send_notification
94int
95send_notification(port_id port, long token, ulong what, long op,
96	nspace_id nsida, nspace_id /*nsidb*/, ino_t vnida, ino_t vnidb,
97	ino_t vnidc, const char *name)
98{
99	if (what != B_QUERY_UPDATE)
100		return B_BAD_VALUE;
101
102	// check the name
103	if (!name)
104		name = "";
105
106	switch (op) {
107		case B_ENTRY_CREATED:
108		case B_ENTRY_REMOVED:
109			return UserlandFS::KernelEmu::notify_query(port, token, op, nsida,
110				vnida, name, vnidc);
111		case B_ENTRY_MOVED:
112		{
113			// translate to a B_ENTRY_REMOVED + B_ENTRY_CREATED pair
114			// We do at least miss the original name though.
115			status_t error = UserlandFS::KernelEmu::notify_query(port, token,
116				B_ENTRY_REMOVED, nsida, vnida, "", vnidc);
117			if (error != B_OK)
118				return error;
119
120			return UserlandFS::KernelEmu::notify_query(port, token,
121				B_ENTRY_CREATED, nsida, vnidb, name, vnidc);
122		}
123
124		default:
125			return B_BAD_VALUE;
126	}
127}
128
129
130// #pragma mark - VNodes
131
132
133// get_vnode
134int
135get_vnode(nspace_id nsid, ino_t vnid, void **data)
136{
137	return UserlandFS::KernelEmu::get_vnode(nsid, vnid, data);
138}
139
140// put_vnode
141int
142put_vnode(nspace_id nsid, ino_t vnid)
143{
144	return UserlandFS::KernelEmu::put_vnode(nsid, vnid);
145}
146
147// new_vnode
148int
149new_vnode(nspace_id nsid, ino_t vnid, void *data)
150{
151	// get the node capabilities
152	FSVNodeCapabilities capabilities;
153	get_beos_file_system_node_capabilities(capabilities);
154
155	// The semantics of new_vnode() has changed. The new publish_vnode()
156	// should work like the former new_vnode().
157	return UserlandFS::KernelEmu::publish_vnode(nsid, vnid, data,
158		capabilities);
159}
160
161// remove_vnode
162int
163remove_vnode(nspace_id nsid, ino_t vnid)
164{
165	return UserlandFS::KernelEmu::remove_vnode(nsid, vnid);
166}
167
168// unremove_vnode
169int
170unremove_vnode(nspace_id nsid, ino_t vnid)
171{
172	return UserlandFS::KernelEmu::unremove_vnode(nsid, vnid);
173}
174
175// is_vnode_removed
176int
177is_vnode_removed(nspace_id nsid, ino_t vnid)
178{
179	bool removed;
180	status_t error = UserlandFS::KernelEmu::get_vnode_removed(nsid, vnid,
181		&removed);
182	if (error != B_OK)
183		return error;
184	return (removed ? 1 : 0);
185}
186
187
188// #pragma mark - Locking
189
190
191int
192new_lock(lock *l, const char *name)
193{
194	return beos_new_lock((beos_lock*)l, name);
195}
196
197int
198free_lock(lock *l)
199{
200	return beos_free_lock((beos_lock*)l);
201}
202
203int
204new_mlock(mlock *l, long c, const char *name)
205{
206	return beos_new_mlock((beos_mlock*)l, c, name);
207}
208
209int
210free_mlock(mlock *l)
211{
212	return beos_free_mlock((beos_mlock*)l);
213}
214
215
216// #pragma mark - Block Cache
217
218
219// init_block_cache
220int
221init_block_cache(int max_blocks, int flags)
222{
223	return beos_init_block_cache(max_blocks, flags);
224}
225
226void
227shutdown_block_cache(void)
228{
229	beos_shutdown_block_cache();
230}
231
232void
233force_cache_flush(int dev, int prefer_log_blocks)
234{
235	beos_force_cache_flush(dev, prefer_log_blocks);
236}
237
238int
239flush_blocks(int dev, off_t bnum, int nblocks)
240{
241	return beos_flush_blocks(dev, bnum, nblocks);
242}
243
244int
245flush_device(int dev, int warn_locked)
246{
247	return beos_flush_device(dev, warn_locked);
248}
249
250int
251init_cache_for_device(int fd, off_t max_blocks)
252{
253	return beos_init_cache_for_device(fd, max_blocks);
254}
255
256int
257remove_cached_device_blocks(int dev, int allow_write)
258{
259	return beos_remove_cached_device_blocks(dev, allow_write);
260}
261
262void *
263get_block(int dev, off_t bnum, int bsize)
264{
265	return beos_get_block(dev, bnum, bsize);
266}
267
268void *
269get_empty_block(int dev, off_t bnum, int bsize)
270{
271	return beos_get_empty_block(dev, bnum, bsize);
272}
273
274int
275release_block(int dev, off_t bnum)
276{
277	return beos_release_block(dev, bnum);
278}
279
280int
281mark_blocks_dirty(int dev, off_t bnum, int nblocks)
282{
283	return beos_mark_blocks_dirty(dev, bnum, nblocks);
284}
285
286int
287cached_read(int dev, off_t bnum, void *data, off_t num_blocks, int bsize)
288{
289	return beos_cached_read(dev, bnum, data, num_blocks, bsize);
290}
291
292int
293cached_write(int dev, off_t bnum, const void *data, off_t num_blocks, int bsize)
294{
295	return beos_cached_write(dev, bnum, data, num_blocks, bsize);
296}
297
298int
299cached_write_locked(int dev, off_t bnum, const void *data, off_t num_blocks,
300	int bsize)
301{
302	return beos_cached_write_locked(dev, bnum, data, num_blocks, bsize);
303}
304
305int
306set_blocks_info(int dev, off_t *blocks, int nblocks,
307	void (*func)(off_t bnum, size_t nblocks, void *arg), void *arg)
308{
309	return beos_set_blocks_info(dev, blocks, nblocks, func, arg);
310}
311
312size_t
313read_phys_blocks(int fd, off_t bnum, void *data, uint num_blocks, int bsize)
314{
315	return beos_read_phys_blocks(fd, bnum, data, num_blocks, bsize);
316}
317
318size_t
319write_phys_blocks(int fd, off_t bnum, void *data, uint num_blocks, int bsize)
320{
321	return beos_write_phys_blocks(fd, bnum, data, num_blocks, bsize);
322}
323
324
325// #pragma mark - Misc
326
327
328// kernel_debugger
329void
330kernel_debugger(const char *message)
331{
332	UserlandFS::KernelEmu::kernel_debugger(message);
333}
334
335// panic
336void
337panic(const char *format, ...)
338{
339	char buffer[1024];
340	strcpy(buffer, "PANIC: ");
341	int32 prefixLen = strlen(buffer);
342
343	va_list args;
344	va_start(args, format);
345	vsnprintf(buffer + prefixLen, sizeof(buffer) - prefixLen, format, args);
346	va_end(args);
347
348	debugger(buffer);
349}
350
351// parse_expression
352//ulong
353//parse_expression(char *str)
354//{
355//	return 0;
356//}
357
358// add_debugger_command
359int
360add_debugger_command(char *name,
361	int (*func)(int argc, char **argv), char *help)
362{
363	return UserlandFS::KernelEmu::add_debugger_command(name, func, help);
364}
365
366// remove_debugger_command
367int
368remove_debugger_command(char *name,
369	int (*func)(int argc, char **argv))
370{
371	return UserlandFS::KernelEmu::remove_debugger_command(name, func);
372}
373
374// parse_expression
375uint32
376parse_expression(const char *string)
377{
378	return UserlandFS::KernelEmu::parse_expression(string);
379}
380
381// dprintf
382void
383dprintf(const char *format, ...)
384{
385	va_list args;
386	va_start(args, format);
387	UserlandFS::KernelEmu::vdprintf(format, args);
388	va_end(args);
389}
390
391// kprintf
392void
393kprintf(const char *format, ...)
394{
395}
396
397// spawn_kernel_thread
398thread_id
399spawn_kernel_thread(thread_entry function, const char *threadName,
400	long priority, void *arg)
401{
402	return UserlandFS::KernelEmu::spawn_kernel_thread(function,	threadName,
403		priority, arg);
404}
405