* Adjusted BeOSKernelFileSystem and BeOSKernelVolume to Haiku's FS interface.

* Moved stuff need for the BeOS interface only into the beos_* namespace.
* Shuffled a few things around to reduce the block cache implementation
  dependencies. compat.h and sysdep.c are gone accordingly.
* The whole UserlandFSServer builds now and could (at least theorectically)
  drive a FS add-on implementing the old interface. The required emulation of
  the BeOS kernel is not yet provided, though.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20247 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2007-02-28 04:54:13 +00:00
parent 8474904ee0
commit ca6faf4958
20 changed files with 1153 additions and 1040 deletions

View File

@ -1,12 +1,13 @@
// BeOSKernelFileSystem.cpp
#include "BeOSKernelFileSystem.h"
#include <new>
#include "BeOSKernelFileSystem.h"
#include "BeOSKernelVolume.h"
// constructor
BeOSKernelFileSystem::BeOSKernelFileSystem(vnode_ops* fsOps)
BeOSKernelFileSystem::BeOSKernelFileSystem(beos_vnode_ops* fsOps)
: FileSystem(),
fFSOps(fsOps)
{

View File

@ -5,18 +5,20 @@
#include "FileSystem.h"
struct beos_vnode_ops;
namespace UserlandFS {
class BeOSKernelFileSystem : public FileSystem {
public:
BeOSKernelFileSystem(vnode_ops* fsOps);
BeOSKernelFileSystem(beos_vnode_ops* fsOps);
virtual ~BeOSKernelFileSystem();
virtual status_t CreateVolume(Volume** volume, mount_id id);
virtual status_t DeleteVolume(Volume* volume);
private:
vnode_ops* fFSOps;
beos_vnode_ops* fFSOps;
};
} // namespace UserlandFS

View File

@ -2,9 +2,12 @@
#include "BeOSKernelVolume.h"
#include "beos_fs_interface.h"
#include "kernel_emu.h"
// constructor
BeOSKernelVolume::BeOSKernelVolume(FileSystem* fileSystem, nspace_id id,
vnode_ops* fsOps)
BeOSKernelVolume::BeOSKernelVolume(FileSystem* fileSystem, mount_id id,
beos_vnode_ops* fsOps)
: Volume(fileSystem, id),
fFSOps(fsOps),
fVolumeCookie(NULL)
@ -21,11 +24,13 @@ BeOSKernelVolume::~BeOSKernelVolume()
// Mount
status_t
BeOSKernelVolume::Mount(const char* device, ulong flags, const char* parameters,
int32 len, vnode_id* rootID)
BeOSKernelVolume::Mount(const char* device, uint32 flags,
const char* parameters, vnode_id* rootID)
{
if (!fFSOps->mount)
return B_BAD_VALUE;
size_t len = (parameters ? strlen(parameters) : 0);
return fFSOps->mount(GetID(), device, flags, (void*)parameters, len,
&fVolumeCookie, rootID);
}
@ -48,100 +53,253 @@ BeOSKernelVolume::Sync()
return fFSOps->sync(fVolumeCookie);
}
// ReadFSStat
// ReadFSInfo
status_t
BeOSKernelVolume::ReadFSStat(fs_info* info)
BeOSKernelVolume::ReadFSInfo(fs_info* info)
{
if (!fFSOps->rfsstat)
return B_BAD_VALUE;
return fFSOps->rfsstat(fVolumeCookie, info);
// Haiku's fs_info equals BeOS's version
return fFSOps->rfsstat(fVolumeCookie, (beos_fs_info*)info);
}
// WriteFSStat
// WriteFSInfo
status_t
BeOSKernelVolume::WriteFSStat(struct fs_info *info, long mask)
BeOSKernelVolume::WriteFSInfo(const struct fs_info* info, uint32 mask)
{
if (!fFSOps->wfsstat)
return B_BAD_VALUE;
return fFSOps->wfsstat(fVolumeCookie, info, mask);
// Haiku's fs_info equals BeOS's version
return fFSOps->wfsstat(fVolumeCookie, (beos_fs_info*)info, (long)mask);
}
// #pragma mark -
// #pragma mark ----- vnodes -----
// #pragma mark - vnodes
// Lookup
status_t
BeOSKernelVolume::Lookup(fs_vnode dir, const char* entryName, vnode_id* vnid,
int* type)
{
if (!fFSOps->walk)
return B_BAD_VALUE;
status_t error = fFSOps->walk(fVolumeCookie, dir, entryName, NULL, vnid);
if (error != B_OK)
return error;
// We need to get the node stat to return the node's type.
// TODO: This is quite expensive. get_vnode() and put_vnode() cause trips to
// the kernel. If it is implemented properly walk() has already called
// get_vnode() for our node. Introducing a mechanism that would allow us to
// temporarily track the {get,put,new}_vnode() calls of our thread would save
// those two kernel trips.
// get the vnode
fs_vnode node;
error = UserlandFS::KernelEmu::get_vnode(GetID(), *vnid, &node);
if (error != B_OK) {
// walk() has called get_vnode() for the caller, so we need to put the
// node
UserlandFS::KernelEmu::put_vnode(GetID(), *vnid);
return error;
}
// get the node's stat
struct stat st;
error = ReadStat(node, &st);
if (error == B_OK)
*type = (st.st_mode & S_IFMT);
// put the node for our get_vnode()
UserlandFS::KernelEmu::put_vnode(GetID(), *vnid);
// on error put the node for walk()'s get_vnode()
if (error != B_OK)
UserlandFS::KernelEmu::put_vnode(GetID(), *vnid);
return error;
}
// ReadVNode
status_t
BeOSKernelVolume::ReadVNode(vnode_id vnid, char reenter, void** node)
BeOSKernelVolume::ReadVNode(vnode_id vnid, bool reenter, fs_vnode* node)
{
if (!fFSOps->read_vnode)
return B_BAD_VALUE;
return fFSOps->read_vnode(fVolumeCookie, vnid, reenter, node);
return fFSOps->read_vnode(fVolumeCookie, vnid, (char)reenter, node);
}
// WriteVNode
status_t
BeOSKernelVolume::WriteVNode(void* node, char reenter)
BeOSKernelVolume::WriteVNode(fs_vnode node, bool reenter)
{
if (!fFSOps->write_vnode)
return B_BAD_VALUE;
return fFSOps->write_vnode(fVolumeCookie, node, reenter);
return fFSOps->write_vnode(fVolumeCookie, node, (char)reenter);
}
// RemoveVNode
status_t
BeOSKernelVolume::RemoveVNode(void* node, char reenter)
BeOSKernelVolume::RemoveVNode(fs_vnode node, bool reenter)
{
if (!fFSOps->remove_vnode)
return B_BAD_VALUE;
return fFSOps->remove_vnode(fVolumeCookie, node, reenter);
return fFSOps->remove_vnode(fVolumeCookie, node, (char)reenter);
}
// #pragma mark -
// #pragma mark ----- nodes -----
// #pragma mark - nodes
// IOCtl
status_t
BeOSKernelVolume::IOCtl(fs_vnode node, fs_cookie cookie, uint32 command,
void* buffer, size_t size)
{
if (!fFSOps->ioctl)
return B_BAD_VALUE;
return fFSOps->ioctl(fVolumeCookie, node, cookie, (int)command, buffer,
size);
}
// SetFlags
status_t
BeOSKernelVolume::SetFlags(fs_vnode node, fs_cookie cookie, int flags)
{
if (!fFSOps->setflags)
return B_BAD_VALUE;
return fFSOps->setflags(fVolumeCookie, node, cookie, flags);
}
// Select
status_t
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);
return B_OK;
}
return fFSOps->select(fVolumeCookie, node, cookie, event, ref, sync);
}
// Deselect
status_t
BeOSKernelVolume::Deselect(fs_vnode node, fs_cookie cookie, uint8 event,
selectsync* sync)
{
if (!fFSOps->select || !fFSOps->deselect)
return B_OK;
return fFSOps->deselect(fVolumeCookie, node, cookie, event, sync);
}
// FSync
status_t
BeOSKernelVolume::FSync(void* node)
BeOSKernelVolume::FSync(fs_vnode node)
{
if (!fFSOps->fsync)
return B_BAD_VALUE;
return fFSOps->fsync(fVolumeCookie, node);
}
// ReadStat
// ReadSymlink
status_t
BeOSKernelVolume::ReadStat(void* node, struct stat* st)
BeOSKernelVolume::ReadSymlink(fs_vnode node, char* buffer, size_t bufferSize,
size_t* bytesRead)
{
if (!fFSOps->rstat)
if (!fFSOps->readlink)
return B_BAD_VALUE;
return fFSOps->rstat(fVolumeCookie, node, st);
*bytesRead = bufferSize;
return fFSOps->readlink(fVolumeCookie, node, buffer, bytesRead);
}
// WriteStat
// CreateSymlink
status_t
BeOSKernelVolume::WriteStat(void* node, struct stat* st, long mask)
BeOSKernelVolume::CreateSymlink(fs_vnode dir, const char* name,
const char* target, int mode)
{
if (!fFSOps->wstat)
if (!fFSOps->symlink)
return B_BAD_VALUE;
return fFSOps->wstat(fVolumeCookie, node, st, mask);
// TODO: Don't ignore mode?
return fFSOps->symlink(fVolumeCookie, dir, name, target);
}
// Link
status_t
BeOSKernelVolume::Link(fs_vnode dir, const char* name, fs_vnode node)
{
if (!fFSOps->link)
return B_BAD_VALUE;
return fFSOps->link(fVolumeCookie, dir, name, node);
}
// Unlink
status_t
BeOSKernelVolume::Unlink(fs_vnode dir, const char* name)
{
if (!fFSOps->unlink)
return B_BAD_VALUE;
return fFSOps->unlink(fVolumeCookie, dir, name);
}
// Rename
status_t
BeOSKernelVolume::Rename(fs_vnode oldDir, const char* oldName, fs_vnode newDir,
const char* newName)
{
if (!fFSOps->rename)
return B_BAD_VALUE;
return fFSOps->rename(fVolumeCookie, oldDir, oldName, newDir, newName);
}
// Access
status_t
BeOSKernelVolume::Access(void* node, int mode)
BeOSKernelVolume::Access(fs_vnode node, int mode)
{
if (!fFSOps->access)
return B_BAD_VALUE;
return fFSOps->access(fVolumeCookie, node, mode);
}
// #pragma mark -
// #pragma mark ----- files -----
// ReadStat
status_t
BeOSKernelVolume::ReadStat(fs_vnode node, struct stat* st)
{
if (!fFSOps->rstat)
return B_BAD_VALUE;
// Haiku's struct stat has an additional st_type field (for an attribute
// type), but that doesn't matter here
return fFSOps->rstat(fVolumeCookie, node, (struct beos_stat*)st);
}
// WriteStat
status_t
BeOSKernelVolume::WriteStat(fs_vnode node, const struct stat *st, uint32 mask)
{
if (!fFSOps->wstat)
return B_BAD_VALUE;
// Haiku's struct stat has an additional st_type field (for an attribute
// type), but that doesn't matter here
return fFSOps->wstat(fVolumeCookie, node, (struct beos_stat*)st,
(long)mask);
}
// #pragma mark - files
// Create
status_t
BeOSKernelVolume::Create(void* dir, const char* name, int openMode, int mode,
vnode_id* vnid, void** cookie)
BeOSKernelVolume::Create(fs_vnode dir, const char* name, int openMode, int mode,
fs_cookie* cookie, vnode_id* vnid)
{
if (!fFSOps->create)
return B_BAD_VALUE;
@ -151,7 +309,7 @@ BeOSKernelVolume::Create(void* dir, const char* name, int openMode, int mode,
// Open
status_t
BeOSKernelVolume::Open(void* node, int openMode, void** cookie)
BeOSKernelVolume::Open(fs_vnode node, int openMode, fs_cookie* cookie)
{
if (!fFSOps->open)
return B_BAD_VALUE;
@ -160,7 +318,7 @@ BeOSKernelVolume::Open(void* node, int openMode, void** cookie)
// Close
status_t
BeOSKernelVolume::Close(void* node, void* cookie)
BeOSKernelVolume::Close(fs_vnode node, fs_cookie cookie)
{
if (!fFSOps->close)
return B_OK;
@ -169,7 +327,7 @@ BeOSKernelVolume::Close(void* node, void* cookie)
// FreeCookie
status_t
BeOSKernelVolume::FreeCookie(void* node, void* cookie)
BeOSKernelVolume::FreeCookie(fs_vnode node, fs_cookie cookie)
{
if (!fFSOps->free_cookie)
return B_OK;
@ -178,7 +336,7 @@ BeOSKernelVolume::FreeCookie(void* node, void* cookie)
// Read
status_t
BeOSKernelVolume::Read(void* node, void* cookie, off_t pos, void* buffer,
BeOSKernelVolume::Read(fs_vnode node, fs_cookie cookie, off_t pos, void* buffer,
size_t bufferSize, size_t* bytesRead)
{
if (!fFSOps->read)
@ -189,8 +347,8 @@ BeOSKernelVolume::Read(void* node, void* cookie, off_t pos, void* buffer,
// Write
status_t
BeOSKernelVolume::Write(void* node, void* cookie, off_t pos, const void* buffer,
size_t bufferSize, size_t* bytesWritten)
BeOSKernelVolume::Write(fs_vnode node, fs_cookie cookie, off_t pos,
const void* buffer, size_t bufferSize, size_t* bytesWritten)
{
if (!fFSOps->write)
return B_BAD_VALUE;
@ -199,113 +357,38 @@ BeOSKernelVolume::Write(void* node, void* cookie, off_t pos, const void* buffer,
bytesWritten);
}
// IOCtl
// #pragma mark - directories
// CreateDir
status_t
BeOSKernelVolume::IOCtl(void* node, void* cookie, int command, void *buffer,
size_t size)
BeOSKernelVolume::CreateDir(fs_vnode dir, const char* name, int mode,
vnode_id *newDir)
{
if (!fFSOps->ioctl)
if (!fFSOps->mkdir || !fFSOps->walk) // we need walk() too
return B_BAD_VALUE;
return fFSOps->ioctl(fVolumeCookie, node, cookie, command, buffer, size);
status_t error = fFSOps->mkdir(fVolumeCookie, dir, name, mode);
if (error != B_OK)
return error;
// we need to get the node ID by invoking walk()
vnode_id id;
error = fFSOps->walk(fVolumeCookie, dir, name, NULL, &id);
if (error != B_OK)
return error;
// put the node for walk()'s get_vnode()
UserlandFS::KernelEmu::put_vnode(GetID(), id);
*newDir = id;
return B_OK;
}
// SetFlags
// RemoveDir
status_t
BeOSKernelVolume::SetFlags(void* node, void* cookie, int flags)
{
if (!fFSOps->setflags)
return B_BAD_VALUE;
return fFSOps->setflags(fVolumeCookie, node, cookie, flags);
}
// Select
status_t
BeOSKernelVolume::Select(void* node, void* cookie, uint8 event, uint32 ref,
selectsync* sync)
{
if (!fFSOps->select) {
notify_select_event(sync, ref);
return B_OK;
}
return fFSOps->select(fVolumeCookie, node, cookie, event, ref, sync);
}
// Deselect
status_t
BeOSKernelVolume::Deselect(void* node, void* cookie, uint8 event,
selectsync* sync)
{
if (!fFSOps->select || !fFSOps->deselect)
return B_OK;
return fFSOps->deselect(fVolumeCookie, node, cookie, event, sync);
}
// #pragma mark -
// #pragma mark ----- hard links / symlinks -----
// Link
status_t
BeOSKernelVolume::Link(void* dir, const char* name, void* node)
{
if (!fFSOps->link)
return B_BAD_VALUE;
return fFSOps->link(fVolumeCookie, dir, name, node);
}
// Unlink
status_t
BeOSKernelVolume::Unlink(void* dir, const char* name)
{
if (!fFSOps->unlink)
return B_BAD_VALUE;
return fFSOps->unlink(fVolumeCookie, dir, name);
}
// Symlink
status_t
BeOSKernelVolume::Symlink(void* dir, const char* name, const char* target)
{
if (!fFSOps->symlink)
return B_BAD_VALUE;
return fFSOps->symlink(fVolumeCookie, dir, name, target);
}
// ReadLink
status_t
BeOSKernelVolume::ReadLink(void* node, char* buffer, size_t bufferSize,
size_t* bytesRead)
{
if (!fFSOps->readlink)
return B_BAD_VALUE;
*bytesRead = bufferSize;
return fFSOps->readlink(fVolumeCookie, node, buffer, bytesRead);
}
// Rename
status_t
BeOSKernelVolume::Rename(void* oldDir, const char* oldName, void* newDir,
const char* newName)
{
if (!fFSOps->rename)
return B_BAD_VALUE;
return fFSOps->rename(fVolumeCookie, oldDir, oldName, newDir, newName);
}
// #pragma mark -
// #pragma mark ----- directories -----
// MkDir
status_t
BeOSKernelVolume::MkDir(void* dir, const char* name, int mode)
{
if (!fFSOps->mkdir)
return B_BAD_VALUE;
return fFSOps->mkdir(fVolumeCookie, dir, name, mode);
}
// RmDir
status_t
BeOSKernelVolume::RmDir(void* dir, const char* name)
BeOSKernelVolume::RemoveDir(fs_vnode dir, const char* name)
{
if (!fFSOps->rmdir)
return B_BAD_VALUE;
@ -314,7 +397,7 @@ BeOSKernelVolume::RmDir(void* dir, const char* name)
// OpenDir
status_t
BeOSKernelVolume::OpenDir(void* node, void** cookie)
BeOSKernelVolume::OpenDir(fs_vnode node, fs_cookie* cookie)
{
if (!fFSOps->opendir)
return B_BAD_VALUE;
@ -323,7 +406,7 @@ BeOSKernelVolume::OpenDir(void* node, void** cookie)
// CloseDir
status_t
BeOSKernelVolume::CloseDir(void* node, void* cookie)
BeOSKernelVolume::CloseDir(fs_vnode node, fs_vnode cookie)
{
if (!fFSOps->closedir)
return B_OK;
@ -332,7 +415,7 @@ BeOSKernelVolume::CloseDir(void* node, void* cookie)
// FreeDirCookie
status_t
BeOSKernelVolume::FreeDirCookie(void* node, void* cookie)
BeOSKernelVolume::FreeDirCookie(fs_vnode node, fs_vnode cookie)
{
if (!fFSOps->free_dircookie)
return B_OK;
@ -341,41 +424,35 @@ BeOSKernelVolume::FreeDirCookie(void* node, void* cookie)
// ReadDir
status_t
BeOSKernelVolume::ReadDir(void* node, void* cookie, void* buffer,
size_t bufferSize, int32 count, int32* countRead)
BeOSKernelVolume::ReadDir(fs_vnode node, fs_vnode cookie, void* buffer,
size_t bufferSize, uint32 count, uint32* countRead)
{
if (!fFSOps->readdir)
return B_BAD_VALUE;
*countRead = count;
return fFSOps->readdir(fVolumeCookie, node, cookie, countRead,
(dirent*)buffer, bufferSize);
// Haiku's struct dirent equals BeOS's version
return fFSOps->readdir(fVolumeCookie, node, cookie, (long*)countRead,
(beos_dirent*)buffer, bufferSize);
}
// RewindDir
status_t
BeOSKernelVolume::RewindDir(void* node, void* cookie)
BeOSKernelVolume::RewindDir(fs_vnode node, fs_vnode cookie)
{
if (!fFSOps->rewinddir)
return B_BAD_VALUE;
return fFSOps->rewinddir(fVolumeCookie, node, cookie);
}
// Walk
status_t
BeOSKernelVolume::Walk(void* dir, const char* entryName, char** resolvedPath,
vnode_id* vnid)
{
if (!fFSOps->walk)
return B_BAD_VALUE;
return fFSOps->walk(fVolumeCookie, dir, entryName, resolvedPath, vnid);
}
// #pragma mark -
// #pragma mark ----- attributes -----
// #pragma mark - attribute directories
// OpenAttrDir
status_t
BeOSKernelVolume::OpenAttrDir(void* node, void** cookie)
BeOSKernelVolume::OpenAttrDir(fs_vnode node, fs_cookie *cookie)
{
if (!fFSOps->open_attrdir)
return B_BAD_VALUE;
@ -384,7 +461,7 @@ BeOSKernelVolume::OpenAttrDir(void* node, void** cookie)
// CloseAttrDir
status_t
BeOSKernelVolume::CloseAttrDir(void* node, void* cookie)
BeOSKernelVolume::CloseAttrDir(fs_vnode node, fs_cookie cookie)
{
if (!fFSOps->close_attrdir)
return B_OK;
@ -393,7 +470,7 @@ BeOSKernelVolume::CloseAttrDir(void* node, void* cookie)
// FreeAttrDirCookie
status_t
BeOSKernelVolume::FreeAttrDirCookie(void* node, void* cookie)
BeOSKernelVolume::FreeAttrDirCookie(fs_vnode node, fs_cookie cookie)
{
if (!fFSOps->free_attrdircookie)
return B_OK;
@ -402,83 +479,100 @@ BeOSKernelVolume::FreeAttrDirCookie(void* node, void* cookie)
// ReadAttrDir
status_t
BeOSKernelVolume::ReadAttrDir(void* node, void* cookie, void* buffer,
size_t bufferSize, int32 count, int32* countRead)
BeOSKernelVolume::ReadAttrDir(fs_vnode node, fs_cookie cookie, void* buffer,
size_t bufferSize, uint32 count, uint32* countRead)
{
if (!fFSOps->read_attrdir)
return B_BAD_VALUE;
*countRead = count;
return fFSOps->read_attrdir(fVolumeCookie, node, cookie, countRead,
(struct dirent*)buffer, bufferSize);
// Haiku's struct dirent equals BeOS's version
return fFSOps->read_attrdir(fVolumeCookie, node, cookie, (long*)countRead,
(struct beos_dirent*)buffer, bufferSize);
}
// RewindAttrDir
status_t
BeOSKernelVolume::RewindAttrDir(void* node, void* cookie)
BeOSKernelVolume::RewindAttrDir(fs_vnode node, fs_cookie cookie)
{
if (!fFSOps->rewind_attrdir)
return B_BAD_VALUE;
return fFSOps->rewind_attrdir(fVolumeCookie, node, cookie);
}
// #pragma mark - attributes
// ReadAttr
status_t
BeOSKernelVolume::ReadAttr(void* node, const char* name, int type, off_t pos,
BeOSKernelVolume::ReadAttr(fs_vnode node, fs_cookie cookie, off_t pos,
void* buffer, size_t bufferSize, size_t* bytesRead)
{
if (!fFSOps->read_attr)
return B_BAD_VALUE;
*bytesRead = bufferSize;
return fFSOps->read_attr(fVolumeCookie, node, name, type, buffer, bytesRead,
pos);
// TODO: Implement!
return B_BAD_VALUE;
// if (!fFSOps->read_attr)
// return B_BAD_VALUE;
// *bytesRead = bufferSize;
// return fFSOps->read_attr(fVolumeCookie, node, name, type, buffer, bytesRead,
// pos);
}
// WriteAttr
status_t
BeOSKernelVolume::WriteAttr(void* node, const char* name, int type, off_t pos,
BeOSKernelVolume::WriteAttr(fs_vnode node, fs_cookie cookie, off_t pos,
const void* buffer, size_t bufferSize, size_t* bytesWritten)
{
if (!fFSOps->write_attr)
// TODO: Implement!
return B_BAD_VALUE;
// if (!fFSOps->write_attr)
// return B_BAD_VALUE;
// *bytesWritten = bufferSize;
// return fFSOps->write_attr(fVolumeCookie, node, name, type, buffer,
// bytesWritten, pos);
}
// ReadAttrStat
status_t
BeOSKernelVolume::ReadAttrStat(fs_vnode node, fs_cookie cookie, struct stat *st)
{
// TODO: Implement!
return B_BAD_VALUE;
// if (!fFSOps->stat_attr)
// return B_BAD_VALUE;
// return fFSOps->stat_attr(fVolumeCookie, node, name, attrInfo);
}
// RenameAttr
status_t
BeOSKernelVolume::RenameAttr(fs_vnode oldNode, const char* oldName,
fs_vnode newNode, const char* newName)
{
if (!fFSOps->rename_attr)
return B_BAD_VALUE;
*bytesWritten = bufferSize;
return fFSOps->write_attr(fVolumeCookie, node, name, type, buffer,
bytesWritten, pos);
if (oldNode != newNode)
return B_BAD_VALUE;
return fFSOps->rename_attr(fVolumeCookie, oldNode, oldName, newName);
}
// RemoveAttr
status_t
BeOSKernelVolume::RemoveAttr(void* node, const char* name)
BeOSKernelVolume::RemoveAttr(fs_vnode node, const char* name)
{
if (!fFSOps->remove_attr)
return B_BAD_VALUE;
return fFSOps->remove_attr(fVolumeCookie, node, name);
}
// RenameAttr
status_t
BeOSKernelVolume::RenameAttr(void* node, const char* oldName, const char* newName)
{
if (!fFSOps->rename_attr)
return B_BAD_VALUE;
return fFSOps->rename_attr(fVolumeCookie, node, oldName, newName);
}
// StatAttr
status_t
BeOSKernelVolume::StatAttr(void* node, const char* name,
struct attr_info* attrInfo)
{
if (!fFSOps->stat_attr)
return B_BAD_VALUE;
return fFSOps->stat_attr(fVolumeCookie, node, name, attrInfo);
}
// #pragma mark - indices
// #pragma mark -
// #pragma mark ----- indices -----
// OpenIndexDir
status_t
BeOSKernelVolume::OpenIndexDir(void** cookie)
BeOSKernelVolume::OpenIndexDir(fs_cookie *cookie)
{
if (!fFSOps->open_indexdir)
return B_BAD_VALUE;
@ -487,7 +581,7 @@ BeOSKernelVolume::OpenIndexDir(void** cookie)
// CloseIndexDir
status_t
BeOSKernelVolume::CloseIndexDir(void* cookie)
BeOSKernelVolume::CloseIndexDir(fs_cookie cookie)
{
if (!fFSOps->close_indexdir)
return B_OK;
@ -496,7 +590,7 @@ BeOSKernelVolume::CloseIndexDir(void* cookie)
// FreeIndexDirCookie
status_t
BeOSKernelVolume::FreeIndexDirCookie(void* cookie)
BeOSKernelVolume::FreeIndexDirCookie(fs_cookie cookie)
{
if (!fFSOps->free_indexdircookie)
return B_OK;
@ -505,19 +599,22 @@ BeOSKernelVolume::FreeIndexDirCookie(void* cookie)
// ReadIndexDir
status_t
BeOSKernelVolume::ReadIndexDir(void* cookie, void* buffer, size_t bufferSize,
int32 count, int32* countRead)
BeOSKernelVolume::ReadIndexDir(fs_cookie cookie, void* buffer,
size_t bufferSize, uint32 count, uint32* countRead)
{
if (!fFSOps->read_indexdir)
return B_BAD_VALUE;
*countRead = count;
return fFSOps->read_indexdir(fVolumeCookie, cookie, countRead,
(struct dirent*)buffer, bufferSize);
// Haiku's struct dirent equals BeOS's version
return fFSOps->read_indexdir(fVolumeCookie, cookie, (long*)countRead,
(struct beos_dirent*)buffer, bufferSize);
}
// RewindIndexDir
status_t
BeOSKernelVolume::RewindIndexDir(void* cookie)
BeOSKernelVolume::RewindIndexDir(fs_cookie cookie)
{
if (!fFSOps->rewind_indexdir)
return B_BAD_VALUE;
@ -526,11 +623,11 @@ BeOSKernelVolume::RewindIndexDir(void* cookie)
// CreateIndex
status_t
BeOSKernelVolume::CreateIndex(const char* name, int type, int flags)
BeOSKernelVolume::CreateIndex(const char* name, uint32 type, uint32 flags)
{
if (!fFSOps->create_index)
return B_BAD_VALUE;
return fFSOps->create_index(fVolumeCookie, name, type, flags);
return fFSOps->create_index(fVolumeCookie, name, (int)type, (int)flags);
}
// RemoveIndex
@ -542,41 +639,47 @@ BeOSKernelVolume::RemoveIndex(const char* name)
return fFSOps->remove_index(fVolumeCookie, name);
}
// RenameIndex
status_t
BeOSKernelVolume::RenameIndex(const char* oldName, const char* newName)
{
if (!fFSOps->rename_index)
return B_BAD_VALUE;
return fFSOps->rename_index(fVolumeCookie, oldName, newName);
}
// StatIndex
status_t
BeOSKernelVolume::StatIndex(const char *name, struct index_info* indexInfo)
BeOSKernelVolume::ReadIndexStat(const char *name, struct stat *st)
{
if (!fFSOps->stat_index)
return B_BAD_VALUE;
return fFSOps->stat_index(fVolumeCookie, name, indexInfo);
beos_index_info indexInfo;
status_t error = fFSOps->stat_index(fVolumeCookie, name, &indexInfo);
if (error != B_OK)
return error;
// translate index_info into struct stat
st->st_type = indexInfo.type;
st->st_size = indexInfo.size;
st->st_mtime = indexInfo.modification_time;
st->st_crtime = indexInfo.creation_time;
st->st_uid = indexInfo.uid;
st->st_gid = indexInfo.gid;
return B_OK;
}
// #pragma mark -
// #pragma mark ----- queries -----
// #pragma mark - queries
// OpenQuery
status_t
BeOSKernelVolume::OpenQuery(const char* queryString, ulong flags, port_id port,
long token, void** cookie)
BeOSKernelVolume::OpenQuery(const char* queryString, uint32 flags, port_id port,
uint32 token, fs_cookie *cookie)
{
if (!fFSOps->open_query)
return B_BAD_VALUE;
return fFSOps->open_query(fVolumeCookie, queryString, flags, port,
token, cookie);
(long)token, cookie);
}
// CloseQuery
status_t
BeOSKernelVolume::CloseQuery(void* cookie)
BeOSKernelVolume::CloseQuery(fs_cookie cookie)
{
if (!fFSOps->close_query)
return B_OK;
@ -585,7 +688,7 @@ BeOSKernelVolume::CloseQuery(void* cookie)
// FreeQueryCookie
status_t
BeOSKernelVolume::FreeQueryCookie(void* cookie)
BeOSKernelVolume::FreeQueryCookie(fs_cookie cookie)
{
if (!fFSOps->free_querycookie)
return B_OK;
@ -594,13 +697,16 @@ BeOSKernelVolume::FreeQueryCookie(void* cookie)
// ReadQuery
status_t
BeOSKernelVolume::ReadQuery(void* cookie, void* buffer, size_t bufferSize,
int32 count, int32* countRead)
BeOSKernelVolume::ReadQuery(fs_cookie cookie, void* buffer, size_t bufferSize,
uint32 count, uint32* countRead)
{
if (!fFSOps->read_query)
return B_BAD_VALUE;
*countRead = count;
return fFSOps->read_query(fVolumeCookie, cookie, countRead,
(struct dirent*)buffer, bufferSize);
// Haiku's struct dirent equals BeOS's version
return fFSOps->read_query(fVolumeCookie, cookie, (long*)countRead,
(struct beos_dirent*)buffer, bufferSize);
}

View File

@ -5,130 +5,138 @@
#include "Volume.h"
struct vnode_ops;
struct beos_vnode_ops;
namespace UserlandFS {
class BeOSKernelVolume : public Volume {
public:
BeOSKernelVolume(FileSystem* fileSystem,
nspace_id id, vnode_ops* fsOps);
mount_id id, beos_vnode_ops* fsOps);
virtual ~BeOSKernelVolume();
// FS
virtual status_t Mount(const char* device, ulong flags,
const char* parameters, int32 len,
vnode_id* rootID);
virtual status_t Mount(const char* device, uint32 flags,
const char* parameters, vnode_id* rootID);
virtual status_t Unmount();
virtual status_t Sync();
virtual status_t ReadFSStat(fs_info* info);
virtual status_t WriteFSStat(struct fs_info *info, long mask);
virtual status_t ReadFSInfo(fs_info* info);
virtual status_t WriteFSInfo(const struct fs_info* info,
uint32 mask);
// vnodes
virtual status_t ReadVNode(vnode_id vnid, char reenter,
void** node);
virtual status_t WriteVNode(void* node, char reenter);
virtual status_t RemoveVNode(void* node, char reenter);
virtual status_t Lookup(fs_vnode dir, const char* entryName,
vnode_id* vnid, int* type);
virtual status_t ReadVNode(vnode_id vnid, bool reenter,
fs_vnode* node);
virtual status_t WriteVNode(fs_vnode node, bool reenter);
virtual status_t RemoveVNode(fs_vnode node, bool reenter);
// nodes
virtual status_t FSync(void* node);
virtual status_t ReadStat(void* node, struct stat* st);
virtual status_t WriteStat(void* node, struct stat* st,
long mask);
virtual status_t Access(void* node, int mode);
virtual status_t IOCtl(fs_vnode node, fs_cookie cookie,
uint32 command, void* buffer, size_t size);
virtual status_t SetFlags(fs_vnode node, fs_cookie cookie,
int flags);
virtual status_t Select(fs_vnode node, fs_cookie cookie,
uint8 event, uint32 ref, selectsync* sync);
virtual status_t Deselect(fs_vnode node, fs_cookie cookie,
uint8 event, selectsync* sync);
virtual status_t FSync(fs_vnode node);
virtual status_t ReadSymlink(fs_vnode node, char* buffer,
size_t bufferSize, size_t* bytesRead);
virtual status_t CreateSymlink(fs_vnode dir, const char* name,
const char* target, int mode);
virtual status_t Link(fs_vnode dir, const char* name,
fs_vnode node);
virtual status_t Unlink(fs_vnode dir, const char* name);
virtual status_t Rename(fs_vnode oldDir, const char* oldName,
fs_vnode newDir, const char* newName);
virtual status_t Access(fs_vnode node, int mode);
virtual status_t ReadStat(fs_vnode node, struct stat* st);
virtual status_t WriteStat(fs_vnode node, const struct stat *st,
uint32 mask);
// files
virtual status_t Create(void* dir, const char* name,
int openMode, int mode, vnode_id* vnid,
void** cookie);
virtual status_t Open(void* node, int openMode, void** cookie);
virtual status_t Close(void* node, void* cookie);
virtual status_t FreeCookie(void* node, void* cookie);
virtual status_t Read(void* node, void* cookie, off_t pos,
virtual status_t Create(fs_vnode dir, const char* name,
int openMode, int mode, fs_cookie* cookie,
vnode_id* vnid);
virtual status_t Open(fs_vnode node, int openMode,
fs_cookie* cookie);
virtual status_t Close(fs_vnode node, fs_cookie cookie);
virtual status_t FreeCookie(fs_vnode node, fs_cookie cookie);
virtual status_t Read(fs_vnode node, fs_cookie cookie, off_t pos,
void* buffer, size_t bufferSize,
size_t* bytesRead);
virtual status_t Write(void* node, void* cookie, off_t pos,
const void* buffer, size_t bufferSize,
size_t* bytesWritten);
virtual status_t IOCtl(void* node, void* cookie, int command,
void *buffer, size_t size);
virtual status_t SetFlags(void* node, void* cookie, int flags);
virtual status_t Select(void* node, void* cookie, uint8 event,
uint32 ref, selectsync* sync);
virtual status_t Deselect(void* node, void* cookie, uint8 event,
selectsync* sync);
// hard links / symlinks
virtual status_t Link(void* dir, const char* name, void* node);
virtual status_t Unlink(void* dir, const char* name);
virtual status_t Symlink(void* dir, const char* name,
const char* target);
virtual status_t ReadLink(void* node, char* buffer,
size_t bufferSize, size_t* bytesRead);
virtual status_t Rename(void* oldDir, const char* oldName,
void* newDir, const char* newName);
virtual status_t Write(fs_vnode node, fs_cookie cookie,
off_t pos, const void* buffer,
size_t bufferSize, size_t* bytesWritten);
// directories
virtual status_t MkDir(void* dir, const char* name, int mode);
virtual status_t RmDir(void* dir, const char* name);
virtual status_t OpenDir(void* node, void** cookie);
virtual status_t CloseDir(void* node, void* cookie);
virtual status_t FreeDirCookie(void* node, void* cookie);
virtual status_t ReadDir(void* node, void* cookie,
virtual status_t CreateDir(fs_vnode dir, const char* name,
int mode, vnode_id *newDir);
virtual status_t RemoveDir(fs_vnode dir, const char* name);
virtual status_t OpenDir(fs_vnode node, fs_cookie* cookie);
virtual status_t CloseDir(fs_vnode node, fs_vnode cookie);
virtual status_t FreeDirCookie(fs_vnode node, fs_vnode cookie);
virtual status_t ReadDir(fs_vnode node, fs_vnode cookie,
void* buffer, size_t bufferSize,
int32 count, int32* countRead);
virtual status_t RewindDir(void* node, void* cookie);
virtual status_t Walk(void* dir, const char* entryName,
char** resolvedPath, vnode_id* vnid);
uint32 count, uint32* countRead);
virtual status_t RewindDir(fs_vnode node, fs_vnode cookie);
// attribute directories
virtual status_t OpenAttrDir(fs_vnode node, fs_cookie *cookie);
virtual status_t CloseAttrDir(fs_vnode node, fs_cookie cookie);
virtual status_t FreeAttrDirCookie(fs_vnode node,
fs_cookie cookie);
virtual status_t ReadAttrDir(fs_vnode node, fs_cookie cookie,
void* buffer, size_t bufferSize,
uint32 count, uint32* countRead);
virtual status_t RewindAttrDir(fs_vnode node, fs_cookie cookie);
// attributes
virtual status_t OpenAttrDir(void* node, void** cookie);
virtual status_t CloseAttrDir(void* node, void* cookie);
virtual status_t FreeAttrDirCookie(void* node, void* cookie);
virtual status_t ReadAttrDir(void* node, void* cookie,
void* buffer, size_t bufferSize,
int32 count, int32* countRead);
virtual status_t RewindAttrDir(void* node, void* cookie);
virtual status_t ReadAttr(void* node, const char* name,
int type, off_t pos, void* buffer,
size_t bufferSize, size_t* bytesRead);
virtual status_t WriteAttr(void* node, const char* name,
int type, off_t pos, const void* buffer,
virtual status_t ReadAttr(fs_vnode node, fs_cookie cookie,
off_t pos, void* buffer, size_t bufferSize,
size_t* bytesRead);
virtual status_t WriteAttr(fs_vnode node, fs_cookie cookie,
off_t pos, const void* buffer,
size_t bufferSize, size_t* bytesWritten);
virtual status_t RemoveAttr(void* node, const char* name);
virtual status_t RenameAttr(void* node, const char* oldName,
virtual status_t ReadAttrStat(fs_vnode node, fs_cookie cookie,
struct stat *st);
virtual status_t RenameAttr(fs_vnode oldNode,
const char* oldName, fs_vnode newNode,
const char* newName);
virtual status_t StatAttr(void* node, const char* name,
struct attr_info* attrInfo);
virtual status_t RemoveAttr(fs_vnode node, const char* name);
// indices
virtual status_t OpenIndexDir(void** cookie);
virtual status_t CloseIndexDir(void* cookie);
virtual status_t FreeIndexDirCookie(void* cookie);
virtual status_t ReadIndexDir(void* cookie, void* buffer,
size_t bufferSize, int32 count,
int32* countRead);
virtual status_t RewindIndexDir(void* cookie);
virtual status_t CreateIndex(const char* name, int type,
int flags);
virtual status_t OpenIndexDir(fs_cookie *cookie);
virtual status_t CloseIndexDir(fs_cookie cookie);
virtual status_t FreeIndexDirCookie(fs_cookie cookie);
virtual status_t ReadIndexDir(fs_cookie cookie, void* buffer,
size_t bufferSize, uint32 count,
uint32* countRead);
virtual status_t RewindIndexDir(fs_cookie cookie);
virtual status_t CreateIndex(const char* name, uint32 type,
uint32 flags);
virtual status_t RemoveIndex(const char* name);
virtual status_t RenameIndex(const char* oldName,
const char* newName);
virtual status_t StatIndex(const char *name,
struct index_info* indexInfo);
virtual status_t ReadIndexStat(const char *name,
struct stat *st);
// queries
virtual status_t OpenQuery(const char* queryString,
ulong flags, port_id port, long token,
void** cookie);
virtual status_t CloseQuery(void* cookie);
virtual status_t FreeQueryCookie(void* cookie);
virtual status_t ReadQuery(void* cookie, void* buffer,
size_t bufferSize, int32 count,
int32* countRead);
uint32 flags, port_id port, uint32 token,
fs_cookie *cookie);
virtual status_t CloseQuery(fs_cookie cookie);
virtual status_t FreeQueryCookie(fs_cookie cookie);
virtual status_t ReadQuery(fs_cookie cookie, void* buffer,
size_t bufferSize, uint32 count,
uint32* countRead);
private:
vnode_ops* fFSOps;
beos_vnode_ops* fFSOps;
void* fVolumeCookie;
};

View File

@ -32,19 +32,19 @@ Application UserlandFSServer
SingleReplyRequestHandler.cpp
String.cpp
# cache.c
# sysdep.c
beos_fs_cache.c
# BeOSKernelFileSystem.cpp
# BeOSKernelVolume.cpp
beos_lock.cpp
BeOSKernelFileSystem.cpp
BeOSKernelVolume.cpp
DispatcherFileSystem.cpp
FileSystem.cpp
# kernel_emu.cpp
kernel_emu.cpp
main.cpp
RequestThread.cpp
ServerDefs.cpp
UserlandFSDispatcher.cpp
# UserlandFSServer.cpp
UserlandFSServer.cpp
UserlandRequestHandler.cpp
Volume.cpp
: be

View File

@ -1,11 +1,12 @@
// UserlandFSServer.cpp
#include "UserlandFSServer.h"
#include <new>
#include <stdio.h>
#include <string.h>
#include <Application.h>
#include <cache.h>
#include <Clipboard.h>
#include <FindDirectory.h>
#include <fs_interface.h>
@ -14,6 +15,8 @@
#include <Path.h>
#include "AutoLocker.h"
#include "beos_fs_cache.h"
#include "beos_fs_interface.h"
#include "BeOSKernelFileSystem.h"
#include "Compatibility.h"
#include "Debug.h"
@ -22,7 +25,6 @@
#include "FSInfo.h"
#include "RequestThread.h"
#include "ServerDefs.h"
#include "UserlandFSServer.h"
static const int32 kRequestThreadCount = 10;
@ -52,7 +54,7 @@ UserlandFSServer::~UserlandFSServer()
delete fNotificationRequestPort;
delete fFileSystem;
if (fBlockCacheInitialized)
shutdown_block_cache();
beos_shutdown_block_cache();
if (fAddOnImage >= 0)
unload_add_on(fAddOnImage);
}
@ -72,12 +74,14 @@ UserlandFSServer::Init(const char* fileSystem)
error = addOnPath.Append(fileSystem);
if (error != B_OK)
RETURN_ERROR(error);
// load the add-on
fAddOnImage = load_add_on(addOnPath.Path());
if (fAddOnImage < 0)
RETURN_ERROR(fAddOnImage);
// get the symbols "fs_entry" and "api_version"
vnode_ops* fsOps;
beos_vnode_ops* fsOps;
error = get_image_symbol(fAddOnImage, "fs_entry", B_SYMBOL_TYPE_TEXT,
(void**)&fsOps);
if (error != B_OK)
@ -87,18 +91,22 @@ UserlandFSServer::Init(const char* fileSystem)
(void**)&apiVersion);
if (error != B_OK)
RETURN_ERROR(error);
// check api version
if (*apiVersion != B_CUR_FS_API_VERSION)
if (*apiVersion != BEOS_FS_API_VERSION)
RETURN_ERROR(B_ERROR);
// create the file system
fFileSystem = new(nothrow) BeOSKernelFileSystem(fsOps);
if (!fileSystem)
RETURN_ERROR(B_NO_MEMORY);
// init the block cache
error = init_block_cache(kMaxBlockCacheBlocks, 0);
error = beos_init_block_cache(kMaxBlockCacheBlocks, 0);
if (error != B_OK)
RETURN_ERROR(error);
fBlockCacheInitialized = true;
// create the notification request port
fNotificationRequestPort = new(nothrow) RequestPort(kRequestPortSize);
if (!fNotificationRequestPort)
@ -106,6 +114,7 @@ UserlandFSServer::Init(const char* fileSystem)
error = fNotificationRequestPort->InitCheck();
if (error != B_OK)
RETURN_ERROR(error);
// now create the request threads
fRequestThreads = new(nothrow) RequestThread[kRequestThreadCount];
if (!fRequestThreads)
@ -115,12 +124,15 @@ UserlandFSServer::Init(const char* fileSystem)
if (error != B_OK)
RETURN_ERROR(error);
}
// run the threads
for (int32 i = 0; i < kRequestThreadCount; i++)
fRequestThreads[i].Run();
// enter the debugger here, if desired
if (gServerSettings.ShallEnterDebugger())
debugger("File system ready to use.");
// finally register with the dispatcher
error = _RegisterWithDispatcher(fileSystem);
RETURN_ERROR(error);

View File

@ -5,6 +5,11 @@
#include <Application.h>
namespace UserlandFSUtil {
class RequestPort;
}
using UserlandFSUtil::RequestPort;
namespace UserlandFS {
class FileSystem;

View File

@ -63,7 +63,7 @@ Volume::ReadFSInfo(fs_info* info)
// WriteFSInfo
status_t
Volume::WriteFSInfo(const struct fs_info *info, uint32 mask)
Volume::WriteFSInfo(const struct fs_info* info, uint32 mask)
{
return B_BAD_VALUE;
}

View File

@ -24,7 +24,7 @@ public:
virtual status_t Unmount();
virtual status_t Sync();
virtual status_t ReadFSInfo(fs_info* info);
virtual status_t WriteFSInfo(const struct fs_info *info,
virtual status_t WriteFSInfo(const struct fs_info* info,
uint32 mask);
// vnodes

View File

@ -43,17 +43,16 @@
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#ifdef __BEOS__
#include <OS.h>
#include <KernelExport.h>
#endif
#include "compat.h"
#include "lock.h"
#include "cache.h"
#include "beos_fs_cache.h"
#include "beos_fs_cache_priv.h"
#include "beos_lock.h"
@ -65,6 +64,8 @@
#endif
typedef off_t fs_off_t;
/* forward prototypes */
static int flush_ents(cache_ent **ents, int n_ents);
@ -78,8 +79,21 @@ int chatty_io = 0;
#define CHUNK (512 * 1024) /* a hack to work around scsi driver bugs */
static void
beos_panic(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
while (TRUE)
;
}
size_t
read_phys_blocks(int fd, fs_off_t bnum, void *data, uint num_blocks, int bsize)
beos_read_phys_blocks(int fd, fs_off_t bnum, void *data, uint num_blocks, int bsize)
{
size_t ret = 0;
size_t sum;
@ -116,7 +130,7 @@ read_phys_blocks(int fd, fs_off_t bnum, void *data, uint num_blocks, int bsize)
}
size_t
write_phys_blocks(int fd, fs_off_t bnum, void *data, uint num_blocks, int bsize)
beos_write_phys_blocks(int fd, fs_off_t bnum, void *data, uint num_blocks, int bsize)
{
size_t ret = 0;
size_t sum;
@ -358,7 +372,7 @@ hash_delete(hash_table *ht, int dev, fs_off_t bnum)
else if (prev)
prev->next = he->next;
else
panic("hash table is inconsistent\n");
beos_panic("hash table is inconsistent\n");
free(he);
ht->num_elements--;
@ -374,7 +388,7 @@ hash_delete(hash_table *ht, int dev, fs_off_t bnum)
static block_cache bc;
#define MAX_IOVECS 64 /* # of iovecs for use by cache code */
static lock iovec_lock;
static beos_lock iovec_lock;
static struct iovec *iovec_pool[MAX_IOVECS]; /* each ptr is to an array of iovecs */
static int iovec_used[MAX_IOVECS]; /* non-zero == iovec is in use */
@ -394,7 +408,7 @@ static bigtime_t last_cache_access = 0;
int
init_block_cache(int max_blocks, int flags)
beos_init_block_cache(int max_blocks, int flags)
{
memset(&bc, 0, sizeof(bc));
memset(iovec_pool, 0, sizeof(iovec_pool));
@ -408,10 +422,10 @@ init_block_cache(int max_blocks, int flags)
bc.max_blocks = max_blocks;
bc.flags = flags;
if (new_lock(&bc.lock, "bollockcache") != 0)
if (beos_new_lock(&bc.lock, "bollockcache") != 0)
goto err;
if (new_lock(&iovec_lock, "iovec_lock") != 0)
if (beos_new_lock(&iovec_lock, "iovec_lock") != 0)
goto err;
/* allocate two of these up front so vm won't accidently re-enter itself */
@ -431,10 +445,10 @@ init_block_cache(int max_blocks, int flags)
err:
if (bc.lock.s >= 0)
free_lock(&bc.lock);
beos_free_lock(&bc.lock);
if (iovec_lock.s >= 0)
free_lock(&iovec_lock);
beos_free_lock(&iovec_lock);
shutdown_hash_table(&bc.ht);
memset((void *)&bc, 0, sizeof(bc));
@ -456,13 +470,13 @@ get_iovec_array(void)
}
if (i >= MAX_IOVECS) /* uh-oh */
panic("cache: ran out of iovecs (pool 0x%x, used 0x%x)!\n",
beos_panic("cache: ran out of iovecs (pool 0x%x, used 0x%x)!\n",
&iovec_pool[0], &iovec_used[0]);
if (iovec_pool[i] == NULL) {
iovec_pool[i] = (struct iovec *)malloc(sizeof(struct iovec)*NUM_FLUSH_BLOCKS);
if (iovec_pool == NULL)
panic("can't allocate an iovec!\n");
beos_panic("can't allocate an iovec!\n");
}
iov = iovec_pool[i];
@ -545,7 +559,7 @@ check_bcache(char *str)
if (count != bc.cur_blocks) {
if (count < bc.cur_blocks - 16)
panic("%s: count == %d, cur_blocks %d, prev 0x%x\n",
beos_panic("%s: count == %d, cur_blocks %d, prev 0x%x\n",
str, count, bc.cur_blocks, prev);
else
printf("%s: count == %d, cur_blocks %d, prev 0x%x\n",
@ -588,13 +602,13 @@ check_lists(void)
for(oce=bc.locked.lru; oce; oce=oce->next) {
if (oce == ce) {
dump_lists();
panic("1:ce @ 0x%x is in two lists(cel 0x%x &LOCKED)\n",ce,cel);
beos_panic("1:ce @ 0x%x is in two lists(cel 0x%x &LOCKED)\n",ce,cel);
}
}
}
if (prev && prev != cel->mru) {
dump_lists();
panic("*** last element in list != cel mru (ce 0x%x, cel 0x%x)\n",
beos_panic("*** last element in list != cel mru (ce 0x%x, cel 0x%x)\n",
prev, cel);
}
@ -603,13 +617,13 @@ check_lists(void)
for(oce=bc.normal.lru; oce; oce=oce->next) {
if (oce == ce) {
dump_lists();
panic("3:ce @ 0x%x is in two lists(cel 0x%x & DIRTY)\n",ce,cel);
beos_panic("3:ce @ 0x%x is in two lists(cel 0x%x & DIRTY)\n",ce,cel);
}
}
}
if (prev && prev != cel->mru) {
dump_lists();
panic("*** last element in list != cel mru (ce 0x%x, cel 0x%x)\n",
beos_panic("*** last element in list != cel mru (ce 0x%x, cel 0x%x)\n",
prev, cel);
}
}
@ -727,7 +741,7 @@ static void
add_to_head(cache_ent_list *cel, cache_ent *ce)
{
if (ce->next != NULL || ce->prev != NULL) {
panic("*** ath: ce has non-null next/prev ptr (ce 0x%x nxt 0x%x, prv 0x%x)\n",
beos_panic("*** ath: ce has non-null next/prev ptr (ce 0x%x nxt 0x%x, prv 0x%x)\n",
ce, ce->next, ce->prev);
}
@ -752,7 +766,7 @@ static void
add_to_tail(cache_ent_list *cel, cache_ent *ce)
{
if (ce->next != NULL || ce->prev != NULL) {
panic("*** att: ce has non-null next/prev ptr (ce 0x%x nxt 0x%x, prv 0x%x)\n",
beos_panic("*** att: ce has non-null next/prev ptr (ce 0x%x nxt 0x%x, prv 0x%x)\n",
ce, ce->next, ce->prev);
}
@ -775,7 +789,7 @@ cache_ent_cmp(const void *a, const void *b)
cache_ent *p1 = *(cache_ent **)a, *p2 = *(cache_ent **)b;
if (p1 == NULL || p2 == NULL)
panic("cache_ent pointers are null?!? (a 0x%lx, b 0x%lx\n)\n", a, b);
beos_panic("cache_ent pointers are null?!? (a 0x%lx, b 0x%lx\n)\n", a, b);
if (p1->dev == p2->dev) {
diff = p1->block_num - p2->block_num;
@ -878,7 +892,7 @@ flush_cache_ent(cache_ent *ce)
data = ce->data;
if (chatty_io > 2) printf("flush: %7Ld\n", ce->block_num);
ret = write_phys_blocks(ce->dev, ce->block_num, data, 1, ce->bsize);
ret = beos_write_phys_blocks(ce->dev, ce->block_num, data, 1, ce->bsize);
if (ce->func) {
ce->func(ce->logged_bnum, 1, ce->arg);
@ -1070,7 +1084,7 @@ delete_cache_list(cache_ent_list *cel)
void
shutdown_block_cache(void)
beos_shutdown_block_cache(void)
{
/* print_hash_stats(&bc.ht); */
@ -1090,17 +1104,17 @@ shutdown_block_cache(void)
shutdown_hash_table(&bc.ht);
if (bc.lock.s > 0)
free_lock(&bc.lock);
beos_free_lock(&bc.lock);
bc.lock.s = -1;
if (iovec_lock.s >= 0)
free_lock(&iovec_lock);
beos_free_lock(&iovec_lock);
}
int
init_cache_for_device(int fd, fs_off_t max_blocks)
beos_init_cache_for_device(int fd, fs_off_t max_blocks)
{
int ret = 0;
@ -1153,7 +1167,7 @@ block_lookup(int dev, fs_off_t bnum)
}
if (ce->flags & CE_BUSY)
panic("block lookup: returning a busy block @ 0x%lx?!?\n",(ulong)ce);
beos_panic("block lookup: returning a busy block @ 0x%lx?!?\n",(ulong)ce);
return ce;
}
@ -1161,7 +1175,7 @@ block_lookup(int dev, fs_off_t bnum)
int
set_blocks_info(int dev, fs_off_t *blocks, int nblocks,
beos_set_blocks_info(int dev, fs_off_t *blocks, int nblocks,
void (*func)(fs_off_t bnum, size_t nblocks, void *arg), void *arg)
{
int i, j, cur;
@ -1176,7 +1190,7 @@ set_blocks_info(int dev, fs_off_t *blocks, int nblocks,
/* printf("sbi: %ld (arg 0x%x)\n", blocks[i], arg); */
ce = block_lookup(dev, blocks[i]);
if (ce == NULL) {
panic("*** set_block_info can't find bnum %ld!\n", blocks[i]);
beos_panic("*** set_block_info can't find bnum %ld!\n", blocks[i]);
UNLOCK(bc.lock);
return ENOENT; /* hopefully this doesn't happen... */
}
@ -1184,19 +1198,19 @@ set_blocks_info(int dev, fs_off_t *blocks, int nblocks,
if (blocks[i] != ce->block_num || dev != ce->dev) {
UNLOCK(bc.lock);
panic("** error1: looked up dev %d block %ld but found dev %d "
beos_panic("** error1: looked up dev %d block %ld but found dev %d "
"bnum %ld\n", dev, blocks[i], ce->dev, ce->block_num);
return EBADF;
}
if (ce->lock == 0) {
panic("* set_block_info on bnum %ld (%d) but it's not locked!\n",
beos_panic("* set_block_info on bnum %ld (%d) but it's not locked!\n",
blocks[i], nblocks);
}
if ((ce->flags & CE_DIRTY) == 0) {
panic("*** set_block_info on non-dirty block bnum %ld (%d)!\n",
beos_panic("*** set_block_info on non-dirty block bnum %ld (%d)!\n",
blocks[i], nblocks);
}
@ -1241,7 +1255,7 @@ set_blocks_info(int dev, fs_off_t *blocks, int nblocks,
/* we can call hash_lookup() here because we know it's around */
ce = hash_lookup(&bc.ht, dev, blocks[i]);
if (ce == NULL) {
panic("*** set_block_info can't find bnum %Ld!\n", blocks[i]);
beos_panic("*** set_block_info can't find bnum %Ld!\n", blocks[i]);
UNLOCK(bc.lock);
return ENOENT; /* hopefully this doesn't happen... */
}
@ -1249,18 +1263,18 @@ set_blocks_info(int dev, fs_off_t *blocks, int nblocks,
ce->flags &= ~(CE_DIRTY | CE_BUSY);
if (ce->func != NULL) {
panic("*** set_block_info non-null callback on bnum %Ld\n",
beos_panic("*** set_block_info non-null callback on bnum %Ld\n",
ce->block_num);
}
if (ce->clone != NULL) {
panic("*** ce->clone == %p, not NULL in set_block_info\n",
beos_panic("*** ce->clone == %p, not NULL in set_block_info\n",
ce->clone);
}
ce->clone = (void *)malloc(ce->bsize);
if (ce->clone == NULL)
panic("*** can't clone bnum %Ld (bsize %d)\n",
beos_panic("*** can't clone bnum %Ld (bsize %d)\n",
ce->block_num, ce->bsize);
@ -1311,7 +1325,7 @@ do_flush(cache_ent **ents, int max)
}
int
flush_device(int dev, int warn_locked)
beos_flush_device(int dev, int warn_locked)
{
int cur;
cache_ent *ce;
@ -1422,7 +1436,7 @@ real_remove_cached_blocks(int dev, int allow_writes, cache_ent_list *cel)
ce->data = NULL;
if ((junk = hash_delete(&bc.ht, ce->dev, ce->block_num)) != ce) {
panic("*** remove_cached_device: bad hash table entry %ld "
beos_panic("*** remove_cached_device: bad hash table entry %ld "
"0x%lx != 0x%lx\n", ce->block_num, (ulong)junk, (ulong)ce);
}
@ -1434,7 +1448,7 @@ real_remove_cached_blocks(int dev, int allow_writes, cache_ent_list *cel)
}
int
remove_cached_device_blocks(int dev, int allow_writes)
beos_remove_cached_device_blocks(int dev, int allow_writes)
{
LOCK(bc.lock);
@ -1451,7 +1465,7 @@ remove_cached_device_blocks(int dev, int allow_writes)
int
flush_blocks(int dev, fs_off_t bnum, int nblocks)
beos_flush_blocks(int dev, fs_off_t bnum, int nblocks)
{
int cur, i;
cache_ent *ce;
@ -1470,7 +1484,7 @@ flush_blocks(int dev, fs_off_t bnum, int nblocks)
if (bnum != ce->block_num || dev != ce->dev) {
UNLOCK(bc.lock);
panic("error2: looked up dev %d block %ld but found %d %ld\n",
beos_panic("error2: looked up dev %d block %ld but found %d %ld\n",
dev, bnum, ce->dev, ce->block_num);
return EBADF;
}
@ -1513,7 +1527,7 @@ flush_blocks(int dev, fs_off_t bnum, int nblocks)
int
mark_blocks_dirty(int dev, fs_off_t bnum, int nblocks)
beos_mark_blocks_dirty(int dev, fs_off_t bnum, int nblocks)
{
int ret = 0;
cache_ent *ce;
@ -1542,7 +1556,7 @@ mark_blocks_dirty(int dev, fs_off_t bnum, int nblocks)
int
release_block(int dev, fs_off_t bnum)
beos_release_block(int dev, fs_off_t bnum)
{
cache_ent *ce;
@ -1552,7 +1566,7 @@ release_block(int dev, fs_off_t bnum)
ce = block_lookup(dev, bnum);
if (ce) {
if (bnum != ce->block_num || dev != ce->dev) {
panic("*** error3: looked up dev %d block %ld but found %d %ld\n",
beos_panic("*** error3: looked up dev %d block %ld but found %d %ld\n",
dev, bnum, ce->dev, ce->block_num);
UNLOCK(bc.lock);
return EBADF;
@ -1571,7 +1585,7 @@ release_block(int dev, fs_off_t bnum)
}
} else { /* hmmm, that's odd, didn't find it */
panic("** release_block asked to find %ld but it's not here\n",
beos_panic("** release_block asked to find %ld but it's not here\n",
bnum);
}
@ -1588,14 +1602,14 @@ new_cache_ent(int bsize)
ce = (cache_ent *)calloc(1, sizeof(cache_ent));
if (ce == NULL) {
panic("*** error: cache can't allocate memory!\n");
beos_panic("*** error: cache can't allocate memory!\n");
return NULL;
}
ce->data = malloc(bsize);
if (ce->data == NULL) {
free(ce);
panic("** error cache can't allocate data memory\n");
beos_panic("** error cache can't allocate data memory\n");
UNLOCK(bc.lock);
return NULL;
}
@ -1614,7 +1628,7 @@ get_ents(cache_ent **ents, int num_needed, int max, int *num_gotten, int bsize)
cache_ent *ce;
if (num_needed > max)
panic("get_ents: num_needed %d but max %d (doh!)\n", num_needed, max);
beos_panic("get_ents: num_needed %d but max %d (doh!)\n", num_needed, max);
/* if the cache isn't full yet, just allocate the blocks */
for(cur=0; bc.cur_blocks < bc.max_blocks && cur < num_needed; cur++) {
@ -1628,7 +1642,7 @@ get_ents(cache_ent **ents, int num_needed, int max, int *num_gotten, int bsize)
while(cur < num_needed && retry_counter < max_retry) {
for(ce=bc.normal.lru; ce && cur < num_needed; ce=ce->next) {
if (ce->lock)
panic("get_ents: normal list has locked blocks (ce 0x%x)\n",ce);
beos_panic("get_ents: normal list has locked blocks (ce 0x%x)\n",ce);
if (ce->flags & CE_BUSY) /* don't touch busy blocks */
continue;
@ -1648,7 +1662,7 @@ get_ents(cache_ent **ents, int num_needed, int max, int *num_gotten, int bsize)
if (cur < num_needed && retry_counter >= max_retry) { /* oh shit! */
dump_cache_list();
UNLOCK(bc.lock);
panic("get_ents: waited too long; can't get enough ce's (c %d n %d)\n",
beos_panic("get_ents: waited too long; can't get enough ce's (c %d n %d)\n",
cur, num_needed);
}
@ -1664,7 +1678,7 @@ get_ents(cache_ent **ents, int num_needed, int max, int *num_gotten, int bsize)
continue;
if (ce->lock)
panic("get_ents:2 dirty list has locked blocks (ce 0x%x)\n",ce);
beos_panic("get_ents:2 dirty list has locked blocks (ce 0x%x)\n",ce);
ce->flags |= CE_BUSY;
ents[cur++] = ce;
@ -1747,10 +1761,10 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
/* some sanity checks first */
if (bsize == 0)
panic("cache_io: block size == 0 for bnum %Ld?!?\n", bnum);
beos_panic("cache_io: block size == 0 for bnum %Ld?!?\n", bnum);
if (num_blocks == 0)
panic("cache_io: bnum %Ld has num_blocks == 0!\n", bnum);
beos_panic("cache_io: bnum %Ld has num_blocks == 0!\n", bnum);
if (data == NULL && dataptr == NULL) {
printf("major butthead move: null data and dataptr! bnum %Ld:%Ld\n",
@ -1760,11 +1774,11 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
if (data == NULL) {
if (num_blocks != 1) /* get_block() should never do that */
panic("cache_io: num_blocks %Ld but should be 1\n",
beos_panic("cache_io: num_blocks %Ld but should be 1\n",
num_blocks);
if (op & CACHE_WRITE)
panic("cache_io: get_block() asked to write?!?\n");
beos_panic("cache_io: get_block() asked to write?!?\n");
}
if (bnum + num_blocks > max_device_blocks[dev]) {
@ -1784,12 +1798,12 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
fs_off_t tmp;
if (data == NULL || (op & CACHE_LOCKED)) {
panic("*** asked to do a large locked io that's too hard!\n");
beos_panic("*** asked to do a large locked io that's too hard!\n");
}
if (op & CACHE_READ) {
if (read_phys_blocks(dev, bnum, data, num_blocks, bsize) != 0) {
if (beos_read_phys_blocks(dev, bnum, data, num_blocks, bsize) != 0) {
printf("cache read:read_phys_blocks failed (%s on blocks %Ld:%Ld)!\n",
strerror(errno), bnum, num_blocks);
return EINVAL;
@ -1811,7 +1825,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
if (ce) {
if (tmp != ce->block_num || dev != ce->dev) {
UNLOCK(bc.lock);
panic("*** error4: looked up dev %d block %Ld but "
beos_panic("*** error4: looked up dev %d block %Ld but "
"found %d %Ld\n", dev, tmp, ce->dev,
ce->block_num);
}
@ -1831,7 +1845,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
if (ce) {
if (tmp != ce->block_num || dev != ce->dev) {
UNLOCK(bc.lock);
panic("*** error5: looked up dev %d block %Ld but "
beos_panic("*** error5: looked up dev %d block %Ld but "
"found %d %Ld\n", dev, tmp, ce->dev,
ce->block_num);
return EBADF;
@ -1850,7 +1864,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
UNLOCK(bc.lock);
if (write_phys_blocks(dev, bnum, data, num_blocks, bsize) != 0) {
if (beos_write_phys_blocks(dev, bnum, data, num_blocks, bsize) != 0) {
printf("cache write: write_phys_blocks failed (%s on blocks "
"%Ld:%Ld)!\n", strerror(errno), bnum, num_blocks);
return EINVAL;
@ -1871,13 +1885,13 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
if (ce) {
if (bnum != ce->block_num || dev != ce->dev) {
UNLOCK(bc.lock);
panic("*** error6: looked up dev %d block %ld but found "
beos_panic("*** error6: looked up dev %d block %ld but found "
"%d %ld\n", dev, bnum, ce->dev, ce->block_num);
return EBADF;
}
if (bsize != ce->bsize) {
panic("*** requested bsize %d but ce->bsize %d ce @ 0x%x\n",
beos_panic("*** requested bsize %d but ce->bsize %d ce @ 0x%x\n",
bsize, ce->bsize, ce);
}
@ -1913,7 +1927,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
ce->flags |= CE_DIRTY;
} else {
panic("cached_block_io: bogus op %d\n", op);
beos_panic("cached_block_io: bogus op %d\n", op);
}
if (op & CACHE_LOCKED)
@ -1982,7 +1996,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
get_ents(ents, num_needed, NUM_FLUSH_BLOCKS, &real_nblocks, bsize);
if (real_nblocks < num_needed) {
panic("don't have enough cache ents (need %d got %d %ld::%d)\n",
beos_panic("don't have enough cache ents (need %d got %d %ld::%d)\n",
num_needed, real_nblocks, bnum, num_blocks);
}
@ -2024,7 +2038,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
*/
if (cur < num_needed) {
if (hash_insert(&bc.ht, dev, bnum + cur, ce) != 0)
panic("could not insert cache ent for %d %ld (0x%lx)\n",
beos_panic("could not insert cache ent for %d %ld (0x%lx)\n",
dev, bnum + cur, (ulong)ents[cur]);
}
@ -2035,7 +2049,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
num_dirty++;
if (ce->lock)
panic("cbio: can't use locked blocks here ce @ 0x%x\n",ce);
beos_panic("cbio: can't use locked blocks here ce @ 0x%x\n",ce);
else
cel = &bc.normal;
@ -2113,7 +2127,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
tmp_ce = (cache_ent *)hash_delete(&bc.ht,dev,bnum+cur);
if (tmp_ce != ents[cur]) {
panic("hash_del0: %d %ld got 0x%lx, not 0x%lx\n",
beos_panic("hash_del0: %d %ld got 0x%lx, not 0x%lx\n",
dev, bnum+cur, (ulong)tmp_ce,
(ulong)ents[cur]);
}
@ -2121,7 +2135,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
tmp_ce = (cache_ent *)hash_delete(&bc.ht,ents[cur]->dev,
ents[cur]->block_num);
if (tmp_ce != ents[cur]) {
panic("hash_del1: %d %ld got 0x%lx, not 0x%lx\n",
beos_panic("hash_del1: %d %ld got 0x%lx, not 0x%lx\n",
ents[cur]->dev, ents[cur]->block_num, (ulong)tmp_ce,
(ulong)ents[cur]);
}
@ -2190,7 +2204,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
if (ce->dev != -1) {
tmp_ce = hash_delete(&bc.ht, ce->dev, ce->block_num);
if (tmp_ce == NULL || tmp_ce != ce) {
panic("*** hash_delete failure (ce 0x%x tce 0x%x)\n",
beos_panic("*** hash_delete failure (ce 0x%x tce 0x%x)\n",
ce, tmp_ce);
}
}
@ -2212,7 +2226,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
ents[cur]->flags &= ~CE_BUSY;
if (ents[cur]->lock)
panic("should not have locked blocks here (ce 0x%x)\n",
beos_panic("should not have locked blocks here (ce 0x%x)\n",
ents[cur]);
add_to_tail(&bc.normal, ents[cur]);
@ -2227,7 +2241,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
tmp_ce = (cache_ent *)hash_delete(&bc.ht,dev,bnum+cur);
if (tmp_ce != ents[cur]) {
panic("hash_del: %d %ld got 0x%lx, not 0x%lx\n",
beos_panic("hash_del: %d %ld got 0x%lx, not 0x%lx\n",
dev, bnum+cur, (ulong)tmp_ce,
(ulong)ents[cur]);
}
@ -2259,13 +2273,13 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
if (ce->dev != -1) { /* then clean this guy up */
if (ce->next || ce->prev)
panic("ce @ 0x%x should not be in a list yet!\n", ce);
beos_panic("ce @ 0x%x should not be in a list yet!\n", ce);
if (ce->clone)
free(ce->clone);
if (ce->data == NULL)
panic("ce @ 0x%lx has a null data ptr\n", (ulong)ce);
beos_panic("ce @ 0x%lx has a null data ptr\n", (ulong)ce);
}
ce->dev = dev;
@ -2309,7 +2323,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
if (data != NULL)
data = (void *)((char *)data + bsize);
else if (cur_nblocks != 1)
panic("cache can't handle setting data_ptr twice!\n");
beos_panic("cache can't handle setting data_ptr twice!\n");
} /* end of for(cur=0; cur < cur_nblocks; cur++) */
bnum += cur_nblocks;
@ -2326,7 +2340,7 @@ cache_block_io(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsiz
void *
get_block(int dev, fs_off_t bnum, int bsize)
beos_get_block(int dev, fs_off_t bnum, int bsize)
{
void *data;
@ -2338,7 +2352,7 @@ get_block(int dev, fs_off_t bnum, int bsize)
}
void *
get_empty_block(int dev, fs_off_t bnum, int bsize)
beos_get_empty_block(int dev, fs_off_t bnum, int bsize)
{
void *data;
@ -2350,7 +2364,7 @@ get_empty_block(int dev, fs_off_t bnum, int bsize)
}
int
cached_read(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsize)
beos_cached_read(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsize)
{
return cache_block_io(dev, bnum, data, num_blocks, bsize,
CACHE_READ | CACHE_READ_AHEAD_OK, NULL);
@ -2358,14 +2372,14 @@ cached_read(int dev, fs_off_t bnum, void *data, fs_off_t num_blocks, int bsize)
int
cached_write(int dev, fs_off_t bnum, const void *data, fs_off_t num_blocks,int bsize)
beos_cached_write(int dev, fs_off_t bnum, const void *data, fs_off_t num_blocks,int bsize)
{
return cache_block_io(dev, bnum, (void *)data, num_blocks, bsize,
CACHE_WRITE, NULL);
}
int
cached_write_locked(int dev, fs_off_t bnum, const void *data,
beos_cached_write_locked(int dev, fs_off_t bnum, const void *data,
fs_off_t num_blocks, int bsize)
{
return cache_block_io(dev, bnum, (void *)data, num_blocks, bsize,
@ -2374,7 +2388,7 @@ cached_write_locked(int dev, fs_off_t bnum, const void *data,
void
force_cache_flush(int dev, int prefer_log_blocks)
beos_force_cache_flush(int dev, int prefer_log_blocks)
{
int i, count = 0;
cache_ent *ce;

View File

@ -0,0 +1,60 @@
/*
Copyright 1999-2001, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
#ifndef USERLAND_FS_BEOS_FS_CACHE_H
#define USERLAND_FS_BEOS_FS_CACHE_H
#include <BeBuild.h>
#ifndef _IMPEXP_KERNEL
#define _IMPEXP_KERNEL
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern _IMPEXP_KERNEL int beos_init_block_cache(int max_blocks, int flags);
extern _IMPEXP_KERNEL void beos_shutdown_block_cache(void);
extern _IMPEXP_KERNEL void beos_force_cache_flush(int dev,
int prefer_log_blocks);
extern _IMPEXP_KERNEL int beos_flush_blocks(int dev, off_t bnum, int nblocks);
extern _IMPEXP_KERNEL int beos_flush_device(int dev, int warn_locked);
extern _IMPEXP_KERNEL int beos_init_cache_for_device(int fd,
off_t max_blocks);
extern _IMPEXP_KERNEL int beos_remove_cached_device_blocks(int dev,
int allow_write);
extern _IMPEXP_KERNEL void *beos_get_block(int dev, off_t bnum, int bsize);
extern _IMPEXP_KERNEL void *beos_get_empty_block(int dev, off_t bnum,
int bsize);
extern _IMPEXP_KERNEL int beos_release_block(int dev, off_t bnum);
extern _IMPEXP_KERNEL int beos_mark_blocks_dirty(int dev, off_t bnum,
int nblocks);
extern _IMPEXP_KERNEL int beos_cached_read(int dev, off_t bnum, void *data,
off_t num_blocks, int bsize);
extern _IMPEXP_KERNEL int beos_cached_write(int dev, off_t bnum,
const void *data, off_t num_blocks, int bsize);
extern _IMPEXP_KERNEL int beos_cached_write_locked(int dev, off_t bnum,
const void *data, off_t num_blocks, int bsize);
extern _IMPEXP_KERNEL int beos_set_blocks_info(int dev, off_t *blocks,
int nblocks, void (*func)(off_t bnum,
size_t nblocks, void *arg), void *arg);
extern _IMPEXP_KERNEL size_t beos_read_phys_blocks (int fd, off_t bnum,
void *data, uint num_blocks, int bsize);
extern _IMPEXP_KERNEL size_t beos_write_phys_blocks(int fd, off_t bnum,
void *data, uint num_blocks, int bsize);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* USERLAND_FS_BEOS_FS_CACHE_H */

View File

@ -0,0 +1,83 @@
/*
Copyright 1999-2001, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
#ifndef USERLAND_FS_BEOS_FS_CACHE_PRIV_H
#define USERLAND_FS_BEOS_FS_CACHE_PRIV_H
#include "beos_lock.h"
#ifndef _IMPEXP_KERNEL
#define _IMPEXP_KERNEL
#endif
typedef struct hash_ent {
int dev;
off_t bnum;
off_t hash_val;
void *data;
struct hash_ent *next;
} hash_ent;
typedef struct hash_table {
hash_ent **table;
int max;
int mask; /* == max - 1 */
int num_elements;
} hash_table;
#define HT_DEFAULT_MAX 128
typedef struct cache_ent {
int dev;
off_t block_num;
int bsize;
volatile int flags;
void *data;
void *clone; /* copy of data by set_block_info() */
int lock;
void (*func)(off_t bnum, size_t num_blocks, void *arg);
off_t logged_bnum;
void *arg;
struct cache_ent *next, /* points toward mru end of list */
*prev; /* points toward lru end of list */
} cache_ent;
#define CE_NORMAL 0x0000 /* a nice clean pristine page */
#define CE_DIRTY 0x0002 /* needs to be written to disk */
#define CE_BUSY 0x0004 /* this block has i/o happening, don't touch it */
typedef struct cache_ent_list {
cache_ent *lru; /* tail of the list */
cache_ent *mru; /* head of the list */
} cache_ent_list;
typedef struct block_cache {
struct beos_lock lock;
int flags;
int cur_blocks;
int max_blocks;
hash_table ht;
cache_ent_list normal, /* list of "normal" blocks (clean & dirty) */
locked; /* list of clean and locked blocks */
} block_cache;
#if 0 /* XXXdbg -- need to deal with write through caches */
#define DC_WRITE_THROUGH 0x0001 /* cache is write-through (for floppies) */
#endif
#define ALLOW_WRITES 1
#define NO_WRITES 0
#endif /* USERLAND_FS_BEOS_FS_CACHE_PRIV_H */

View File

@ -0,0 +1,243 @@
// beos_fs_interface.h
#ifndef USERLAND_FS_BEOS_FS_INTERFACE_H
#define USERLAND_FS_BEOS_FS_INTERFACE_H
#include <fs_interface.h>
// BeOS FS API version
#define BEOS_FS_API_VERSION 2
// BeOS structures
typedef struct beos_iovec {
void *iov_base;
size_t iov_len;
} beos_iovec;
typedef struct beos_dirent {
dev_t d_dev;
dev_t d_pdev;
ino_t d_ino;
ino_t d_pino;
unsigned short d_reclen;
char d_name[1];
} beos_dirent_t;
struct beos_stat {
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
off_t st_size;
dev_t st_rdev;
size_t st_blksize;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
time_t st_crtime;
};
struct beos_fs_info {
dev_t dev;
ino_t root;
uint32 flags;
off_t block_size;
off_t io_size;
off_t total_blocks;
off_t free_blocks;
off_t total_nodes;
off_t free_nodes;
char device_name[128];
char volume_name[B_FILE_NAME_LENGTH];
char fsh_name[B_OS_NAME_LENGTH];
};
typedef struct beos_attr_info {
uint32 type;
off_t size;
} beos_attr_info;
typedef struct beos_index_info {
uint32 type;
off_t size;
time_t modification_time;
time_t creation_time;
uid_t uid;
gid_t gid;
} beos_index_info;
// FS interface hook types
typedef int beos_op_read_vnode(void *ns, vnode_id vnid, char r, void **node);
typedef int beos_op_write_vnode(void *ns, void *node, char r);
typedef int beos_op_remove_vnode(void *ns, void *node, char r);
typedef int beos_op_secure_vnode(void *ns, void *node);
typedef int beos_op_walk(void *ns, void *base, const char *file, char **newpath,
vnode_id *vnid);
typedef int beos_op_access(void *ns, void *node, int mode);
typedef int beos_op_create(void *ns, void *dir, const char *name,
int omode, int perms, vnode_id *vnid, void **cookie);
typedef int beos_op_mkdir(void *ns, void *dir, const char *name, int perms);
typedef int beos_op_symlink(void *ns, void *dir, const char *name,
const char *path);
typedef int beos_op_link(void *ns, void *dir, const char *name, void *node);
typedef int beos_op_rename(void *ns, void *olddir, const char *oldname,
void *newdir, const char *newname);
typedef int beos_op_unlink(void *ns, void *dir, const char *name);
typedef int beos_op_rmdir(void *ns, void *dir, const char *name);
typedef int beos_op_readlink(void *ns, void *node, char *buf, size_t *bufsize);
typedef int beos_op_opendir(void *ns, void *node, void **cookie);
typedef int beos_op_closedir(void *ns, void *node, void *cookie);
typedef int beos_op_rewinddir(void *ns, void *node, void *cookie);
typedef int beos_op_readdir(void *ns, void *node, void *cookie, long *num,
struct beos_dirent *buf, size_t bufsize);
typedef int beos_op_open(void *ns, void *node, int omode, void **cookie);
typedef int beos_op_close(void *ns, void *node, void *cookie);
typedef int beos_op_free_cookie(void *ns, void *node, void *cookie);
typedef int beos_op_read(void *ns, void *node, void *cookie, off_t pos,
void *buf, size_t *len);
typedef int beos_op_write(void *ns, void *node, void *cookie, off_t pos,
const void *buf, size_t *len);
typedef int beos_op_readv(void *ns, void *node, void *cookie, off_t pos,
const beos_iovec *vec, size_t count, size_t *len);
typedef int beos_op_writev(void *ns, void *node, void *cookie, off_t pos,
const beos_iovec *vec, size_t count, size_t *len);
typedef int beos_op_ioctl(void *ns, void *node, void *cookie, int cmd,
void *buf, size_t len);
typedef int beos_op_setflags(void *ns, void *node, void *cookie, int flags);
typedef int beos_op_rstat(void *ns, void *node, struct beos_stat *);
typedef int beos_op_wstat(void *ns, void *node, const struct beos_stat *,
long mask);
typedef int beos_op_fsync(void *ns, void *node);
typedef int beos_op_select(void *ns, void *node, void *cookie, uint8 event,
uint32 ref, selectsync *sync);
typedef int beos_op_deselect(void *ns, void *node, void *cookie, uint8 event,
selectsync *sync);
typedef int beos_op_initialize(const char *devname, void *parms, size_t len);
typedef int beos_op_mount(mount_id nsid, const char *devname, ulong flags,
void *parms, size_t len, void **data, vnode_id *vnid);
typedef int beos_op_unmount(void *ns);
typedef int beos_op_sync(void *ns);
typedef int beos_op_rfsstat(void *ns, struct beos_fs_info *);
typedef int beos_op_wfsstat(void *ns, struct beos_fs_info *, long mask);
typedef int beos_op_open_attrdir(void *ns, void *node, void **cookie);
typedef int beos_op_close_attrdir(void *ns, void *node, void *cookie);
typedef int beos_op_rewind_attrdir(void *ns, void *node, void *cookie);
typedef int beos_op_read_attrdir(void *ns, void *node, void *cookie, long *num,
struct beos_dirent *buf, size_t bufsize);
typedef int beos_op_remove_attr(void *ns, void *node, const char *name);
typedef int beos_op_rename_attr(void *ns, void *node, const char *oldname,
const char *newname);
typedef int beos_op_stat_attr(void *ns, void *node, const char *name,
struct beos_attr_info *buf);
typedef int beos_op_write_attr(void *ns, void *node, const char *name, int type,
const void *buf, size_t *len, off_t pos);
typedef int beos_op_read_attr(void *ns, void *node, const char *name, int type,
void *buf, size_t *len, off_t pos);
typedef int beos_op_open_indexdir(void *ns, void **cookie);
typedef int beos_op_close_indexdir(void *ns, void *cookie);
typedef int beos_op_rewind_indexdir(void *ns, void *cookie);
typedef int beos_op_read_indexdir(void *ns, void *cookie, long *num,
struct beos_dirent *buf, size_t bufsize);
typedef int beos_op_create_index(void *ns, const char *name, int type,
int flags);
typedef int beos_op_remove_index(void *ns, const char *name);
typedef int beos_op_rename_index(void *ns, const char *oldname,
const char *newname);
typedef int beos_op_stat_index(void *ns, const char *name,
struct beos_index_info *buf);
typedef int beos_op_open_query(void *ns, const char *query, ulong flags,
port_id port, long token, void **cookie);
typedef int beos_op_close_query(void *ns, void *cookie);
typedef int beos_op_read_query(void *ns, void *cookie, long *num,
struct beos_dirent *buf, size_t bufsize);
// the FS interface structure
typedef struct beos_vnode_ops {
beos_op_read_vnode (*read_vnode);
beos_op_write_vnode (*write_vnode);
beos_op_remove_vnode (*remove_vnode);
beos_op_secure_vnode (*secure_vnode);
beos_op_walk (*walk);
beos_op_access (*access);
beos_op_create (*create);
beos_op_mkdir (*mkdir);
beos_op_symlink (*symlink);
beos_op_link (*link);
beos_op_rename (*rename);
beos_op_unlink (*unlink);
beos_op_rmdir (*rmdir);
beos_op_readlink (*readlink);
beos_op_opendir (*opendir);
beos_op_closedir (*closedir);
beos_op_free_cookie (*free_dircookie);
beos_op_rewinddir (*rewinddir);
beos_op_readdir (*readdir);
beos_op_open (*open);
beos_op_close (*close);
beos_op_free_cookie (*free_cookie);
beos_op_read (*read);
beos_op_write (*write);
beos_op_readv (*readv);
beos_op_writev (*writev);
beos_op_ioctl (*ioctl);
beos_op_setflags (*setflags);
beos_op_rstat (*rstat);
beos_op_wstat (*wstat);
beos_op_fsync (*fsync);
beos_op_initialize (*initialize);
beos_op_mount (*mount);
beos_op_unmount (*unmount);
beos_op_sync (*sync);
beos_op_rfsstat (*rfsstat);
beos_op_wfsstat (*wfsstat);
beos_op_select (*select);
beos_op_deselect (*deselect);
beos_op_open_indexdir (*open_indexdir);
beos_op_close_indexdir (*close_indexdir);
beos_op_free_cookie (*free_indexdircookie);
beos_op_rewind_indexdir (*rewind_indexdir);
beos_op_read_indexdir (*read_indexdir);
beos_op_create_index (*create_index);
beos_op_remove_index (*remove_index);
beos_op_rename_index (*rename_index);
beos_op_stat_index (*stat_index);
beos_op_open_attrdir (*open_attrdir);
beos_op_close_attrdir (*close_attrdir);
beos_op_free_cookie (*free_attrdircookie);
beos_op_rewind_attrdir (*rewind_attrdir);
beos_op_read_attrdir (*read_attrdir);
beos_op_write_attr (*write_attr);
beos_op_read_attr (*read_attr);
beos_op_remove_attr (*remove_attr);
beos_op_rename_attr (*rename_attr);
beos_op_stat_attr (*stat_attr);
beos_op_open_query (*open_query);
beos_op_close_query (*close_query);
beos_op_free_cookie (*free_querycookie);
beos_op_read_query (*read_query);
} beos_vnode_ops;
#endif // USERLAND_FS_BEOS_FS_INTERFACE_H

View File

@ -0,0 +1,50 @@
#include "beos_lock.h"
int
beos_new_lock(beos_lock *l, const char *name)
{
if (!l)
return B_BAD_VALUE;
l->s = create_sem(0, name);
if (l->s < 0)
return l->s;
l->c = 1;
return B_OK;
}
int
beos_free_lock(beos_lock *l)
{
if (!l)
return B_BAD_VALUE;
delete_sem(l->s);
return 0;
}
int
beos_new_mlock(beos_mlock *l, long c, const char *name)
{
if (!l)
return B_BAD_VALUE;
l->s = create_sem(c, name);
if (l->s < 0)
return l->s;
return B_OK;
}
int
beos_free_mlock(beos_mlock *l)
{
if (!l)
return B_BAD_VALUE;
delete_sem(l->s);
return 0;
}

View File

@ -0,0 +1,55 @@
/*
Copyright 1999-2001, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
#ifndef USERLAND_FS_BEOS_LOCK_H
#define USERLAND_FS_BEOS_LOCK_H
#include <BeBuild.h>
#include <OS.h>
#ifndef _IMPEXP_KERNEL
#define _IMPEXP_KERNEL
#endif
#ifdef __cplusplus
extern "C" {
#else
typedef struct beos_lock beos_lock;
typedef struct beos_mlock beos_mlock;
#endif
struct beos_lock {
sem_id s;
long c;
};
struct beos_mlock {
sem_id s;
};
extern _IMPEXP_KERNEL int beos_new_lock(beos_lock *l, const char *name);
extern _IMPEXP_KERNEL int beos_free_lock(beos_lock *l);
#ifdef LOCK
#undef LOCK
#endif
#define LOCK(l) if (atomic_add(&l.c, -1) <= 0) acquire_sem(l.s);
#define UNLOCK(l) if (atomic_add(&l.c, 1) < 0) release_sem(l.s);
extern _IMPEXP_KERNEL int beos_new_mlock(beos_mlock *l, long c, const char *name);
extern _IMPEXP_KERNEL int beos_free_mlock(beos_mlock *l);
#define LOCKM(l,cnt) acquire_sem_etc(l.s, cnt, 0, 0)
#define UNLOCKM(l,cnt) release_sem_etc(l.s, cnt, 0)
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@ -1,204 +0,0 @@
/*
This file contains some kit-wide typedefs and structs that basically
emulate most of a normal posix-y type system. The purpose of hiding
everything behind these typedefs is to avoid inconsistencies between
various systems (such as the difference in size between off_t on BeOS
and some versions of Unix). To further avoid complications I've also
hidden the stat and dirent structs since those vary even more widely.
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
Dominic Giampaolo
dbg@be.com
*/
#ifndef _COMPAT_H
#define _COMPAT_H
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <memory.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#ifdef __BEOS__
#include <OS.h> /* for typedefs and prototypes */
#include <image.h> /* for a few typedefs */
#include <Drivers.h> /* for various ioctl structs, etc */
#include <iovec.h> /* because we're boneheads sometimes */
#else
#include <sys/uio.h>
#endif
/*
By default (for portability reasons) the size of off_t's and ino_t's
is 32-bit. You can change the file system to be 64-bit if you want
by defining OFF_T_SIZE to be 8.
NOTE: if you change the size of OFF_T_SIZE to be 8 you will have to
go through the code and change any calls to printf() to use the
appropriate format for 64-bit integers on your OS. I have seen
4 different formats now: %Ld (BeOS and Linux), %qd (FreeBSD),
%lld (Irix) and %I64d (NT).
*/
#define OFF_T_SIZE 8
#if OFF_T_SIZE == 4
typedef long fs_off_t;
typedef long my_ino_t;
#elif OFF_T_SIZE == 8
typedef long long fs_off_t;
typedef long long my_ino_t;
#else
#error OFF_T_SIZE must be either 4 or 8.
#endif
typedef int my_dev_t;
typedef int my_mode_t;
typedef int my_uid_t;
typedef int my_gid_t;
/* This is the maximum length of a file name. Adjust it as you see fit */
#define FILE_NAME_LENGTH 256
/* This is maximum name size for naming a volume or semaphore/lock */
#define IDENT_NAME_LENGTH 32
typedef struct my_dirent {
my_dev_t d_dev;
my_ino_t d_ino;
unsigned short d_reclen;
char d_name[1];
} my_dirent_t;
typedef struct {
int fd;
struct my_dirent ent;
} MY_DIR;
/*
This is a pretty regular stat structure but it's our "internal"
version since if we depended on the host version we'd be exposed
to all sorts of nasty things (different sized ino_t's, etc).
We also can't use the normal naming style of "st_" for each field
name because on some systems fields like st_atime are really just
define's that expand to all sorts of weird stuff.
*/
struct my_stat {
my_dev_t dev; /* "device" that this file resides on */
my_ino_t ino; /* this file's inode #, unique per device */
my_mode_t mode; /* mode bits (rwx for user, group, etc) */
int nlink; /* number of hard links to this file */
my_uid_t uid; /* user id of the owner of this file */
my_gid_t gid; /* group id of the owner of this file */
fs_off_t size; /* size in bytes of this file */
size_t blksize; /* preferred block size for i/o */
time_t atime; /* last access time */
time_t mtime; /* last modification time */
time_t ctime; /* last change time, not creation time */
time_t crtime; /* creation time; not posix but useful */
};
#define MY_S_IFMT 00000170000 /* type of file */
#define MY_S_IFLNK 00000120000 /* symbolic link */
#define MY_S_IFREG 00000100000 /* regular */
#define MY_S_IFBLK 00000060000 /* block special */
#define MY_S_IFDIR 00000040000 /* directory */
#define MY_S_IFCHR 00000020000 /* character special */
#define MY_S_IFIFO 00000010000 /* fifo */
#define MY_S_ISREG(m) (((m) & MY_S_IFMT) == MY_S_IFREG)
#define MY_S_ISLNK(m) (((m) & MY_S_IFMT) == MY_S_IFLNK)
#define MY_S_ISBLK(m) (((m) & MY_S_IFMT) == MY_S_IFBLK)
#define MY_S_ISDIR(m) (((m) & MY_S_IFMT) == MY_S_IFDIR)
#define MY_S_ISCHR(m) (((m) & MY_S_IFMT) == MY_S_IFCHR)
#define MY_S_ISFIFO(m) (((m) & MY_S_IFMT) == MY_S_IFIFO)
#define MY_S_IUMSK 07777 /* user settable bits */
#define MY_S_ISUID 04000 /* set user id on execution */
#define MY_S_ISGID 02000 /* set group id on execution */
#define MY_S_ISVTX 01000 /* save swapped text even after use */
#define MY_S_IRWXU 00700 /* read, write, execute: owner */
#define MY_S_IRUSR 00400 /* read permission: owner */
#define MY_S_IWUSR 00200 /* write permission: owner */
#define MY_S_IXUSR 00100 /* execute permission: owner */
#define MY_S_IRWXG 00070 /* read, write, execute: group */
#define MY_S_IRGRP 00040 /* read permission: group */
#define MY_S_IWGRP 00020 /* write permission: group */
#define MY_S_IXGRP 00010 /* execute permission: group */
#define MY_S_IRWXO 00007 /* read, write, execute: other */
#define MY_S_IROTH 00004 /* read permission: other */
#define MY_S_IWOTH 00002 /* write permission: other */
#define MY_S_IXOTH 00001 /* execute permission: other */
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef __BEOS__
typedef long sem_id;
typedef unsigned char uchar;
typedef short int16;
typedef unsigned short uint16;
typedef int int32;
typedef unsigned int uint32;
#define ulong unsigned long /* make it a #define to avoid conflicts */
typedef long long int64;
typedef unsigned long long uint64;
typedef unsigned int port_id;
typedef int bool;
typedef int image_id;
typedef long long bigtime_t;
typedef long thread_id;
typedef long status_t;
sem_id create_sem(long count, const char *name);
long delete_sem(sem_id sem);
long acquire_sem(sem_id sem);
long acquire_sem_etc(sem_id sem, int count, int flags,
bigtime_t microsecond_timeout);
long release_sem(sem_id sem);
long release_sem_etc(sem_id sem, long count, long flags);
long atomic_add(long *value, long addvalue);
int snooze(bigtime_t f);
bigtime_t system_time(void);
ssize_t read_pos(int fd, fs_off_t _pos, void *data, size_t nbytes);
ssize_t write_pos(int fd, fs_off_t _pos, const void *data, size_t nbytes);
ssize_t readv_pos(int fd, fs_off_t _pos, struct iovec *iov, int count);
ssize_t writev_pos(int fd, fs_off_t _pos, struct iovec *iov, int count);
#endif /* __BEOS__ */
void panic(const char *msg, ...);
int device_is_read_only(const char *device);
int get_device_block_size(int fd);
fs_off_t get_num_device_blocks(int fd);
int device_is_removeable(int fd);
int lock_removeable_device(int fd, bool on_or_off);
void hexdump(void *address, int size);
#endif /* _COMPAT_H */

View File

@ -1,20 +1,19 @@
// kernel_emu.cpp
#include "kernel_emu.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <fsproto.h>
#include <KernelExport.h>
#include <OS.h>
#include "RequestPort.h"
#include "Requests.h"
#include "RequestThread.h"
#include "UserlandFSServer.h"
#include "UserlandRequestHandler.h"
// Taken from the OBOS Storage Kit (storage_support.cpp)
// Taken from the Haiku Storage Kit (storage_support.cpp)
/*! The length of the first component is returned as well as the index at
which the next one starts. These values are only valid, if the function
returns \c B_OK.
@ -25,8 +24,7 @@
written into. \c 0 is returned, if there is no next component.
\return \c B_OK, if \a path is not \c NULL, \c B_BAD_VALUE otherwise
*/
static
status_t
static status_t
parse_first_path_component(const char *path, int32& length,
int32& nextComponent)
{
@ -51,7 +49,7 @@ parse_first_path_component(const char *path, int32& length,
// new_path
int
new_path(const char *path, char **copy)
UserlandFS::KernelEmu::new_path(const char *path, char **copy)
{
// check errors and special cases
if (!copy)
@ -96,7 +94,7 @@ new_path(const char *path, char **copy)
// free_path
void
free_path(char *p)
UserlandFS::KernelEmu::free_path(char *p)
{
free(p);
}
@ -104,8 +102,7 @@ free_path(char *p)
// #pragma mark -
// get_port_and_fs
static
status_t
static status_t
get_port_and_fs(RequestPort** port, FileSystem** fileSystem)
{
// get the request thread
@ -124,8 +121,8 @@ get_port_and_fs(RequestPort** port, FileSystem** fileSystem)
// notify_listener
int
notify_listener(int op, nspace_id nsid, vnode_id vnida, vnode_id vnidb,
vnode_id vnidc, const char *name)
UserlandFS::KernelEmu::notify_listener(int op, mount_id nsid, vnode_id vnida,
vnode_id vnidb, vnode_id vnidc, const char *name)
{
// get the request port and the file system
RequestPort* port;
@ -162,7 +159,7 @@ notify_listener(int op, nspace_id nsid, vnode_id vnida, vnode_id vnidb,
// notify_select_event
void
notify_select_event(selectsync *sync, uint32 ref)
UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref)
{
// get the request port and the file system
RequestPort* port;
@ -190,9 +187,9 @@ notify_select_event(selectsync *sync, uint32 ref)
// send_notification
int
send_notification(port_id targetPort, long token, ulong what, long op,
nspace_id nsida, nspace_id nsidb, vnode_id vnida, vnode_id vnidb,
vnode_id vnidc, const char *name)
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)
{
// get the request port and the file system
RequestPort* port;
@ -234,9 +231,8 @@ send_notification(port_id targetPort, long token, ulong what, long op,
// #pragma mark -
// get_vnode
_EXPORT
int
get_vnode(nspace_id nsid, vnode_id vnid, void** data)
UserlandFS::KernelEmu::get_vnode(mount_id nsid, vnode_id vnid, void** data)
{
// get the request port and the file system
RequestPort* port;
@ -267,9 +263,8 @@ get_vnode(nspace_id nsid, vnode_id vnid, void** data)
}
// put_vnode
_EXPORT
int
put_vnode(nspace_id nsid, vnode_id vnid)
UserlandFS::KernelEmu::put_vnode(mount_id nsid, vnode_id vnid)
{
// get the request port and the file system
RequestPort* port;
@ -299,9 +294,8 @@ put_vnode(nspace_id nsid, vnode_id vnid)
}
// new_vnode
_EXPORT
int
new_vnode(nspace_id nsid, vnode_id vnid, void* data)
UserlandFS::KernelEmu::new_vnode(mount_id nsid, vnode_id vnid, void* data)
{
// get the request port and the file system
RequestPort* port;
@ -332,9 +326,8 @@ new_vnode(nspace_id nsid, vnode_id vnid, void* data)
}
// remove_vnode
_EXPORT
int
remove_vnode(nspace_id nsid, vnode_id vnid)
UserlandFS::KernelEmu::remove_vnode(mount_id nsid, vnode_id vnid)
{
// get the request port and the file system
RequestPort* port;
@ -364,9 +357,8 @@ remove_vnode(nspace_id nsid, vnode_id vnid)
}
// unremove_vnode
_EXPORT
int
unremove_vnode(nspace_id nsid, vnode_id vnid)
UserlandFS::KernelEmu::unremove_vnode(mount_id nsid, vnode_id vnid)
{
// get the request port and the file system
RequestPort* port;
@ -396,9 +388,8 @@ unremove_vnode(nspace_id nsid, vnode_id vnid)
}
// is_vnode_removed
_EXPORT
int
is_vnode_removed(nspace_id nsid, vnode_id vnid)
UserlandFS::KernelEmu::is_vnode_removed(mount_id nsid, vnode_id vnid)
{
// get the request port and the file system
RequestPort* port;
@ -430,17 +421,15 @@ is_vnode_removed(nspace_id nsid, vnode_id vnid)
// #pragma mark -
// kernel_debugger
_EXPORT
void
kernel_debugger(const char *message)
UserlandFS::KernelEmu::kernel_debugger(const char *message)
{
debugger(message);
}
// panic
_EXPORT
void
panic(const char *format, ...)
UserlandFS::KernelEmu::panic(const char *format, ...)
{
char buffer[1024];
strcpy(buffer, "PANIC: ");
@ -460,42 +449,38 @@ panic(const char *format, ...)
}
// parse_expression
_EXPORT
ulong
parse_expression(char *str)
{
return 0;
}
//ulong
//parse_expression(char *str)
//{
// return 0;
//}
// add_debugger_command
_EXPORT
int
add_debugger_command(char *name, int (*func)(int argc, char **argv),
char *help)
UserlandFS::KernelEmu::add_debugger_command(char *name,
int (*func)(int argc, char **argv), char *help)
{
return B_OK;
}
// remove_debugger_command
_EXPORT
int
remove_debugger_command(char *name, int (*func)(int argc, char **argv))
UserlandFS::KernelEmu::remove_debugger_command(char *name,
int (*func)(int argc, char **argv))
{
return B_OK;
}
// kprintf
_EXPORT
void
kprintf(const char *format, ...)
{
}
//void
//kprintf(const char *format, ...)
//{
//}
// spawn_kernel_thread
thread_id
spawn_kernel_thread(thread_entry function, const char *threadName,
long priority, void *arg)
UserlandFS::KernelEmu::spawn_kernel_thread(thread_entry function,
const char *threadName, long priority, void *arg)
{
return spawn_thread(function, threadName, priority, arg);
}

View File

@ -0,0 +1,40 @@
// kernel_emu.h
#include <fs_interface.h>
#include <KernelExport.h>
#include <OS.h>
namespace UserlandFS {
namespace KernelEmu {
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,
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,
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);
void kernel_debugger(const char *message);
void panic(const char *format, ...);
int add_debugger_command(char *name, int (*func)(int argc, char **argv),
char *help);
int remove_debugger_command(char *name, int (*func)(int argc, char **argv));
thread_id spawn_kernel_thread(thread_entry function, const char *threadName,
long priority, void *arg);
} // namespace KernelEmu
} // namespace UserlandFS

View File

@ -6,11 +6,11 @@
#include "Debug.h"
#include "ServerDefs.h"
#include "UserlandFSDispatcher.h"
#include "UserlandFSServer.h"
//#include "UserlandFSServer.h"
// server signature
static const char* kServerSignature
= "application/x-vnd.bonefish.userlandfs-server";
= "application/x-vnd.haiku.userlandfs-server";
// usage
static const char* kUsage =
@ -46,15 +46,16 @@ main(int argc, char** argv)
{
kArgC = argc;
kArgV = argv;
// init debugging
init_debugging();
struct DebuggingExiter {
DebuggingExiter() {}
~DebuggingExiter() { exit_debugging(); }
} _;
// parse arguments
int argi = 1;
// parse options
for (; argi < argc; argi++) {
const char* arg = argv[argi];
int32 argLen = strlen(arg);
@ -71,6 +72,7 @@ main(int argc, char** argv)
gServerSettings.SetEnterDebugger(true);
}
}
// get file system, if any
bool dispatcher = true;
const char* fileSystem = NULL;
@ -82,6 +84,7 @@ main(int argc, char** argv)
print_usage();
return 1;
}
// create and init the application
BApplication* app = NULL;
status_t error = B_OK;
@ -95,19 +98,19 @@ main(int argc, char** argv)
error = dispatcher->Init();
app = dispatcher;
} else {
UserlandFSServer* server
= new(nothrow) UserlandFSServer(kServerSignature);
if (!server) {
fprintf(stderr, "Failed to create server.\n");
return 1;
}
error = server->Init(fileSystem);
app = server;
// UserlandFSServer* server
// = new(nothrow) UserlandFSServer(kServerSignature);
// if (!server) {
// fprintf(stderr, "Failed to create server.\n");
// return 1;
// }
// error = server->Init(fileSystem);
// app = server;
}
// run it, if everything went fine
if (error == B_OK)
app->Run();
delete app;
return 0;
}

View File

@ -1,350 +0,0 @@
/*
This file contains some routines that are #ifdef'ed based on what
system you're on. Currently it supports the BeOS and Unix. It
could be extended to support Windows NT but their posix support
is such a joke that it would probably be a real pain in the arse.
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
Dominic Giampaolo
dbg@be.com
*/
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include "compat.h"
int
device_is_read_only(const char *device)
{
#ifdef unix
return 0; /* XXXdbg should do an ioctl or something */
#else
int fd;
device_geometry dg;
fd = open(device, O_RDONLY);
if (ioctl(fd, B_GET_GEOMETRY, &dg) < 0)
return 0;
close(fd);
return dg.read_only;
#endif
}
int
get_device_block_size(int fd)
{
#ifdef unix
return 512; /* XXXdbg should do an ioctl or something */
#else
struct stat st;
device_geometry dg;
if (ioctl(fd, B_GET_GEOMETRY, &dg) < 0) {
if (fstat(fd, &st) < 0 || S_ISDIR(st.st_mode))
return 0;
return 512; /* just assume it's a plain old file or something */
}
return dg.bytes_per_sector;
#endif
}
fs_off_t
get_num_device_blocks(int fd)
{
#ifdef unix
struct stat st;
fstat(fd, &st); /* XXXdbg should be an ioctl or something */
return st.st_size / get_device_block_size(fd);
#else
struct stat st;
device_geometry dg;
if (ioctl(fd, B_GET_GEOMETRY, &dg) >= 0) {
return (fs_off_t)dg.cylinder_count *
(fs_off_t)dg.sectors_per_track *
(fs_off_t)dg.head_count;
}
/* if the ioctl fails, try just stat'ing in case it's a regular file */
if (fstat(fd, &st) < 0)
return 0;
return st.st_size / get_device_block_size(fd);
#endif
}
int
device_is_removeable(int fd)
{
#ifdef unix
return 0; /* XXXdbg should do an ioctl or something */
#else
device_geometry dg;
if (ioctl(fd, B_GET_GEOMETRY, &dg) < 0) {
return 0;
}
return dg.removable;
#endif
}
#if defined(__BEOS__) && !defined(USER)
#include "scsi.h"
#endif
int
lock_removeable_device(int fd, bool on_or_off)
{
#if defined(unix) || defined(USER)
return 0; /* XXXdbg should do an ioctl or something */
#else
return ioctl(fd, B_SCSI_PREVENT_ALLOW, &on_or_off);
#endif
}
#ifndef __BEOS__
ssize_t
read_pos(int fd, fs_off_t _pos, void *data, size_t nbytes)
{
off_t pos = (off_t)_pos;
size_t ret;
if (lseek(fd, pos, SEEK_SET) < 0) {
perror("read lseek");
return EINVAL;
}
ret = read(fd, data, nbytes);
if (ret != nbytes) {
printf("read_pos: wanted %d, got %d\n", nbytes, ret);
return -1;
}
return ret;
}
ssize_t
write_pos(int fd, fs_off_t _pos, const void *data, size_t nbytes)
{
off_t pos = (off_t)_pos;
size_t ret;
if (lseek(fd, pos, SEEK_SET) < 0) {
perror("read lseek");
return EINVAL;
}
ret = write(fd, data, nbytes);
if (ret != nbytes) {
printf("write_pos: wanted %d, got %d\n", nbytes, ret);
return -1;
}
return ret;
}
#ifdef sun /* bloody wankers */
#include <sys/stream.h>
#ifdef DEF_IOV_MAX
#define MAX_IOV DEF_IOV_MAX
#else
#define MAX_IOV 16
#endif
#else /* the rest of the world... */
#define MAX_IOV 8192 /* something way bigger than we'll ever use */
#endif
ssize_t
readv_pos(int fd, fs_off_t _pos, struct iovec *iov, int count)
{
off_t pos = (off_t)_pos;
size_t amt = 0;
ssize_t ret;
struct iovec *tmpiov;
int i, n;
if (lseek(fd, pos, SEEK_SET) < 0) {
perror("read lseek");
return EINVAL;
}
i = 0;
tmpiov = iov;
while (i < count) {
if (i + MAX_IOV < count)
n = MAX_IOV;
else
n = (count - i);
ret = readv(fd, tmpiov, n);
amt += ret;
if (ret < 0)
break;
i += n;
tmpiov += n;
}
return amt;
}
ssize_t
writev_pos(int fd, fs_off_t _pos, struct iovec *iov, int count)
{
off_t pos = (off_t)_pos;
size_t amt = 0;
ssize_t ret;
struct iovec *tmpiov;
int i, n;
if (lseek(fd, pos, SEEK_SET) < 0) {
perror("read lseek");
return EINVAL;
}
i = 0;
tmpiov = iov;
while (i < count) {
if (i + MAX_IOV < count)
n = MAX_IOV;
else
n = (count - i);
ret = writev(fd, tmpiov, n);
amt += ret;
if (ret < 0)
break;
i += n;
tmpiov += n;
}
return amt;
}
#endif /* __BEOS__ */
#include <stdarg.h>
#if 0 // bonefish
void
panic(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
while (TRUE)
;
}
#endif
#include "lock.h"
int
new_lock(lock *l, const char *name)
{
l->c = 1;
l->s = create_sem(0, (char *)name);
if (l->s <= 0)
return l->s;
return 0;
}
int
free_lock(lock *l)
{
delete_sem(l->s);
return 0;
}
int
new_mlock(mlock *l, long c, const char *name)
{
l->s = create_sem(c, (char *)name);
if (l->s <= 0)
return l->s;
return 0;
}
int
free_mlock(mlock *l)
{
delete_sem(l->s);
return 0;
}
#ifdef unix
#include <sys/time.h>
bigtime_t
system_time(void)
{
bigtime_t t;
struct timeval tv;
gettimeofday(&tv, NULL);
t = ((bigtime_t)tv.tv_sec * 1000000) + (bigtime_t)tv.tv_usec;
return t;
}
/*
If you're compiler/system can't deal with the version of system_time()
as defined above, use this one instead
bigtime_t
system_time(void)
{
return (bigtime_t)time(NULL);
}
*/
#endif /* unix */
#ifdef __BEOS__
#include <KernelExport.h>
void
dprintf(const char *format, ...)
{
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
#endif