We do now provide the BeOS style FS add-ons with the kernel interface they

need via library libuserlandfs_beos_kernel.so. Fine-tuned the legacy headers
so they can by used by the the kernel interface emulation code as well as by
the add-ons. This is actually a bit hacky, since we build everything in the
Haiku build environment and thus mix these old headers and Haiku's.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20254 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2007-02-28 22:07:40 +00:00
parent 9b54c9d1e3
commit c10705cbda
8 changed files with 412 additions and 33 deletions

View File

@ -8,7 +8,7 @@
#include <BeBuild.h>
#include "lock.h"
#include <legacy/lock.h>
#ifndef _IMPEXP_KERNEL
#define _IMPEXP_KERNEL

View File

@ -1,7 +1,7 @@
#ifndef _FSPROTO_H
#define _FSPROTO_H
#include <sys/dirent.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
@ -9,10 +9,12 @@
#include <iovec.h>
#include <OS.h>
#include <fs_attr.h>
#include <fs_info.h>
#include <BeBuild.h>
#include <Drivers.h>
#ifndef BUILDING_USERLAND_FS_SERVER
# include <fs_attr.h>
# include <fs_info.h>
# include <fs_volume.h>
#endif // ! BUILDING_USERLAND_FS_SERVER
#ifndef _IMPEXP_KERNEL
#define _IMPEXP_KERNEL
@ -62,6 +64,7 @@ typedef ino_t vnode_id;
struct attr_info;
struct index_info;
typedef struct selectsync selectsync;
typedef int op_read_vnode(void *ns, vnode_id vnid, char r, void **node);
typedef int op_write_vnode(void *ns, void *node, char r);

View File

@ -1,5 +1,5 @@
SubDir HAIKU_TOP src add-ons kernel file_systems userlandfs ;
SubInclude HAIKU_TOP src add-ons kernel file_systems userlandfs kernel_add_on ;
#SubInclude HAIKU_TOP src add-ons kernel file_systems userlandfs server ;
SubInclude HAIKU_TOP src add-ons kernel file_systems userlandfs server ;
#SubInclude HAIKU_TOP src add-ons kernel file_systems userlandfs ufs_mount ;

View File

