2007-02-26 16:26:02 +00:00
|
|
|
// BeOSKernelVolume.cpp
|
2007-02-24 00:30:19 +00:00
|
|
|
|
2007-02-26 16:26:02 +00:00
|
|
|
#include "BeOSKernelVolume.h"
|
2007-02-24 00:30:19 +00:00
|
|
|
|
2007-03-01 01:16:13 +00:00
|
|
|
#include <new>
|
|
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
#include "beos_fs_interface.h"
|
2007-03-02 01:45:58 +00:00
|
|
|
#include "Debug.h"
|
2007-02-28 04:54:13 +00:00
|
|
|
#include "kernel_emu.h"
|
|
|
|
|
|
2007-03-01 01:16:13 +00:00
|
|
|
|
|
|
|
|
using std::nothrow;
|
|
|
|
|
|
|
|
|
|
static int open_mode_to_access(int openMode);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// AttributeCookie
|
|
|
|
|
class BeOSKernelVolume::AttributeCookie {
|
|
|
|
|
public:
|
|
|
|
|
AttributeCookie(const char* name, uint32 type, int openMode, bool exists,
|
|
|
|
|
bool create)
|
|
|
|
|
: fType(type),
|
|
|
|
|
fOpenMode(openMode),
|
|
|
|
|
fExists(exists),
|
|
|
|
|
fCreate(create)
|
|
|
|
|
{
|
|
|
|
|
strcpy(fName, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char fName[B_ATTR_NAME_LENGTH];
|
|
|
|
|
uint32 fType;
|
|
|
|
|
int fOpenMode;
|
|
|
|
|
bool fExists;
|
|
|
|
|
bool fCreate;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// constructor
|
2007-06-21 19:50:57 +00:00
|
|
|
BeOSKernelVolume::BeOSKernelVolume(FileSystem* fileSystem, dev_t id,
|
2007-02-28 04:54:13 +00:00
|
|
|
beos_vnode_ops* fsOps)
|
2007-02-26 16:26:02 +00:00
|
|
|
: Volume(fileSystem, id),
|
2007-02-24 00:30:19 +00:00
|
|
|
fFSOps(fsOps),
|
|
|
|
|
fVolumeCookie(NULL)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// destructor
|
2007-02-26 16:26:02 +00:00
|
|
|
BeOSKernelVolume::~BeOSKernelVolume()
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
// #pragma mark ----- FS -----
|
|
|
|
|
|
|
|
|
|
// Mount
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::Mount(const char* device, uint32 flags,
|
2007-06-21 19:50:57 +00:00
|
|
|
const char* parameters, ino_t* rootID)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->mount)
|
|
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
size_t len = (parameters ? strlen(parameters) : 0);
|
2007-02-24 00:30:19 +00:00
|
|
|
return fFSOps->mount(GetID(), device, flags, (void*)parameters, len,
|
|
|
|
|
&fVolumeCookie, rootID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Unmount
|
|
|
|
|
status_t
|
2007-02-26 16:26:02 +00:00
|
|
|
BeOSKernelVolume::Unmount()
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->unmount)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->unmount(fVolumeCookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sync
|
|
|
|
|
status_t
|
2007-02-26 16:26:02 +00:00
|
|
|
BeOSKernelVolume::Sync()
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->sync)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->sync(fVolumeCookie);
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// ReadFSInfo
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::ReadFSInfo(fs_info* info)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->rfsstat)
|
|
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
// Haiku's fs_info equals BeOS's version
|
|
|
|
|
return fFSOps->rfsstat(fVolumeCookie, (beos_fs_info*)info);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// WriteFSInfo
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::WriteFSInfo(const struct fs_info* info, uint32 mask)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->wfsstat)
|
|
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
// Haiku's fs_info equals BeOS's version
|
|
|
|
|
return fFSOps->wfsstat(fVolumeCookie, (beos_fs_info*)info, (long)mask);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
// #pragma mark - vnodes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Lookup
|
|
|
|
|
status_t
|
2007-06-21 19:50:57 +00:00
|
|
|
BeOSKernelVolume::Lookup(fs_vnode dir, const char* entryName, ino_t* vnid,
|
2007-02-28 04:54:13 +00:00
|
|
|
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;
|
|
|
|
|
}
|
2007-02-24 00:30:19 +00:00
|
|
|
|
2007-04-03 04:40:54 +00:00
|
|
|
// LookupNoType
|
|
|
|
|
status_t
|
|
|
|
|
BeOSKernelVolume::LookupNoType(fs_vnode dir, const char* entryName,
|
2007-06-21 19:50:57 +00:00
|
|
|
ino_t* vnid)
|
2007-04-03 04:40:54 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->walk)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->walk(fVolumeCookie, dir, entryName, NULL, vnid);
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// ReadVNode
|
|
|
|
|
status_t
|
2007-06-21 19:50:57 +00:00
|
|
|
BeOSKernelVolume::ReadVNode(ino_t vnid, bool reenter, fs_vnode* node)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->read_vnode)
|
|
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
return fFSOps->read_vnode(fVolumeCookie, vnid, (char)reenter, node);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WriteVNode
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::WriteVNode(fs_vnode node, bool reenter)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->write_vnode)
|
|
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
return fFSOps->write_vnode(fVolumeCookie, node, (char)reenter);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RemoveVNode
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::RemoveVNode(fs_vnode node, bool reenter)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->remove_vnode)
|
|
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
return fFSOps->remove_vnode(fVolumeCookie, node, (char)reenter);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// #pragma mark - nodes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// IOCtl
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::IOCtl(fs_vnode node, fs_cookie cookie, uint32 command,
|
|
|
|
|
void* buffer, size_t size)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->ioctl)
|
2007-02-24 00:30:19 +00:00
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
return fFSOps->ioctl(fVolumeCookie, node, cookie, (int)command, buffer,
|
|
|
|
|
size);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// SetFlags
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::SetFlags(fs_vnode node, fs_cookie cookie, int flags)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->setflags)
|
2007-02-24 00:30:19 +00:00
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
return fFSOps->setflags(fVolumeCookie, node, cookie, flags);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// Select
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::Select(fs_vnode node, fs_cookie cookie, uint8 event,
|
|
|
|
|
uint32 ref, selectsync* sync)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->select) {
|
2007-03-02 00:41:09 +00:00
|
|
|
UserlandFS::KernelEmu::notify_select_event(sync, ref, event, false);
|
2007-02-28 04:54:13 +00:00
|
|
|
return B_OK;
|
|
|
|
|
}
|
|
|
|
|
return fFSOps->select(fVolumeCookie, node, cookie, event, ref, sync);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// Deselect
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::Deselect(fs_vnode node, fs_cookie cookie, uint8 event,
|
|
|
|
|
selectsync* sync)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->select || !fFSOps->deselect)
|
|
|
|
|
return B_OK;
|
|
|
|
|
return fFSOps->deselect(fVolumeCookie, node, cookie, event, sync);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// FSync
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::FSync(fs_vnode node)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->fsync)
|
2007-02-24 00:30:19 +00:00
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
return fFSOps->fsync(fVolumeCookie, node);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// ReadSymlink
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::ReadSymlink(fs_vnode node, char* buffer, size_t bufferSize,
|
|
|
|
|
size_t* bytesRead)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->readlink)
|
2007-02-24 00:30:19 +00:00
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
*bytesRead = bufferSize;
|
|
|
|
|
return fFSOps->readlink(fVolumeCookie, node, buffer, bytesRead);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// CreateSymlink
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::CreateSymlink(fs_vnode dir, const char* name,
|
|
|
|
|
const char* target, int mode)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->symlink)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
// TODO: Don't ignore mode?
|
|
|
|
|
return fFSOps->symlink(fVolumeCookie, dir, name, target);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// Link
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::Link(fs_vnode dir, const char* name, fs_vnode node)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->link)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->link(fVolumeCookie, dir, name, node);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// Unlink
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::Unlink(fs_vnode dir, const char* name)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->unlink)
|
2007-02-24 00:30:19 +00:00
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
return fFSOps->unlink(fVolumeCookie, dir, name);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// Rename
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::Rename(fs_vnode oldDir, const char* oldName, fs_vnode newDir,
|
|
|
|
|
const char* newName)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->rename)
|
2007-02-24 00:30:19 +00:00
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
return fFSOps->rename(fVolumeCookie, oldDir, oldName, newDir, newName);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// Access
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::Access(fs_vnode node, int mode)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->access)
|
2007-03-05 05:16:08 +00:00
|
|
|
return B_OK;
|
2007-02-28 04:54:13 +00:00
|
|
|
return fFSOps->access(fVolumeCookie, node, mode);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// ReadStat
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::ReadStat(fs_vnode node, struct stat* st)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->rstat)
|
2007-02-24 00:30:19 +00:00
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
// 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);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// WriteStat
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::WriteStat(fs_vnode node, const struct stat *st, uint32 mask)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
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);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
// #pragma mark - files
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Create
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::Create(fs_vnode dir, const char* name, int openMode, int mode,
|
2007-06-21 19:50:57 +00:00
|
|
|
fs_cookie* cookie, ino_t* vnid)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->create)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->create(fVolumeCookie, dir, name, openMode, mode, vnid,
|
|
|
|
|
cookie);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// Open
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::Open(fs_vnode node, int openMode, fs_cookie* cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->open)
|
2007-02-24 00:30:19 +00:00
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
return fFSOps->open(fVolumeCookie, node, openMode, cookie);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// Close
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::Close(fs_vnode node, fs_cookie cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->close)
|
|
|
|
|
return B_OK;
|
|
|
|
|
return fFSOps->close(fVolumeCookie, node, cookie);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// FreeCookie
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::FreeCookie(fs_vnode node, fs_cookie cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->free_cookie)
|
|
|
|
|
return B_OK;
|
|
|
|
|
return fFSOps->free_cookie(fVolumeCookie, node, cookie);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// Read
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::Read(fs_vnode node, fs_cookie cookie, off_t pos, void* buffer,
|
|
|
|
|
size_t bufferSize, size_t* bytesRead)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->read)
|
2007-02-24 00:30:19 +00:00
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
*bytesRead = bufferSize;
|
2007-02-28 04:54:13 +00:00
|
|
|
return fFSOps->read(fVolumeCookie, node, cookie, pos, buffer, bytesRead);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// Write
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::Write(fs_vnode node, fs_cookie cookie, off_t pos,
|
|
|
|
|
const void* buffer, size_t bufferSize, size_t* bytesWritten)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->write)
|
2007-02-24 00:30:19 +00:00
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
*bytesWritten = bufferSize;
|
|
|
|
|
return fFSOps->write(fVolumeCookie, node, cookie, pos, buffer,
|
|
|
|
|
bytesWritten);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// #pragma mark - directories
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// CreateDir
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::CreateDir(fs_vnode dir, const char* name, int mode,
|
2007-06-21 19:50:57 +00:00
|
|
|
ino_t *newDir)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->mkdir || !fFSOps->walk) // we need walk() too
|
2007-02-24 00:30:19 +00:00
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
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()
|
2007-06-21 19:50:57 +00:00
|
|
|
ino_t id;
|
2007-02-28 04:54:13 +00:00
|
|
|
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;
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// RemoveDir
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::RemoveDir(fs_vnode dir, const char* name)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->rmdir)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->rmdir(fVolumeCookie, dir, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// OpenDir
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::OpenDir(fs_vnode node, fs_cookie* cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->opendir)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->opendir(fVolumeCookie, node, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CloseDir
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::CloseDir(fs_vnode node, fs_vnode cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->closedir)
|
|
|
|
|
return B_OK;
|
|
|
|
|
return fFSOps->closedir(fVolumeCookie, node, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FreeDirCookie
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::FreeDirCookie(fs_vnode node, fs_vnode cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->free_dircookie)
|
|
|
|
|
return B_OK;
|
|
|
|
|
return fFSOps->free_dircookie(fVolumeCookie, node, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ReadDir
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::ReadDir(fs_vnode node, fs_vnode cookie, void* buffer,
|
|
|
|
|
size_t bufferSize, uint32 count, uint32* countRead)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->readdir)
|
|
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
*countRead = count;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
// Haiku's struct dirent equals BeOS's version
|
|
|
|
|
return fFSOps->readdir(fVolumeCookie, node, cookie, (long*)countRead,
|
|
|
|
|
(beos_dirent*)buffer, bufferSize);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RewindDir
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::RewindDir(fs_vnode node, fs_vnode cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->rewinddir)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->rewinddir(fVolumeCookie, node, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// #pragma mark - attribute directories
|
|
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
|
|
|
|
|
// OpenAttrDir
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::OpenAttrDir(fs_vnode node, fs_cookie *cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->open_attrdir)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->open_attrdir(fVolumeCookie, node, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CloseAttrDir
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::CloseAttrDir(fs_vnode node, fs_cookie cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->close_attrdir)
|
|
|
|
|
return B_OK;
|
|
|
|
|
return fFSOps->close_attrdir(fVolumeCookie, node, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FreeAttrDirCookie
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::FreeAttrDirCookie(fs_vnode node, fs_cookie cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->free_attrdircookie)
|
|
|
|
|
return B_OK;
|
|
|
|
|
return fFSOps->free_attrdircookie(fVolumeCookie, node, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ReadAttrDir
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::ReadAttrDir(fs_vnode node, fs_cookie cookie, void* buffer,
|
|
|
|
|
size_t bufferSize, uint32 count, uint32* countRead)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->read_attrdir)
|
|
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
*countRead = count;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
// Haiku's struct dirent equals BeOS's version
|
|
|
|
|
return fFSOps->read_attrdir(fVolumeCookie, node, cookie, (long*)countRead,
|
|
|
|
|
(struct beos_dirent*)buffer, bufferSize);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RewindAttrDir
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::RewindAttrDir(fs_vnode node, fs_cookie cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->rewind_attrdir)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->rewind_attrdir(fVolumeCookie, node, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
// #pragma mark - attributes
|
|
|
|
|
|
|
|
|
|
|
2007-03-01 01:16:13 +00:00
|
|
|
// CreateAttr
|
|
|
|
|
status_t
|
|
|
|
|
BeOSKernelVolume::CreateAttr(fs_vnode node, const char* name, uint32 type,
|
|
|
|
|
int openMode, fs_cookie* cookie)
|
|
|
|
|
{
|
|
|
|
|
return _OpenAttr(node, name, type, openMode, true, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// OpenAttr
|
|
|
|
|
status_t
|
|
|
|
|
BeOSKernelVolume::OpenAttr(fs_vnode node, const char* name, int openMode,
|
|
|
|
|
fs_cookie* cookie)
|
|
|
|
|
{
|
|
|
|
|
return _OpenAttr(node, name, 0, openMode, false, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CloseAttr
|
|
|
|
|
status_t
|
|
|
|
|
BeOSKernelVolume::CloseAttr(fs_vnode node, fs_cookie cookie)
|
|
|
|
|
{
|
|
|
|
|
return B_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FreeAttrCookie
|
|
|
|
|
status_t
|
|
|
|
|
BeOSKernelVolume::FreeAttrCookie(fs_vnode node, fs_cookie _cookie)
|
|
|
|
|
{
|
|
|
|
|
AttributeCookie* cookie = (AttributeCookie*)_cookie;
|
|
|
|
|
|
|
|
|
|
// If the attribute doesn't exist yet and it was opened with
|
|
|
|
|
// CreateAttr(), we could create it now. We have a race condition here
|
|
|
|
|
// though, since someone else could have created it in the meantime.
|
|
|
|
|
|
|
|
|
|
delete cookie;
|
|
|
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// ReadAttr
|
|
|
|
|
status_t
|
2007-03-01 01:16:13 +00:00
|
|
|
BeOSKernelVolume::ReadAttr(fs_vnode node, fs_cookie _cookie, off_t pos,
|
2007-02-24 00:30:19 +00:00
|
|
|
void* buffer, size_t bufferSize, size_t* bytesRead)
|
|
|
|
|
{
|
2007-03-01 01:16:13 +00:00
|
|
|
AttributeCookie* cookie = (AttributeCookie*)_cookie;
|
|
|
|
|
|
|
|
|
|
// check, if open mode allows reading
|
|
|
|
|
if ((open_mode_to_access(cookie->fOpenMode) | R_OK) == 0)
|
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
|
|
|
|
|
// read
|
|
|
|
|
if (!fFSOps->read_attr)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
|
|
*bytesRead = bufferSize;
|
|
|
|
|
return fFSOps->read_attr(fVolumeCookie, node, cookie->fName, cookie->fType,
|
|
|
|
|
buffer, bytesRead, pos);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WriteAttr
|
|
|
|
|
status_t
|
2007-03-01 01:16:13 +00:00
|
|
|
BeOSKernelVolume::WriteAttr(fs_vnode node, fs_cookie _cookie, off_t pos,
|
2007-02-24 00:30:19 +00:00
|
|
|
const void* buffer, size_t bufferSize, size_t* bytesWritten)
|
|
|
|
|
{
|
2007-03-01 01:16:13 +00:00
|
|
|
AttributeCookie* cookie = (AttributeCookie*)_cookie;
|
|
|
|
|
|
|
|
|
|
// check, if open mode allows writing
|
|
|
|
|
if ((open_mode_to_access(cookie->fOpenMode) | W_OK) == 0)
|
|
|
|
|
return B_FILE_ERROR;
|
|
|
|
|
|
|
|
|
|
// write
|
|
|
|
|
if (!fFSOps->write_attr)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
|
|
*bytesWritten = bufferSize;
|
|
|
|
|
return fFSOps->write_attr(fVolumeCookie, node, cookie->fName, cookie->fType,
|
|
|
|
|
buffer, bytesWritten, pos);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// ReadAttrStat
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-03-01 01:16:13 +00:00
|
|
|
BeOSKernelVolume::ReadAttrStat(fs_vnode node, fs_cookie _cookie,
|
|
|
|
|
struct stat *st)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-03-01 01:16:13 +00:00
|
|
|
AttributeCookie* cookie = (AttributeCookie*)_cookie;
|
|
|
|
|
|
|
|
|
|
// get the stats
|
|
|
|
|
beos_attr_info attrInfo;
|
|
|
|
|
if (!fFSOps->stat_attr)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
|
|
status_t error = fFSOps->stat_attr(fVolumeCookie, node, cookie->fName,
|
|
|
|
|
&attrInfo);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
// translate to struct stat
|
|
|
|
|
st->st_size = attrInfo.size;
|
|
|
|
|
st->st_type = attrInfo.type;
|
|
|
|
|
|
|
|
|
|
return B_OK;
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RenameAttr
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::RenameAttr(fs_vnode oldNode, const char* oldName,
|
|
|
|
|
fs_vnode newNode, const char* newName)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->rename_attr)
|
|
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
if (oldNode != newNode)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
|
|
return fFSOps->rename_attr(fVolumeCookie, oldNode, oldName, newName);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
// RemoveAttr
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::RemoveAttr(fs_vnode node, const char* name)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
2007-02-28 04:54:13 +00:00
|
|
|
if (!fFSOps->remove_attr)
|
2007-02-24 00:30:19 +00:00
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
return fFSOps->remove_attr(fVolumeCookie, node, name);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
// #pragma mark - indices
|
|
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
|
|
|
|
|
// OpenIndexDir
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::OpenIndexDir(fs_cookie *cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->open_indexdir)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->open_indexdir(fVolumeCookie, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CloseIndexDir
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::CloseIndexDir(fs_cookie cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->close_indexdir)
|
|
|
|
|
return B_OK;
|
|
|
|
|
return fFSOps->close_indexdir(fVolumeCookie, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FreeIndexDirCookie
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::FreeIndexDirCookie(fs_cookie cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->free_indexdircookie)
|
|
|
|
|
return B_OK;
|
|
|
|
|
return fFSOps->free_indexdircookie(fVolumeCookie, NULL, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ReadIndexDir
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::ReadIndexDir(fs_cookie cookie, void* buffer,
|
|
|
|
|
size_t bufferSize, uint32 count, uint32* countRead)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->read_indexdir)
|
|
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
*countRead = count;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
// Haiku's struct dirent equals BeOS's version
|
|
|
|
|
return fFSOps->read_indexdir(fVolumeCookie, cookie, (long*)countRead,
|
|
|
|
|
(struct beos_dirent*)buffer, bufferSize);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RewindIndexDir
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::RewindIndexDir(fs_cookie cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->rewind_indexdir)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->rewind_indexdir(fVolumeCookie, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CreateIndex
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::CreateIndex(const char* name, uint32 type, uint32 flags)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->create_index)
|
|
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
return fFSOps->create_index(fVolumeCookie, name, (int)type, (int)flags);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RemoveIndex
|
|
|
|
|
status_t
|
2007-02-26 16:26:02 +00:00
|
|
|
BeOSKernelVolume::RemoveIndex(const char* name)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->remove_index)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->remove_index(fVolumeCookie, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// StatIndex
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::ReadIndexStat(const char *name, struct stat *st)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->stat_index)
|
|
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
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;
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
// #pragma mark - queries
|
|
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
|
|
|
|
|
// OpenQuery
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::OpenQuery(const char* queryString, uint32 flags, port_id port,
|
|
|
|
|
uint32 token, fs_cookie *cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->open_query)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
return fFSOps->open_query(fVolumeCookie, queryString, flags, port,
|
2007-02-28 04:54:13 +00:00
|
|
|
(long)token, cookie);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CloseQuery
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::CloseQuery(fs_cookie cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->close_query)
|
|
|
|
|
return B_OK;
|
|
|
|
|
return fFSOps->close_query(fVolumeCookie, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FreeQueryCookie
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::FreeQueryCookie(fs_cookie cookie)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->free_querycookie)
|
|
|
|
|
return B_OK;
|
|
|
|
|
return fFSOps->free_querycookie(fVolumeCookie, NULL, cookie);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ReadQuery
|
|
|
|
|
status_t
|
2007-02-28 04:54:13 +00:00
|
|
|
BeOSKernelVolume::ReadQuery(fs_cookie cookie, void* buffer, size_t bufferSize,
|
|
|
|
|
uint32 count, uint32* countRead)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
if (!fFSOps->read_query)
|
|
|
|
|
return B_BAD_VALUE;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
*countRead = count;
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
// Haiku's struct dirent equals BeOS's version
|
|
|
|
|
return fFSOps->read_query(fVolumeCookie, cookie, (long*)countRead,
|
|
|
|
|
(struct beos_dirent*)buffer, bufferSize);
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-03-01 01:16:13 +00:00
|
|
|
|
|
|
|
|
// #pragma mark - Private
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// _OpenAttr
|
|
|
|
|
status_t
|
|
|
|
|
BeOSKernelVolume::_OpenAttr(fs_vnode node, const char* name, uint32 type,
|
|
|
|
|
int openMode, bool create, fs_cookie* _cookie)
|
|
|
|
|
{
|
|
|
|
|
// check permissions first
|
|
|
|
|
int accessMode = open_mode_to_access(openMode) | (create ? W_OK : 0);
|
|
|
|
|
status_t error = Access(node, accessMode);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
// check whether the attribute already exists
|
|
|
|
|
beos_attr_info attrInfo;
|
|
|
|
|
if (!fFSOps->stat_attr)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
bool exists
|
|
|
|
|
= (fFSOps->stat_attr(fVolumeCookie, node, name, &attrInfo) == B_OK);
|
|
|
|
|
|
|
|
|
|
if (create) {
|
|
|
|
|
// create: fail, if attribute exists and non-existence was required
|
|
|
|
|
if (exists && (openMode & O_EXCL))
|
|
|
|
|
return B_FILE_EXISTS;
|
|
|
|
|
} else {
|
|
|
|
|
// open: fail, if attribute doesn't exist
|
|
|
|
|
if (!exists)
|
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
|
|
|
|
|
|
|
|
|
// keep the attribute type
|
|
|
|
|
type = attrInfo.type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// create an attribute cookie
|
|
|
|
|
AttributeCookie* cookie = new(nothrow) AttributeCookie(name, type,
|
|
|
|
|
openMode, exists, create);
|
|
|
|
|
if (!cookie)
|
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
|
|
|
|
|
// TODO: If we want to support O_TRUNC, we should do that here.
|
|
|
|
|
|
|
|
|
|
*_cookie = cookie;
|
|
|
|
|
return B_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// open_mode_to_access
|
|
|
|
|
static int
|
|
|
|
|
open_mode_to_access(int openMode)
|
|
|
|
|
{
|
|
|
|
|
switch (openMode & O_RWMASK) {
|
|
|
|
|
case O_RDONLY:
|
|
|
|
|
return R_OK;
|
|
|
|
|
case O_WRONLY:
|
|
|
|
|
return W_OK;
|
|
|
|
|
case O_RDWR:
|
|
|
|
|
default:
|
|
|
|
|
return W_OK | R_OK;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|