* The nature of asynchronous I/O is to be asynchronous. So we can't store

an on-stack structure for the request in a hash table when forwarding the
  io() hook. Create a new object (HaikuKernelIORequest) instead and store it
  in a hash table in HaikuKernelFileSystem.
* Some work on the userland side of do_iterative_fd_io().
* Added some missing requests in UserlandFSUtil::is_{kernel,userland}_request().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29505 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-03-14 02:32:25 +00:00
parent 289b6c8d56
commit 7c1ffcb9ec
13 changed files with 373 additions and 96 deletions
+37 -2
View File
@@ -227,6 +227,10 @@ enum {
FILE_CACHE_WRITE_REQUEST,
FILE_CACHE_WRITE_REPLY,
// I/O
DO_ITERATIVE_FD_IO_REQUEST,
DO_ITERATIVE_FD_IO_REPLY,
// general reply
RECEIPT_ACK_REPLY,
@@ -543,7 +547,7 @@ class DoIORequest : public FileRequest {
public:
DoIORequest() : FileRequest(DO_IO_REQUEST) {}
int32 ioRequest;
int32 request;
bool isWrite;
};
@@ -558,7 +562,7 @@ class CancelIORequest : public FileRequest {
public:
CancelIORequest() : FileRequest(CANCEL_IO_REQUEST) {}
int32 ioRequest;
int32 request;
};
// CancelIOReply
@@ -1740,6 +1744,29 @@ public:
};
// #pragma mark - I/O
// DoIterativeFDIORequest
class DoIterativeFDIORequest : public Request {
public:
DoIterativeFDIORequest() : Request(DO_ITERATIVE_FD_IO_REQUEST) {}
status_t GetAddressInfos(AddressInfo* infos, int32* count);
int fd;
int32 request;
void* cookie;
Address vecs;
uint32 vecCount;
};
// DoIterativeFDIOReply
class DoIterativeFDIOReply : public ReplyRequest {
public:
DoIterativeFDIOReply() : ReplyRequest(DO_ITERATIVE_FD_IO_REPLY) {}
};
//////////////////
// General Reply
@@ -2125,6 +2152,11 @@ do_for_request(Request* request, Task& task)
return task((FileCacheWriteRequest*)request);
case FILE_CACHE_WRITE_REPLY:
return task((FileCacheWriteReply*)request);
// I/O
case DO_ITERATIVE_FD_IO_REQUEST:
return task((DoIterativeFDIORequest*)request);
case DO_ITERATIVE_FD_IO_REPLY:
return task((DoIterativeFDIOReply*)request);
// general reply
case RECEIPT_ACK_REPLY:
return task((ReceiptAckReply*)request);
@@ -2340,6 +2372,9 @@ using UserlandFSUtil::FileCacheReadRequest;
using UserlandFSUtil::FileCacheReadReply;
using UserlandFSUtil::FileCacheWriteRequest;
using UserlandFSUtil::FileCacheWriteReply;
// I/O
using UserlandFSUtil::DoIterativeFDIORequest;
using UserlandFSUtil::DoIterativeFDIOReply;
// general reply
using UserlandFSUtil::ReceiptAckReply;
@@ -313,6 +313,14 @@ FileCacheWriteRequest::GetAddressInfos(AddressInfo* infos, int32* count)
return B_OK;
}
// DoIterativeFDIORequest
status_t
DoIterativeFDIORequest::GetAddressInfos(AddressInfo* infos, int32* count)
{
ADD_ADDRESS(vecs);
return B_OK;
}
// #pragma mark -
@@ -531,6 +539,13 @@ UserlandFSUtil::is_kernel_request(uint32 type)
case WRITE_VNODE_REPLY:
case FS_REMOVE_VNODE_REPLY:
return false;
// asynchronous I/O
case DO_IO_REQUEST:
case CANCEL_IO_REQUEST:
return true;
case DO_IO_REPLY:
case CANCEL_IO_REPLY:
return false;
// nodes
case IOCTL_REQUEST:
case SET_FLAGS_REQUEST:
@@ -674,6 +689,7 @@ UserlandFSUtil::is_kernel_request(uint32 type)
// vnodes
case GET_VNODE_REQUEST:
case PUT_VNODE_REQUEST:
case ACQUIRE_VNODE_REQUEST:
case NEW_VNODE_REQUEST:
case PUBLISH_VNODE_REQUEST:
case REMOVE_VNODE_REQUEST:
@@ -682,12 +698,35 @@ UserlandFSUtil::is_kernel_request(uint32 type)
return false;
case GET_VNODE_REPLY:
case PUT_VNODE_REPLY:
case ACQUIRE_VNODE_REPLY:
case NEW_VNODE_REPLY:
case PUBLISH_VNODE_REPLY:
case REMOVE_VNODE_REPLY:
case UNREMOVE_VNODE_REPLY:
case GET_VNODE_REMOVED_REPLY:
return true;
// file cache
case FILE_CACHE_CREATE_REQUEST:
case FILE_CACHE_DELETE_REQUEST:
case FILE_CACHE_SET_ENABLED_REQUEST:
case FILE_CACHE_SET_SIZE_REQUEST:
case FILE_CACHE_SYNC_REQUEST:
case FILE_CACHE_READ_REQUEST:
case FILE_CACHE_WRITE_REQUEST:
return false;
case FILE_CACHE_CREATE_REPLY:
case FILE_CACHE_DELETE_REPLY:
case FILE_CACHE_SET_ENABLED_REPLY:
case FILE_CACHE_SET_SIZE_REPLY:
case FILE_CACHE_SYNC_REPLY:
case FILE_CACHE_READ_REPLY:
case FILE_CACHE_WRITE_REPLY:
return true;
// I/O
case DO_ITERATIVE_FD_IO_REQUEST:
return false;
case DO_ITERATIVE_FD_IO_REPLY:
return true;
// general reply
case RECEIPT_ACK_REPLY:
@@ -737,6 +776,13 @@ UserlandFSUtil::is_userland_request(uint32 type)
case WRITE_VNODE_REPLY:
case FS_REMOVE_VNODE_REPLY:
return true;
// asynchronous I/O
case DO_IO_REQUEST:
case CANCEL_IO_REQUEST:
return false;
case DO_IO_REPLY:
case CANCEL_IO_REPLY:
return true;
// nodes
case IOCTL_REQUEST:
case SET_FLAGS_REQUEST:
@@ -880,6 +926,7 @@ UserlandFSUtil::is_userland_request(uint32 type)
// vnodes
case GET_VNODE_REQUEST:
case PUT_VNODE_REQUEST:
case ACQUIRE_VNODE_REQUEST:
case NEW_VNODE_REQUEST:
case PUBLISH_VNODE_REQUEST:
case REMOVE_VNODE_REQUEST:
@@ -888,12 +935,35 @@ UserlandFSUtil::is_userland_request(uint32 type)
return true;
case GET_VNODE_REPLY:
case PUT_VNODE_REPLY:
case ACQUIRE_VNODE_REPLY:
case NEW_VNODE_REPLY:
case PUBLISH_VNODE_REPLY:
case REMOVE_VNODE_REPLY:
case UNREMOVE_VNODE_REPLY:
case GET_VNODE_REMOVED_REPLY:
return false;
// file cache
case FILE_CACHE_CREATE_REQUEST:
case FILE_CACHE_DELETE_REQUEST:
case FILE_CACHE_SET_ENABLED_REQUEST:
case FILE_CACHE_SET_SIZE_REQUEST:
case FILE_CACHE_SYNC_REQUEST:
case FILE_CACHE_READ_REQUEST:
case FILE_CACHE_WRITE_REQUEST:
return true;
case FILE_CACHE_CREATE_REPLY:
case FILE_CACHE_DELETE_REPLY:
case FILE_CACHE_SET_ENABLED_REPLY:
case FILE_CACHE_SET_SIZE_REPLY:
case FILE_CACHE_SYNC_REPLY:
case FILE_CACHE_READ_REPLY:
case FILE_CACHE_WRITE_REPLY:
return false;
// I/O
case DO_ITERATIVE_FD_IO_REQUEST:
return false;
case DO_ITERATIVE_FD_IO_REPLY:
return true;
// general reply
case RECEIPT_ACK_REPLY:
@@ -5,12 +5,12 @@
#ifndef USERLAND_FS_IO_REQUEST_INFO_H
#define USERLAND_FS_IO_REQUEST_INFO_H
#include <util/OpenHashTable.h>
#include <SupportDefs.h>
namespace UserlandFS {
struct IORequestInfo : HashTableLink<IORequestInfo> {
struct IORequestInfo {
int32 id;
bool isWrite;
@@ -20,6 +20,13 @@ struct IORequestInfo : HashTableLink<IORequestInfo> {
isWrite(isWrite)
{
}
IORequestInfo(const IORequestInfo& other)
:
id(other.id),
isWrite(other.isWrite)
{
}
};
} // namespace UserlandFS
@@ -552,8 +552,8 @@ UserlandRequestHandler::_HandleRequest(DoIORequest* request)
if (result == B_OK) {
RequestThreadContext context(volume);
IORequestInfo requestInfo(request->ioRequest, request->isWrite);
result = volume->DoIO(request->node, request->fileCookie, &requestInfo);
IORequestInfo requestInfo(request->request, request->isWrite);
result = volume->DoIO(request->node, request->fileCookie, requestInfo);
}
// prepare the reply
@@ -582,7 +582,7 @@ UserlandRequestHandler::_HandleRequest(CancelIORequest* request)
if (result == B_OK) {
RequestThreadContext context(volume);
result = volume->CancelIO(request->node, request->fileCookie,
request->ioRequest);
request->request);
}
// prepare the reply
@@ -193,7 +193,7 @@ Volume::RemoveVNode(void* node, bool reenter)
status_t
Volume::DoIO(void* node, void* cookie, IORequestInfo* requestInfo)
Volume::DoIO(void* node, void* cookie, const IORequestInfo& requestInfo)
{
return B_BAD_VALUE;
}
@@ -55,7 +55,7 @@ public:
// asynchronous I/O
virtual status_t DoIO(void* node, void* cookie,
IORequestInfo* requestInfo);
const IORequestInfo& requestInfo);
virtual status_t CancelIO(void* node, void* cookie,
int32 ioRequestID);
@@ -8,20 +8,50 @@
#include <fs_interface.h>
#include <AutoLocker.h>
#include <block_cache.h>
#include <condition_variable.h>
#include "HaikuKernelIORequest.h"
#include "HaikuKernelVolume.h"
// IORequestHashDefinition
struct HaikuKernelFileSystem::IORequestHashDefinition {
typedef int32 KeyType;
typedef HaikuKernelIORequest ValueType;
size_t HashKey(int32 key) const
{ return key; }
size_t Hash(const HaikuKernelIORequest* value) const
{ return value->id; }
bool Compare(int32 key, const HaikuKernelIORequest* value) const
{ return value->id == key; }
HashTableLink<HaikuKernelIORequest>*
GetLink(HaikuKernelIORequest* value) const
{ return value; }
};
// IORequestTable
struct HaikuKernelFileSystem::IORequestTable
: public OpenHashTable<IORequestHashDefinition> {
};
// constructor
HaikuKernelFileSystem::HaikuKernelFileSystem(file_system_module_info* fsModule)
: FileSystem(),
fFSModule(fsModule)
:
FileSystem(),
fFSModule(fsModule),
fIORequests(NULL),
fLock("HaikuKernelFileSystem")
{
_InitCapabilities();
}
// destructor
HaikuKernelFileSystem::~HaikuKernelFileSystem()
{
@@ -29,19 +59,35 @@ HaikuKernelFileSystem::~HaikuKernelFileSystem()
if (fFSModule->info.std_ops)
fFSModule->info.std_ops(B_MODULE_UNINIT);
delete fIORequests;
// TODO: Call the cleanup methods (condition vars, block cache)!
}
// Init
status_t
HaikuKernelFileSystem::Init()
{
status_t error = fLock.InitCheck();
if (error != B_OK)
RETURN_ERROR(error);
// init condition variables
condition_variable_init();
// TODO: Call the cleanup methods, if something goes wrong!
// init block cache
status_t error = block_cache_init();
error = block_cache_init();
if (error != B_OK)
RETURN_ERROR(error);
// create I/O request map
fIORequests = new(std::nothrow) IORequestTable;
if (fIORequests == NULL)
RETURN_ERROR(B_NO_MEMORY);
error = fIORequests->Init();
if (error != B_OK)
RETURN_ERROR(error);
@@ -56,6 +102,7 @@ HaikuKernelFileSystem::Init()
return B_OK;
}
// CreateVolume
status_t
HaikuKernelFileSystem::CreateVolume(Volume** _volume, dev_t id)
@@ -79,6 +126,7 @@ HaikuKernelFileSystem::CreateVolume(Volume** _volume, dev_t id)
return B_OK;
}
// DeleteVolume
status_t
HaikuKernelFileSystem::DeleteVolume(Volume* volume)
@@ -89,6 +137,51 @@ HaikuKernelFileSystem::DeleteVolume(Volume* volume)
return B_OK;
}
// AddIORequest
status_t
HaikuKernelFileSystem::AddIORequest(HaikuKernelIORequest* request)
{
AutoLocker<Locker> _(fLock);
// check, if a request with that ID is already in the map
if (fIORequests->Lookup(request->id) != NULL)
RETURN_ERROR(B_BAD_VALUE);
fIORequests->Insert(request);
return B_OK;
}
// GetIORequest
HaikuKernelIORequest*
HaikuKernelFileSystem::GetIORequest(int32 requestID)
{
AutoLocker<Locker> _(fLock);
HaikuKernelIORequest* request = fIORequests->Lookup(requestID);
if (request != NULL)
request->refCount++;
return request;
}
// PutIORequest
void
HaikuKernelFileSystem::PutIORequest(HaikuKernelIORequest* request,
int32 refCount)
{
AutoLocker<Locker> locker(fLock);
if ((request->refCount -= refCount) <= 0) {
fIORequests->Remove(request);
locker.Unlock();
delete request;
}
}
// _InitCapabilities
void
HaikuKernelFileSystem::_InitCapabilities()
@@ -3,12 +3,16 @@
#ifndef USERLAND_FS_HAIKU_KERNEL_FILE_SYSTEM_H
#define USERLAND_FS_HAIKU_KERNEL_FILE_SYSTEM_H
#include "Locker.h"
#include "../FileSystem.h"
struct file_system_module_info;
namespace UserlandFS {
struct HaikuKernelIORequest;
class HaikuKernelFileSystem : public FileSystem {
public:
HaikuKernelFileSystem(
@@ -20,11 +24,22 @@ public:
virtual status_t CreateVolume(Volume** volume, dev_t id);
virtual status_t DeleteVolume(Volume* volume);
status_t AddIORequest(HaikuKernelIORequest* request);
HaikuKernelIORequest* GetIORequest(int32 requestID);
void PutIORequest(HaikuKernelIORequest* request,
int32 refCount = 1);
private:
class IORequestHashDefinition;
class IORequestTable;
private:
void _InitCapabilities();
private:
file_system_module_info* fFSModule;
IORequestTable* fIORequests;
Locker fLock;
};
} // namespace UserlandFS
@@ -15,6 +15,8 @@
#include "../IORequestInfo.h"
#include "../kernel_emu.h"
#include "HaikuKernelFileSystem.h"
#include "HaikuKernelIORequest.h"
#include "HaikuKernelNode.h"
@@ -24,26 +26,12 @@ class HaikuKernelVolume::NodeMap
};
// IORequestHashDefinition
struct HaikuKernelVolume::IORequestHashDefinition {
typedef int32 KeyType;
typedef IORequestInfo ValueType;
size_t HashKey(int32 key) const
{ return key; }
size_t Hash(const IORequestInfo* value) const
{ return value->id; }
bool Compare(int32 key, const IORequestInfo* value) const
{ return value->id == key; }
HashTableLink<IORequestInfo>* GetLink(IORequestInfo* value) const
{ return value; }
};
// IORequestTable
struct HaikuKernelVolume::IORequestTable
: public OpenHashTable<IORequestHashDefinition> {
};
// _FileSystem
inline HaikuKernelFileSystem*
HaikuKernelVolume::_FileSystem() const
{
return static_cast<HaikuKernelFileSystem*>(fFileSystem);
}
// constructor
@@ -52,8 +40,7 @@ HaikuKernelVolume::HaikuKernelVolume(FileSystem* fileSystem, dev_t id,
:
Volume(fileSystem, id),
fFSModule(fsModule),
fNodes(NULL),
fIORequests(NULL)
fNodes(NULL)
{
fVolume.id = id;
fVolume.partition = -1;
@@ -71,7 +58,6 @@ HaikuKernelVolume::HaikuKernelVolume(FileSystem* fileSystem, dev_t id,
HaikuKernelVolume::~HaikuKernelVolume()
{
delete fNodes;
delete fIORequests;
}
@@ -82,14 +68,7 @@ HaikuKernelVolume::Init()
fNodes = new(std::nothrow) NodeMap;
if (fNodes == NULL)
return B_NO_MEMORY;
status_t error = fNodes->InitCheck();
if (error != B_OK)
return error;
fIORequests = new(std::nothrow) IORequestTable;
if (fIORequests == NULL)
return B_NO_MEMORY;
return fIORequests->Init();
return fNodes->InitCheck();
}
@@ -184,14 +163,6 @@ HaikuKernelVolume::NodeWithID(ino_t vnodeID) const
}
IORequestInfo*
HaikuKernelVolume::IORequestInfoWithID(int32 id) const
{
AutoLocker<NodeMap> locker(fNodes);
return fIORequests->Lookup(id);
}
// #pragma mark -
// #pragma mark ----- FS -----
@@ -374,30 +345,39 @@ HaikuKernelVolume::RemoveVNode(void* _node, bool reenter)
status_t
HaikuKernelVolume::DoIO(void* _node, void* cookie, IORequestInfo* requestInfo)
HaikuKernelVolume::DoIO(void* _node, void* cookie,
const IORequestInfo& requestInfo)
{
HaikuKernelNode* node = (HaikuKernelNode*)_node;
if (!node->ops->io)
return B_BAD_VALUE;
// add the info to the table
AutoLocker<NodeMap> locker(fNodes);
if (fIORequests->Lookup(requestInfo->id))
RETURN_ERROR(B_BAD_VALUE);
// create a request object
HaikuKernelIORequest* request
= new(std::nothrow) HaikuKernelIORequest(requestInfo);
if (request == NULL)
RETURN_ERROR(B_NO_MEMORY);
fIORequests->Insert(requestInfo);
locker.Unlock();
status_t error = _FileSystem()->AddIORequest(request);
if (error != B_OK) {
delete request;
RETURN_ERROR(error);
}
// call the hook
status_t error = node->ops->io(&fVolume, node, cookie,
(io_request*)(addr_t)requestInfo->id);
error = node->ops->io(&fVolume, node, cookie, (io_request*)request);
// remove the info from the table
locker.Lock();
fIORequests->Remove(requestInfo);
// directly put our reference to the request, if the call failed
if (error != B_OK) {
_FileSystem()->PutIORequest(request);
RETURN_ERROR(error);
}
return error;
// TODO: ATM we don't release our reference when the request is finished
// normally!
return B_OK;
}
@@ -409,8 +389,20 @@ HaikuKernelVolume::CancelIO(void* _node, void* cookie, int32 ioRequestID)
if (!node->ops->cancel_io)
return B_BAD_VALUE;
return node->ops->cancel_io(&fVolume, node, cookie,
(io_request*)(addr_t)ioRequestID);
// get the request
HaikuKernelIORequest* request = _FileSystem()->GetIORequest(ioRequestID);
if (request == NULL)
RETURN_ERROR(B_BAD_VALUE);
// call the hook
status_t error = node->ops->cancel_io(&fVolume, node, cookie,
(io_request*)request);
// put the request -- once for the reference we got above, once for the
// reference we've got in DoIO()
_FileSystem()->PutIORequest(request, 2);
return error;
}
@@ -9,6 +9,7 @@
namespace UserlandFS {
class HaikuKernelFileSystem;
class HaikuKernelNode;
@@ -34,7 +35,6 @@ public:
void UndoPublishVNode(HaikuKernelNode* node);
HaikuKernelNode* NodeWithID(ino_t vnodeID) const;
IORequestInfo* IORequestInfoWithID(int32 id) const;
// FS
virtual status_t Mount(const char* device, uint32 flags,
@@ -62,7 +62,7 @@ public:
// asynchronous I/O
virtual status_t DoIO(void* node, void* cookie,
IORequestInfo* requestInfo);
const IORequestInfo& requestInfo);
virtual status_t CancelIO(void* node, void* cookie,
int32 ioRequestID);
@@ -185,17 +185,15 @@ private:
};
class NodeMap;
class IORequestHashDefinition;
class IORequestTable;
private:
void _InitCapabilities();
inline HaikuKernelFileSystem* _FileSystem() const;
private:
file_system_module_info* fFSModule;
FSVolume fVolume;
NodeMap* fNodes;
IORequestTable* fIORequests;
};
@@ -21,6 +21,7 @@
#include "../kernel_emu.h"
#include "../RequestThread.h"
#include "HaikuKernelIORequest.h"
#include "HaikuKernelNode.h"
#include "HaikuKernelVolume.h"
#include "vfs.h"
@@ -270,11 +271,39 @@ do_fd_io(int fd, io_request *request)
// do_iterative_fd_io
status_t
do_iterative_fd_io(int fd, io_request *request, iterative_io_get_vecs getVecs,
iterative_io_finished finished, void *cookie)
do_iterative_fd_io(int fd, io_request *_request, iterative_io_get_vecs getVecs,
iterative_io_finished finished, void *_cookie)
{
// TODO: Implement!
return B_UNSUPPORTED;
#if 0
// get some vecs already
file_io_vec fileVecs[8];
uint32 fileVecCount = 8;
status_t error = getVecs(_cookie, _request, offset, vecLength, fileVecs,
&fileVecCount);
// TODO: We don't have the offset here. We should pass it along in the
// DoIORequest.
#endif
HaikuKernelIORequest* request = (HaikuKernelIORequest*)_request;
// create a cookie
HaikuKernelIterativeFDIOCookie* cookie
= new(std::nothrow) HaikuKernelIterativeFDIOCookie(fd, request, getVecs,
finished, _cookie);
if (cookie == NULL) {
finished(_cookie, _request, B_NO_MEMORY, false, 0);
return B_NO_MEMORY;
}
// send the request
status_t error = UserlandFS::KernelEmu::do_iterative_fd_io(fd, request->id,
cookie, NULL, 0);
if (error != B_OK) {
delete cookie;
return error;
}
return B_OK;
}
@@ -284,19 +313,7 @@ do_iterative_fd_io(int fd, io_request *request, iterative_io_get_vecs getVecs,
bool
io_request_is_write(const io_request* request)
{
// get the volume
RequestThread* thread = RequestThread::GetCurrentThread();
if (thread == NULL || thread->GetContext() == NULL)
return false;
HaikuKernelVolume* volume = dynamic_cast<HaikuKernelVolume*>(
thread->GetContext()->GetVolume());
if (volume == NULL)
return false;
// get the request info
IORequestInfo* info = volume->IORequestInfoWithID((int32)(addr_t)request);
return info != NULL && info->isWrite;
return ((HaikuKernelIORequest*)request)->isWrite;
}
@@ -837,6 +837,53 @@ UserlandFS::KernelEmu::file_cache_write(dev_t mountID, ino_t vnodeID,
}
// #pragma mark - I/O
status_t
UserlandFS::KernelEmu::do_iterative_fd_io(int fd, int32 requestID, void* cookie,
const file_io_vec* vecs, uint32 vecCount)
{
// get the request port and the file system
RequestPort* port;
FileSystem* fileSystem;
status_t error = get_port_and_fs(&port, &fileSystem);
if (error != B_OK)
return error;
// prepare the request
RequestAllocator allocator(port->GetPort());
DoIterativeFDIORequest* request;
error = AllocateRequest(allocator, &request);
if (error != B_OK)
return error;
request->fd = fd;
request->request = requestID;
request->cookie = cookie;
request->vecCount = vecCount;
if (vecCount > 0) {
error = allocator.AllocateData(request->vecs, vecs,
vecCount * sizeof(file_io_vec), sizeof(off_t), false);
if (error != B_OK)
return error;
}
// send the request
UserlandRequestHandler handler(fileSystem, DO_ITERATIVE_FD_IO_REPLY);
DoIterativeFDIOReply* reply;
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
if (error != B_OK)
return error;
// TODO: Up to this point we should call the finished hook or error!
RequestReleaser requestReleaser(port, reply);
// process the reply
return reply->error;
}
// #pragma mark -
@@ -5,6 +5,7 @@
#include <OS.h>
struct selectsync;
struct file_io_vec;
namespace UserlandFS {
namespace KernelEmu {
@@ -31,18 +32,20 @@ status_t remove_vnode(dev_t nsid, ino_t vnid);
status_t unremove_vnode(dev_t nsid, ino_t vnid);
status_t get_vnode_removed(dev_t nsid, ino_t vnid, bool* removed);
extern status_t file_cache_create(dev_t mountID, ino_t vnodeID, off_t size);
extern status_t file_cache_delete(dev_t mountID, ino_t vnodeID);
extern status_t file_cache_set_enabled(dev_t mountID, ino_t vnodeID,
bool enabled);
extern status_t file_cache_set_size(dev_t mountID, ino_t vnodeID, off_t size);
extern status_t file_cache_sync(dev_t mountID, ino_t vnodeID);
status_t file_cache_create(dev_t mountID, ino_t vnodeID, off_t size);
status_t file_cache_delete(dev_t mountID, ino_t vnodeID);
status_t file_cache_set_enabled(dev_t mountID, ino_t vnodeID, bool enabled);
status_t file_cache_set_size(dev_t mountID, ino_t vnodeID, off_t size);
status_t file_cache_sync(dev_t mountID, ino_t vnodeID);
extern status_t file_cache_read(dev_t mountID, ino_t vnodeID, void *cookie,
status_t file_cache_read(dev_t mountID, ino_t vnodeID, void *cookie,
off_t offset, void *bufferBase, size_t *_size);
extern status_t file_cache_write(dev_t mountID, ino_t vnodeID, void *cookie,
status_t file_cache_write(dev_t mountID, ino_t vnodeID, void *cookie,
off_t offset, const void *buffer, size_t *_size);
status_t do_iterative_fd_io(int fd, int32 requestID, void* cookie,
const file_io_vec* vecs, uint32 vecCount);
void kernel_debugger(const char *message);
void vpanic(const char *format, va_list args);
void panic(const char *format, ...) __attribute__ ((format (__printf__, 1, 2)));