@ -181,9 +181,7 @@ BeOSKernelVolume::Select(fs_vnode node, fs_cookie cookie, uint8 event,
uint32 ref, selectsync* sync)
{
if (!fFSOps->select) {
// TODO: ...
// UserlandFS::KernelEmu::notify_select_event(sync, ref, event);
UserlandFS::KernelEmu::notify_select_event(sync, ref);
UserlandFS::KernelEmu::notify_select_event(sync, ref, event);
return B_OK;
}
return fFSOps->select(fVolumeCookie, node, cookie, event, ref, sync);

View File

@ -4,7 +4,7 @@ local userlandFSTop = [ FDirName $(HAIKU_TOP) src add-ons kernel
file_systems userlandfs ] ;
local userlandFSIncludes = [ PrivateHeaders userlandfs ] ;
#SubDirSysHdrs [ FDirName $(userlandFSIncludes) legacy ] ;
SubDirSysHdrs [ FDirName $(userlandFSIncludes) ] ;
SubDirHdrs [ FDirName $(userlandFSIncludes) private ] ;
SubDirHdrs [ FDirName $(userlandFSIncludes) shared ] ;
@ -13,6 +13,7 @@ SEARCH_SOURCE += [ FDirName $(userlandFSTop) shared ] ;
DEFINES += USER=1 ;
DEFINES += DEBUG_APP="\\\"UserlandFSServer\\\"" ;
DEFINES += BUILDING_USERLAND_FS_SERVER=1 ;
Application UserlandFSServer
: AreaSupport.cpp
@ -49,3 +50,9 @@ Application UserlandFSServer
Volume.cpp
: be
;
# the library providing the BeOS kernel interface for add-ons
SharedLibrary libuserlandfs_beos_kernel.so
: beos_kernel_emu.cpp
: <nogrist>UserlandFSServer
;

View File

@ -0,0 +1,315 @@
// beos_kernel_emu.cpp
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <legacy/cache.h>
#include <legacy/fsproto.h>
#include <legacy/lock.h>
#include "beos_fs_cache.h"
#include "beos_lock.h"
#include "kernel_emu.h"
// #pragma mark - Paths
// new_path
int
new_path(const char *path, char **copy)
{
return UserlandFS::KernelEmu::new_path(path, copy);
}
// free_path
void
free_path(char *p)
{
UserlandFS::KernelEmu::free_path(p);
}
// #pragma mark - Notifications
// notify_listener
int
notify_listener(int op, nspace_id nsid, vnode_id vnida, vnode_id vnidb,
vnode_id vnidc, const char *name)
{
return UserlandFS::KernelEmu::notify_listener(op, nsid, vnida, vnidb, vnidc,
name);
}
// notify_select_event
void
notify_select_event(selectsync *sync, uint32 ref)
{
// TODO: Check what best to supply as event arg!
UserlandFS::KernelEmu::notify_select_event(sync, ref, 0);
}
// send_notification
int
send_notification(port_id port, long token, ulong what, long op,
nspace_id nsida, nspace_id nsidb, vnode_id vnida, vnode_id vnidb,
vnode_id vnidc, const char *name)
{
return UserlandFS::KernelEmu::send_notification(port, token, what, op,
nsida, nsidb, vnida, vnidb, vnidc, name);
}
// #pragma mark - VNodes
// get_vnode
int
get_vnode(nspace_id nsid, vnode_id vnid, void **data)
{
return UserlandFS::KernelEmu::get_vnode(nsid, vnid, data);
}
// put_vnode
int
put_vnode(nspace_id nsid, vnode_id vnid)
{
return UserlandFS::KernelEmu::put_vnode(nsid, vnid);
}
// new_vnode
int
new_vnode(nspace_id nsid, vnode_id vnid, void *data)
{
return UserlandFS::KernelEmu::new_vnode(nsid, vnid, data);
}
// remove_vnode
int
remove_vnode(nspace_id nsid, vnode_id vnid)
{
return UserlandFS::KernelEmu::remove_vnode(nsid, vnid);
}
// unremove_vnode
int
unremove_vnode(nspace_id nsid, vnode_id vnid)
{
return UserlandFS::KernelEmu::unremove_vnode(nsid, vnid);
}
// is_vnode_removed
int
is_vnode_removed(nspace_id nsid, vnode_id vnid)
{
return UserlandFS::KernelEmu::is_vnode_removed(nsid, vnid);
}
// #pragma mark - Block Cache
int
new_lock(lock *l, const char *name)
{
return beos_new_lock((beos_lock*)l, name);
}
int
free_lock(lock *l)
{
return beos_free_lock((beos_lock*)l);
}
int
new_mlock(mlock *l, long c, const char *name)
{
return beos_new_mlock((beos_mlock*)l, c, name);
}
int
free_mlock(mlock *l)
{
return beos_free_mlock((beos_mlock*)l);
}
// #pragma mark - Block Cache
// init_block_cache
int
init_block_cache(int max_blocks, int flags)
{
return beos_init_block_cache(max_blocks, flags);
}
void
shutdown_block_cache(void)
{
beos_shutdown_block_cache();
}
void
force_cache_flush(int dev, int prefer_log_blocks)
{
beos_force_cache_flush(dev, prefer_log_blocks);
}
int
flush_blocks(int dev, off_t bnum, int nblocks)
{
return beos_flush_blocks(dev, bnum, nblocks);
}
int
flush_device(int dev, int warn_locked)
{
return beos_flush_device(dev, warn_locked);
}
int
init_cache_for_device(int fd, off_t max_blocks)
{
return beos_init_cache_for_device(fd, max_blocks);
}
int
remove_cached_device_blocks(int dev, int allow_write)
{
return beos_remove_cached_device_blocks(dev, allow_write);
}
void *
get_block(int dev, off_t bnum, int bsize)
{
return beos_get_block(dev, bnum, bsize);
}
void *
get_empty_block(int dev, off_t bnum, int bsize)
{
return beos_get_empty_block(dev, bnum, bsize);
}
int
release_block(int dev, off_t bnum)
{
return beos_release_block(dev, bnum);
}
int
mark_blocks_dirty(int dev, off_t bnum, int nblocks)
{
return beos_mark_blocks_dirty(dev, bnum, nblocks);
}
int
cached_read(int dev, off_t bnum, void *data, off_t num_blocks, int bsize)
{
return beos_cached_read(dev, bnum, data, num_blocks, bsize);
}
int
cached_write(int dev, off_t bnum, const void *data, off_t num_blocks, int bsize)
{
return beos_cached_write(dev, bnum, data, num_blocks, bsize);
}
int
cached_write_locked(int dev, off_t bnum, const void *data, off_t num_blocks,
int bsize)
{
return beos_cached_write_locked(dev, bnum, data, num_blocks, bsize);
}
int
set_blocks_info(int dev, off_t *blocks, int nblocks,
void (*func)(off_t bnum, size_t nblocks, void *arg), void *arg)
{
return beos_set_blocks_info(dev, blocks, nblocks, func, arg);
}
size_t
read_phys_blocks(int fd, off_t bnum, void *data, uint num_blocks, int bsize)
{
return beos_read_phys_blocks(fd, bnum, data, num_blocks, bsize);
}
size_t
write_phys_blocks(int fd, off_t bnum, void *data, uint num_blocks, int bsize)
{
return beos_write_phys_blocks(fd, bnum, data, num_blocks, bsize);
}
// #pragma mark - Misc
// kernel_debugger
void
kernel_debugger(const char *message)
{
UserlandFS::KernelEmu::kernel_debugger(message);
}
// panic
void
panic(const char *format, ...)
{
char buffer[1024];
strcpy(buffer, "PANIC: ");
int32 prefixLen = strlen(buffer);
int bufferSize = sizeof(buffer) - prefixLen;
va_list args;
va_start(args, format);
// no vsnprintf() on PPC
#if defined(__INTEL__)
vsnprintf(buffer + prefixLen, bufferSize - 1, format, args);
#else
vsprintf(buffer + prefixLen, format, args);
#endif
va_end(args);
buffer[sizeof(buffer) - 1] = '\0';
debugger(buffer);
}
// parse_expression
//ulong
//parse_expression(char *str)
//{
// return 0;
//}
// add_debugger_command
int
add_debugger_command(char *name,
int (*func)(int argc, char **argv), char *help)
{
return B_OK;
}
// remove_debugger_command
int
remove_debugger_command(char *name,
int (*func)(int argc, char **argv))
{
return B_OK;
}
// kprintf
void
kprintf(const char *format, ...)
{
}
// spawn_kernel_thread
thread_id
spawn_kernel_thread(thread_entry function, const char *threadName,
long priority, void *arg)
{
return UserlandFS::KernelEmu::spawn_kernel_thread(function, threadName,
priority, arg);
}

View File

@ -99,8 +99,10 @@ UserlandFS::KernelEmu::free_path(char *p)
free(p);
}
// #pragma mark -
// get_port_and_fs
static status_t
get_port_and_fs(RequestPort** port, FileSystem** fileSystem)
@ -120,7 +122,7 @@ get_port_and_fs(RequestPort** port, FileSystem** fileSystem)
}
// notify_listener
int
status_t
UserlandFS::KernelEmu::notify_listener(int op, mount_id nsid, vnode_id vnida,
vnode_id vnidb, vnode_id vnidc, const char *name)
{
@ -130,12 +132,14 @@ UserlandFS::KernelEmu::notify_listener(int op, mount_id nsid, vnode_id vnida,
status_t error = get_port_and_fs(&port, &fileSystem);
if (error != B_OK)
return error;
// prepare the request
RequestAllocator allocator(port->GetPort());
NotifyListenerRequest* request;
error = AllocateRequest(allocator, &request);
if (error != B_OK)
return error;
request->operation = op;
request->nsid = nsid;
request->vnida = vnida;
@ -144,6 +148,7 @@ UserlandFS::KernelEmu::notify_listener(int op, mount_id nsid, vnode_id vnida,
error = allocator.AllocateString(request->name, name);
if (error != B_OK)
return error;
// send the request
UserlandRequestHandler handler(fileSystem, NOTIFY_LISTENER_REPLY);
NotifyListenerReply* reply;
@ -151,6 +156,7 @@ UserlandFS::KernelEmu::notify_listener(int op, mount_id nsid, vnode_id vnida,
if (error != B_OK)
return error;
RequestReleaser requestReleaser(port, reply);
// process the reply
if (reply->error != B_OK)
return reply->error;
@ -159,7 +165,8 @@ UserlandFS::KernelEmu::notify_listener(int op, mount_id nsid, vnode_id vnida,
// notify_select_event
void
UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref)
UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref,
uint8 event)
{
// get the request port and the file system
RequestPort* port;
@ -167,14 +174,18 @@ UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref)
status_t error = get_port_and_fs(&port, &fileSystem);
if (error != B_OK)
return;
// prepare the request
RequestAllocator allocator(port->GetPort());
NotifySelectEventRequest* request;
error = AllocateRequest(allocator, &request);
if (error != B_OK)
return;
request->sync = sync;
request->ref = ref;
request->event = event;
// send the request
UserlandRequestHandler handler(fileSystem, NOTIFY_SELECT_EVENT_REPLY);
NotifySelectEventReply* reply;
@ -182,11 +193,12 @@ UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref)
if (error != B_OK)
return;
RequestReleaser requestReleaser(port, reply);
// process the reply: nothing to do
}
// send_notification
int
status_t
UserlandFS::KernelEmu::send_notification(port_id targetPort, long token,
ulong what, long op, mount_id nsida, mount_id nsidb, vnode_id vnida,
vnode_id vnidb, vnode_id vnidc, const char *name)
@ -197,12 +209,14 @@ UserlandFS::KernelEmu::send_notification(port_id targetPort, long token,
status_t error = get_port_and_fs(&port, &fileSystem);
if (error != B_OK)
return error;
// prepare the request
RequestAllocator allocator(port->GetPort());
SendNotificationRequest* request;
error = AllocateRequest(allocator, &request);
if (error != B_OK)
return error;
request->port = targetPort;
request->token = token;
request->what = what;
@ -215,6 +229,7 @@ UserlandFS::KernelEmu::send_notification(port_id targetPort, long token,
error = allocator.AllocateString(request->name, name);
if (error != B_OK)
return error;
// send the request
UserlandRequestHandler handler(fileSystem, SEND_NOTIFICATION_REPLY);
SendNotificationReply* reply;
@ -222,17 +237,20 @@ UserlandFS::KernelEmu::send_notification(port_id targetPort, long token,
if (error != B_OK)
return error;
RequestReleaser requestReleaser(port, reply);
// process the reply
if (reply->error != B_OK)
return reply->error;
return error;
}
// #pragma mark -
// get_vnode
int
UserlandFS::KernelEmu::get_vnode(mount_id nsid, vnode_id vnid, void** data)
status_t
UserlandFS::KernelEmu::get_vnode(mount_id nsid, vnode_id vnid, fs_vnode* data)
{
// get the request port and the file system
RequestPort* port;
@ -240,14 +258,17 @@ UserlandFS::KernelEmu::get_vnode(mount_id nsid, vnode_id vnid, void** data)
status_t error = get_port_and_fs(&port, &fileSystem);
if (error != B_OK)
return error;
// prepare the request
RequestAllocator allocator(port->GetPort());
GetVNodeRequest* request;
error = AllocateRequest(allocator, &request);
if (error != B_OK)
return error;
request->nsid = nsid;
request->vnid = vnid;
// send the request
UserlandRequestHandler handler(fileSystem, GET_VNODE_REPLY);
GetVNodeReply* reply;
@ -255,6 +276,7 @@ UserlandFS::KernelEmu::get_vnode(mount_id nsid, vnode_id vnid, void** data)
if (error != B_OK)
return error;
RequestReleaser requestReleaser(port, reply);
// process the reply
if (reply->error != B_OK)
return reply->error;
@ -263,7 +285,7 @@ UserlandFS::KernelEmu::get_vnode(mount_id nsid, vnode_id vnid, void** data)
}
// put_vnode
int
status_t
UserlandFS::KernelEmu::put_vnode(mount_id nsid, vnode_id vnid)
{
// get the request port and the file system
@ -272,14 +294,17 @@ UserlandFS::KernelEmu::put_vnode(mount_id nsid, vnode_id vnid)
status_t error = get_port_and_fs(&port, &fileSystem);
if (error != B_OK)
return error;
// prepare the request
RequestAllocator allocator(port->GetPort());
PutVNodeRequest* request;
error = AllocateRequest(allocator, &request);
if (error != B_OK)
return error;
request->nsid = nsid;
request->vnid = vnid;
// send the request
UserlandRequestHandler handler(fileSystem, PUT_VNODE_REPLY);
PutVNodeReply* reply;
@ -287,6 +312,7 @@ UserlandFS::KernelEmu::put_vnode(mount_id nsid, vnode_id vnid)
if (error != B_OK)
return error;
RequestReleaser requestReleaser(port, reply);
// process the reply
if (reply->error != B_OK)
return reply->error;
@ -294,8 +320,8 @@ UserlandFS::KernelEmu::put_vnode(mount_id nsid, vnode_id vnid)
}
// new_vnode
int
UserlandFS::KernelEmu::new_vnode(mount_id nsid, vnode_id vnid, void* data)
status_t
UserlandFS::KernelEmu::new_vnode(mount_id nsid, vnode_id vnid, fs_vnode data)
{
// get the request port and the file system
RequestPort* port;
@ -303,15 +329,18 @@ UserlandFS::KernelEmu::new_vnode(mount_id nsid, vnode_id vnid, void* data)
status_t error = get_port_and_fs(&port, &fileSystem);
if (error != B_OK)
return error;
// prepare the request
RequestAllocator allocator(port->GetPort());
NewVNodeRequest* request;
error = AllocateRequest(allocator, &request);
if (error != B_OK)
return error;
request->nsid = nsid;
request->vnid = vnid;
request->node = data;
// send the request
UserlandRequestHandler handler(fileSystem, NEW_VNODE_REPLY);
NewVNodeReply* reply;
@ -319,14 +348,24 @@ UserlandFS::KernelEmu::new_vnode(mount_id nsid, vnode_id vnid, void* data)
if (error != B_OK)
return error;
RequestReleaser requestReleaser(port, reply);
// process the reply
if (reply->error != B_OK)
return reply->error;
return error;
}
// publish_vnode
status_t
UserlandFS::KernelEmu::publish_vnode(mount_id nsid, vnode_id vnid,
fs_vnode data)
{
// TODO: Implement!
return B_BAD_VALUE;
}
// remove_vnode
int
status_t
UserlandFS::KernelEmu::remove_vnode(mount_id nsid, vnode_id vnid)
{
// get the request port and the file system
@ -335,14 +374,17 @@ UserlandFS::KernelEmu::remove_vnode(mount_id nsid, vnode_id vnid)
status_t error = get_port_and_fs(&port, &fileSystem);
if (error != B_OK)
return error;
// prepare the request
RequestAllocator allocator(port->GetPort());
RemoveVNodeRequest* request;
error = AllocateRequest(allocator, &request);
if (error != B_OK)
return error;
request->nsid = nsid;
request->vnid = vnid;
// send the request
UserlandRequestHandler handler(fileSystem, REMOVE_VNODE_REPLY);
RemoveVNodeReply* reply;
@ -350,6 +392,7 @@ UserlandFS::KernelEmu::remove_vnode(mount_id nsid, vnode_id vnid)
if (error != B_OK)
return error;
RequestReleaser requestReleaser(port, reply);
// process the reply
if (reply->error != B_OK)
return reply->error;
@ -357,7 +400,7 @@ UserlandFS::KernelEmu::remove_vnode(mount_id nsid, vnode_id vnid)
}
// unremove_vnode
int
status_t
UserlandFS::KernelEmu::unremove_vnode(mount_id nsid, vnode_id vnid)
{
// get the request port and the file system
@ -366,14 +409,17 @@ UserlandFS::KernelEmu::unremove_vnode(mount_id nsid, vnode_id vnid)
status_t error = get_port_and_fs(&port, &fileSystem);
if (error != B_OK)
return error;
// prepare the request
RequestAllocator allocator(port->GetPort());
UnremoveVNodeRequest* request;
error = AllocateRequest(allocator, &request);
if (error != B_OK)
return error;
request->nsid = nsid;
request->vnid = vnid;
// send the request
UserlandRequestHandler handler(fileSystem, UNREMOVE_VNODE_REPLY);
UnremoveVNodeReply* reply;
@ -381,6 +427,7 @@ UserlandFS::KernelEmu::unremove_vnode(mount_id nsid, vnode_id vnid)
if (error != B_OK)
return error;
RequestReleaser requestReleaser(port, reply);
// process the reply
if (reply->error != B_OK)
return reply->error;
@ -388,7 +435,7 @@ UserlandFS::KernelEmu::unremove_vnode(mount_id nsid, vnode_id vnid)
}
// is_vnode_removed
int
status_t
UserlandFS::KernelEmu::is_vnode_removed(mount_id nsid, vnode_id vnid)
{
// get the request port and the file system
@ -397,14 +444,17 @@ UserlandFS::KernelEmu::is_vnode_removed(mount_id nsid, vnode_id vnid)
status_t error = get_port_and_fs(&port, &fileSystem);
if (error != B_OK)
return error;
// prepare the request
RequestAllocator allocator(port->GetPort());
IsVNodeRemovedRequest* request;
error = AllocateRequest(allocator, &request);
if (error != B_OK)
return error;
request->nsid = nsid;
request->vnid = vnid;
// send the request
UserlandRequestHandler handler(fileSystem, IS_VNODE_REMOVED_REPLY);
IsVNodeRemovedReply* reply;
@ -412,6 +462,7 @@ UserlandFS::KernelEmu::is_vnode_removed(mount_id nsid, vnode_id vnid)
if (error != B_OK)
return error;
RequestReleaser requestReleaser(port, reply);
// process the reply
if (reply->error != B_OK)
return reply->error;

View File

@ -1,28 +1,33 @@
// kernel_emu.h
#include <fs_interface.h>
#include <KernelExport.h>
#include <OS.h>
struct selectsync;
namespace UserlandFS {
namespace KernelEmu {
typedef int32 mount_id;
typedef int64 vnode_id;
typedef void* fs_vnode;
int new_path(const char *path, char **copy);
void free_path(char *p);
int notify_listener(int op, mount_id nsid, vnode_id vnida, vnode_id vnidb,
status_t notify_listener(int op, mount_id nsid, vnode_id vnida, vnode_id vnidb,
vnode_id vnidc, const char *name);
void notify_select_event(selectsync *sync, uint32 ref);
int send_notification(port_id targetPort, long token, ulong what, long op,
void notify_select_event(selectsync *sync, uint32 ref, uint8 event);
status_t send_notification(port_id targetPort, long token, ulong what, long op,
mount_id nsida, mount_id nsidb, vnode_id vnida, vnode_id vnidb,
vnode_id vnidc, const char *name);
int get_vnode(mount_id nsid, vnode_id vnid, void** data);
int put_vnode(mount_id nsid, vnode_id vnid);
int new_vnode(mount_id nsid, vnode_id vnid, void* data);
int remove_vnode(mount_id nsid, vnode_id vnid);
int unremove_vnode(mount_id nsid, vnode_id vnid);
int is_vnode_removed(mount_id nsid, vnode_id vnid);
status_t get_vnode(mount_id nsid, vnode_id vnid, fs_vnode* data);
status_t put_vnode(mount_id nsid, vnode_id vnid);
status_t new_vnode(mount_id nsid, vnode_id vnid, fs_vnode data);
status_t publish_vnode(mount_id nsid, vnode_id vnid, fs_vnode data);
status_t remove_vnode(mount_id nsid, vnode_id vnid);
status_t unremove_vnode(mount_id nsid, vnode_id vnid);
status_t is_vnode_removed(mount_id nsid, vnode_id vnid);
void kernel_debugger(const char *message);
void panic(const char *format, ...);