* 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:
parent
8474904ee0
commit
ca6faf4958
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -5,6 +5,11 @@
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
namespace UserlandFSUtil {
|
||||
class RequestPort;
|
||||
}
|
||||
using UserlandFSUtil::RequestPort;
|
||||
|
||||
namespace UserlandFS {
|
||||
|
||||
class FileSystem;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
@ -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 */
|
@ -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 */
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
@ -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 */
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user