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