We analyze a client FS's capabilities -- i.e. which hooks it provides or
can be emulated -- and pass this info to the kernel add-on. Thus we can avoid passing requests to the userland that can't be serviced anyway. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20331 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
cf4ccd6575
commit
4e0e80ed6c
191
headers/private/userlandfs/private/FSCapabilities.h
Normal file
191
headers/private/userlandfs/private/FSCapabilities.h
Normal file
@ -0,0 +1,191 @@
|
||||
// FSCapabilities.h
|
||||
|
||||
#ifndef USERLAND_FS_FS_CAPABILITIES_H
|
||||
#define USERLAND_FS_FS_CAPABILITIES_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Debug.h"
|
||||
|
||||
enum client_fs_type {
|
||||
CLIENT_FS_BEOS_KERNEL = 0,
|
||||
CLIENT_FS_HAIKU_KERNEL,
|
||||
};
|
||||
|
||||
enum {
|
||||
// FS operations
|
||||
FS_CAPABILITY_MOUNT = 0,
|
||||
FS_CAPABILITY_UNMOUNT,
|
||||
|
||||
FS_CAPABILITY_READ_FS_INFO,
|
||||
FS_CAPABILITY_WRITE_FS_INFO,
|
||||
FS_CAPABILITY_SYNC,
|
||||
|
||||
// vnode operations
|
||||
FS_CAPABILITY_LOOKUP,
|
||||
FS_CAPABILITY_GET_VNODE_NAME,
|
||||
|
||||
FS_CAPABILITY_GET_VNODE,
|
||||
FS_CAPABILITY_PUT_VNODE,
|
||||
FS_CAPABILITY_REMOVE_VNODE,
|
||||
|
||||
// VM file access
|
||||
FS_CAPABILITY_CAN_PAGE,
|
||||
FS_CAPABILITY_READ_PAGES,
|
||||
FS_CAPABILITY_WRITE_PAGES,
|
||||
|
||||
// cache file access
|
||||
FS_CAPABILITY_GET_FILE_MAP,
|
||||
|
||||
// common operations
|
||||
FS_CAPABILITY_IOCTL,
|
||||
FS_CAPABILITY_SET_FLAGS,
|
||||
FS_CAPABILITY_SELECT,
|
||||
FS_CAPABILITY_DESELECT,
|
||||
FS_CAPABILITY_FSYNC,
|
||||
|
||||
FS_CAPABILITY_READ_SYMLINK,
|
||||
FS_CAPABILITY_CREATE_SYMLINK,
|
||||
|
||||
FS_CAPABILITY_LINK,
|
||||
FS_CAPABILITY_UNLINK,
|
||||
FS_CAPABILITY_RENAME,
|
||||
|
||||
FS_CAPABILITY_ACCESS,
|
||||
FS_CAPABILITY_READ_STAT,
|
||||
FS_CAPABILITY_WRITE_STAT,
|
||||
|
||||
// file operations
|
||||
FS_CAPABILITY_CREATE,
|
||||
FS_CAPABILITY_OPEN,
|
||||
FS_CAPABILITY_CLOSE,
|
||||
FS_CAPABILITY_FREE_COOKIE,
|
||||
FS_CAPABILITY_READ,
|
||||
FS_CAPABILITY_WRITE,
|
||||
|
||||
// directory operations
|
||||
FS_CAPABILITY_CREATE_DIR,
|
||||
FS_CAPABILITY_REMOVE_DIR,
|
||||
FS_CAPABILITY_OPEN_DIR,
|
||||
FS_CAPABILITY_CLOSE_DIR,
|
||||
FS_CAPABILITY_FREE_DIR_COOKIE,
|
||||
FS_CAPABILITY_READ_DIR,
|
||||
FS_CAPABILITY_REWIND_DIR,
|
||||
|
||||
// attribute directory operations
|
||||
FS_CAPABILITY_OPEN_ATTR_DIR,
|
||||
FS_CAPABILITY_CLOSE_ATTR_DIR,
|
||||
FS_CAPABILITY_FREE_ATTR_DIR_COOKIE,
|
||||
FS_CAPABILITY_READ_ATTR_DIR,
|
||||
FS_CAPABILITY_REWIND_ATTR_DIR,
|
||||
|
||||
// attribute operations
|
||||
FS_CAPABILITY_CREATE_ATTR,
|
||||
FS_CAPABILITY_OPEN_ATTR,
|
||||
FS_CAPABILITY_CLOSE_ATTR,
|
||||
FS_CAPABILITY_FREE_ATTR_COOKIE,
|
||||
FS_CAPABILITY_READ_ATTR,
|
||||
FS_CAPABILITY_WRITE_ATTR,
|
||||
|
||||
FS_CAPABILITY_READ_ATTR_STAT,
|
||||
FS_CAPABILITY_WRITE_ATTR_STAT,
|
||||
FS_CAPABILITY_RENAME_ATTR,
|
||||
FS_CAPABILITY_REMOVE_ATTR,
|
||||
|
||||
// index directory & index operations
|
||||
FS_CAPABILITY_OPEN_INDEX_DIR,
|
||||
FS_CAPABILITY_CLOSE_INDEX_DIR,
|
||||
FS_CAPABILITY_FREE_INDEX_DIR_COOKIE,
|
||||
FS_CAPABILITY_READ_INDEX_DIR,
|
||||
FS_CAPABILITY_REWIND_INDEX_DIR,
|
||||
|
||||
FS_CAPABILITY_CREATE_INDEX,
|
||||
FS_CAPABILITY_REMOVE_INDEX,
|
||||
FS_CAPABILITY_READ_INDEX_STAT,
|
||||
|
||||
// query operations
|
||||
FS_CAPABILITY_OPEN_QUERY,
|
||||
FS_CAPABILITY_CLOSE_QUERY,
|
||||
FS_CAPABILITY_FREE_QUERY_COOKIE,
|
||||
FS_CAPABILITY_READ_QUERY,
|
||||
FS_CAPABILITY_REWIND_QUERY,
|
||||
|
||||
FS_CAPABILITY_COUNT,
|
||||
};
|
||||
|
||||
|
||||
namespace UserlandFSUtil {
|
||||
|
||||
struct FSCapabilities {
|
||||
client_fs_type clientFSType;
|
||||
uint8 capabilities[(FS_CAPABILITY_COUNT + 7) / 8];
|
||||
|
||||
inline void ClearAll();
|
||||
|
||||
inline void Set(uint32 capability, bool set = true);
|
||||
inline void Clear(uint32 capability);
|
||||
inline bool Get(uint32 capability) const;
|
||||
|
||||
inline void Dump() const;
|
||||
};
|
||||
|
||||
// ClearAll
|
||||
inline void
|
||||
FSCapabilities::ClearAll()
|
||||
{
|
||||
memset(capabilities, 0, sizeof(capabilities));
|
||||
}
|
||||
|
||||
// Set
|
||||
inline void
|
||||
FSCapabilities::Set(uint32 capability, bool set)
|
||||
{
|
||||
if (capability >= FS_CAPABILITY_COUNT)
|
||||
return;
|
||||
|
||||
uint8 flag = uint8(1 << (capability % 8));
|
||||
if (set)
|
||||
capabilities[capability / 8] |= flag;
|
||||
else
|
||||
capabilities[capability / 8] &= ~flag;
|
||||
}
|
||||
|
||||
// Clear
|
||||
inline void
|
||||
FSCapabilities::Clear(uint32 capability)
|
||||
{
|
||||
Set(capability, false);
|
||||
}
|
||||
|
||||
// Get
|
||||
inline bool
|
||||
FSCapabilities::Get(uint32 capability) const
|
||||
{
|
||||
if (capability >= FS_CAPABILITY_COUNT)
|
||||
return false;
|
||||
|
||||
uint8 flag = uint8(1 << (capability % 8));
|
||||
return (capabilities[capability / 8] & flag);
|
||||
}
|
||||
|
||||
// Dump
|
||||
inline void
|
||||
FSCapabilities::Dump() const
|
||||
{
|
||||
D(
|
||||
char buffer[128];
|
||||
int byteCount = sizeof(capabilities);
|
||||
for (int i = 0; i < byteCount; i++)
|
||||
sprintf(buffer + 2 * i, "%02x", (int)capabilities[i]);
|
||||
|
||||
PRINT(("FSCapabilities[%d, %s]\n", clientFSType, buffer));
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
} // namespace UserlandFSUtil
|
||||
|
||||
using UserlandFSUtil::FSCapabilities;
|
||||
|
||||
#endif // USERLAND_FS_FS_CAPABILITIES_H
|
@ -9,6 +9,7 @@
|
||||
#include <fs_interface.h>
|
||||
|
||||
#include "Compatibility.h"
|
||||
#include "FSCapabilities.h"
|
||||
#include "Request.h"
|
||||
|
||||
|
||||
@ -304,8 +305,9 @@ public:
|
||||
FSConnectReply() : ReplyRequest(FS_CONNECT_REPLY) {}
|
||||
status_t GetAddressInfos(AddressInfo* infos, int32* count);
|
||||
|
||||
Address portInfos;
|
||||
int32 portInfoCount;
|
||||
Address portInfos;
|
||||
int32 portInfoCount;
|
||||
FSCapabilities capabilities;
|
||||
};
|
||||
|
||||
|
||||
|
@ -64,9 +64,11 @@ FileSystem::~FileSystem()
|
||||
|
||||
// Init
|
||||
status_t
|
||||
FileSystem::Init(const char* name, Port::Info* infos, int32 count)
|
||||
FileSystem::Init(const char* name, Port::Info* infos, int32 count,
|
||||
const FSCapabilities& capabilities)
|
||||
{
|
||||
PRINT(("FileSystem::Init(\"%s\", %p, %ld)\n", name, infos, infoCount));
|
||||
PRINT(("FileSystem::Init(\"%s\", %p, %ld)\n", name, infos, count));
|
||||
capabilities.Dump();
|
||||
|
||||
// check parameters
|
||||
if (!name || !infos || count < 2)
|
||||
@ -76,6 +78,8 @@ FileSystem::Init(const char* name, Port::Info* infos, int32 count)
|
||||
if (!fName.SetTo(name))
|
||||
return B_NO_MEMORY;
|
||||
|
||||
fCapabilities = capabilities;
|
||||
|
||||
// create the select sync entry map
|
||||
fSelectSyncs = new(nothrow) SelectSyncMap;
|
||||
if (!fSelectSyncs)
|
||||
@ -159,6 +163,13 @@ FileSystem::GetName() const
|
||||
return fName.GetString();
|
||||
}
|
||||
|
||||
// GetCapabilities
|
||||
const FSCapabilities&
|
||||
FileSystem::GetCapabilities() const
|
||||
{
|
||||
return fCapabilities;
|
||||
}
|
||||
|
||||
// GetPortPool
|
||||
RequestPortPool*
|
||||
FileSystem::GetPortPool()
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <fs_interface.h>
|
||||
|
||||
#include "FSCapabilities.h"
|
||||
#include "LazyInitializable.h"
|
||||
#include "Locker.h"
|
||||
#include "Referencable.h"
|
||||
@ -24,10 +25,14 @@ public:
|
||||
~FileSystem();
|
||||
|
||||
status_t Init(const char* name, Port::Info* infos,
|
||||
int32 infoCount);
|
||||
int32 infoCount,
|
||||
const FSCapabilities& capabilities);
|
||||
|
||||
const char* GetName() const;
|
||||
|
||||
const FSCapabilities& GetCapabilities() const;
|
||||
inline bool HasCapability(uint32 capability) const;
|
||||
|
||||
RequestPortPool* GetPortPool();
|
||||
|
||||
status_t Mount(mount_id id, const char* device,
|
||||
@ -59,6 +64,7 @@ private:
|
||||
Vector<Volume*> fVolumes;
|
||||
Locker fVolumeLock;
|
||||
String fName;
|
||||
FSCapabilities fCapabilities;
|
||||
RequestPort* fNotificationPort;
|
||||
thread_id fNotificationThread;
|
||||
RequestPortPool fPortPool;
|
||||
@ -69,4 +75,12 @@ private:
|
||||
volatile bool fTerminating;
|
||||
};
|
||||
|
||||
|
||||
// HasCapability
|
||||
inline bool
|
||||
FileSystem::HasCapability(uint32 capability) const
|
||||
{
|
||||
return fCapabilities.Get(capability);
|
||||
}
|
||||
|
||||
#endif // USERLAND_FS_FILE_SYSTEM_H
|
||||
|
@ -68,7 +68,7 @@ FileSystemInitializer::FirstTimeInit()
|
||||
if (!fFileSystem)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
error = fFileSystem->Init(fName, infos, count);
|
||||
error = fFileSystem->Init(fName, infos, count, reply->capabilities);
|
||||
if (error != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
|
@ -280,6 +280,10 @@ Volume::Unmount()
|
||||
status_t
|
||||
Volume::Sync()
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_SYNC))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -337,6 +341,10 @@ Volume::ReadFSInfo(fs_info* info)
|
||||
status_t
|
||||
Volume::WriteFSInfo(const struct fs_info *info, uint32 mask)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_WRITE_FS_INFO))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -574,6 +582,10 @@ Volume::IOCtl(fs_vnode node, fs_cookie cookie, uint32 command, void *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_IOCTL))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -630,6 +642,10 @@ Volume::IOCtl(fs_vnode node, fs_cookie cookie, uint32 command, void *buffer,
|
||||
status_t
|
||||
Volume::SetFlags(fs_vnode node, fs_cookie cookie, int flags)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_SET_FLAGS))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -667,6 +683,12 @@ status_t
|
||||
Volume::Select(fs_vnode node, fs_cookie cookie, uint8 event, uint32 ref,
|
||||
selectsync* sync)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_SELECT)) {
|
||||
notify_select_event(sync, ref, event);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -714,6 +736,10 @@ Volume::Select(fs_vnode node, fs_cookie cookie, uint8 event, uint32 ref,
|
||||
status_t
|
||||
Volume::Deselect(fs_vnode node, fs_cookie cookie, uint8 event, selectsync* sync)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_DESELECT))
|
||||
return B_OK;
|
||||
|
||||
struct SyncRemover {
|
||||
SyncRemover(FileSystem* fs, selectsync* sync)
|
||||
: fs(fs), sync(sync) {}
|
||||
@ -760,6 +786,10 @@ Volume::Deselect(fs_vnode node, fs_cookie cookie, uint8 event, selectsync* sync)
|
||||
status_t
|
||||
Volume::FSync(fs_vnode node)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_FSYNC))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -796,6 +826,11 @@ Volume::ReadSymlink(fs_vnode node, char* buffer, size_t bufferSize,
|
||||
size_t* bytesRead)
|
||||
{
|
||||
*bytesRead = 0;
|
||||
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_READ_SYMLINK))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -841,6 +876,10 @@ status_t
|
||||
Volume::CreateSymlink(fs_vnode dir, const char* name, const char* target,
|
||||
int mode)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_CREATE_SYMLINK))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -881,6 +920,10 @@ Volume::CreateSymlink(fs_vnode dir, const char* name, const char* target,
|
||||
status_t
|
||||
Volume::Link(fs_vnode dir, const char* name, fs_vnode node)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_LINK))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -919,6 +962,10 @@ Volume::Link(fs_vnode dir, const char* name, fs_vnode node)
|
||||
status_t
|
||||
Volume::Unlink(fs_vnode dir, const char* name)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_UNLINK))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -957,6 +1004,10 @@ status_t
|
||||
Volume::Rename(fs_vnode oldDir, const char* oldName, fs_vnode newDir,
|
||||
const char* newName)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_RENAME))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -997,6 +1048,10 @@ Volume::Rename(fs_vnode oldDir, const char* oldName, fs_vnode newDir,
|
||||
status_t
|
||||
Volume::Access(fs_vnode node, int mode)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_ACCESS))
|
||||
return B_OK;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1062,6 +1117,10 @@ Volume::ReadStat(fs_vnode node, struct stat* st)
|
||||
status_t
|
||||
Volume::WriteStat(fs_vnode node, const struct stat* st, uint32 mask)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_WRITE_STAT))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1102,6 +1161,10 @@ status_t
|
||||
Volume::Create(fs_vnode dir, const char* name, int openMode, int mode,
|
||||
void** cookie, vnode_id* vnid)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_CREATE))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1148,6 +1211,10 @@ Volume::Create(fs_vnode dir, const char* name, int openMode, int mode,
|
||||
status_t
|
||||
Volume::Open(fs_vnode node, int openMode, fs_cookie* cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_OPEN))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1223,6 +1290,10 @@ Volume::Read(fs_vnode node, fs_cookie cookie, off_t pos, void* buffer,
|
||||
{
|
||||
*bytesRead = 0;
|
||||
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_READ))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1272,6 +1343,10 @@ Volume::Write(fs_vnode node, fs_cookie cookie, off_t pos, const void* buffer,
|
||||
{
|
||||
*bytesWritten = 0;
|
||||
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_WRITE))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1315,6 +1390,10 @@ Volume::Write(fs_vnode node, fs_cookie cookie, off_t pos, const void* buffer,
|
||||
status_t
|
||||
Volume::CreateDir(fs_vnode dir, const char* name, int mode, vnode_id *newDir)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_CREATE_DIR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1354,6 +1433,10 @@ Volume::CreateDir(fs_vnode dir, const char* name, int mode, vnode_id *newDir)
|
||||
status_t
|
||||
Volume::RemoveDir(fs_vnode dir, const char* name)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_REMOVE_DIR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1391,6 +1474,10 @@ Volume::RemoveDir(fs_vnode dir, const char* name)
|
||||
status_t
|
||||
Volume::OpenDir(fs_vnode node, fs_cookie* cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_OPEN_DIR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1466,6 +1553,10 @@ Volume::ReadDir(fs_vnode node, fs_vnode cookie, void* buffer, size_t bufferSize,
|
||||
{
|
||||
*countRead = 0;
|
||||
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_READ_DIR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1521,6 +1612,10 @@ reply->buffer.GetSize()));
|
||||
status_t
|
||||
Volume::RewindDir(fs_vnode node, fs_vnode cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_REWIND_DIR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1560,6 +1655,10 @@ Volume::RewindDir(fs_vnode node, fs_vnode cookie)
|
||||
status_t
|
||||
Volume::OpenAttrDir(fs_vnode node, fs_cookie *cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_OPEN_ATTR_DIR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1635,6 +1734,10 @@ status_t
|
||||
Volume::ReadAttrDir(fs_vnode node, fs_cookie cookie, void* buffer,
|
||||
size_t bufferSize, uint32 count, uint32* countRead)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_READ_ATTR_DIR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
*countRead = 0;
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
@ -1689,6 +1792,10 @@ Volume::ReadAttrDir(fs_vnode node, fs_cookie cookie, void* buffer,
|
||||
status_t
|
||||
Volume::RewindAttrDir(fs_vnode node, fs_cookie cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_REWIND_ATTR_DIR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1728,6 +1835,10 @@ status_t
|
||||
Volume::CreateAttr(fs_vnode node, const char* name, uint32 type, int openMode,
|
||||
fs_cookie* cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_CREATE_ATTR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1771,6 +1882,10 @@ status_t
|
||||
Volume::OpenAttr(fs_vnode node, const char* name, int openMode,
|
||||
fs_cookie* cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_OPEN_ATTR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1851,6 +1966,10 @@ Volume::ReadAttr(fs_vnode node, fs_cookie cookie, off_t pos,
|
||||
{
|
||||
*bytesRead = 0;
|
||||
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_READ_ATTR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1900,6 +2019,10 @@ Volume::WriteAttr(fs_vnode node, fs_cookie cookie, off_t pos,
|
||||
{
|
||||
*bytesWritten = 0;
|
||||
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_WRITE_ATTR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1940,6 +2063,10 @@ Volume::WriteAttr(fs_vnode node, fs_cookie cookie, off_t pos,
|
||||
status_t
|
||||
Volume::ReadAttrStat(fs_vnode node, fs_cookie cookie, struct stat *st)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_READ_ATTR_STAT))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -1977,6 +2104,10 @@ status_t
|
||||
Volume::RenameAttr(fs_vnode oldNode, const char* oldName, fs_vnode newNode,
|
||||
const char* newName)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_RENAME_ATTR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2017,6 +2148,10 @@ Volume::RenameAttr(fs_vnode oldNode, const char* oldName, fs_vnode newNode,
|
||||
status_t
|
||||
Volume::RemoveAttr(fs_vnode node, const char* name)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_REMOVE_ATTR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2058,6 +2193,10 @@ Volume::RemoveAttr(fs_vnode node, const char* name)
|
||||
status_t
|
||||
Volume::OpenIndexDir(fs_cookie *cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_OPEN_INDEX_DIR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2134,6 +2273,10 @@ Volume::ReadIndexDir(fs_cookie cookie, void* buffer, size_t bufferSize,
|
||||
{
|
||||
*countRead = 0;
|
||||
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_READ_INDEX_DIR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2186,6 +2329,10 @@ Volume::ReadIndexDir(fs_cookie cookie, void* buffer, size_t bufferSize,
|
||||
status_t
|
||||
Volume::RewindIndexDir(fs_cookie cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_REWIND_INDEX_DIR))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2220,6 +2367,10 @@ Volume::RewindIndexDir(fs_cookie cookie)
|
||||
status_t
|
||||
Volume::CreateIndex(const char* name, uint32 type, uint32 flags)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_CREATE_INDEX))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2258,6 +2409,10 @@ Volume::CreateIndex(const char* name, uint32 type, uint32 flags)
|
||||
status_t
|
||||
Volume::RemoveIndex(const char* name)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_REMOVE_INDEX))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2294,6 +2449,10 @@ Volume::RemoveIndex(const char* name)
|
||||
status_t
|
||||
Volume::ReadIndexStat(const char* name, struct stat *st)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_READ_INDEX_STAT))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2336,6 +2495,10 @@ status_t
|
||||
Volume::OpenQuery(const char* queryString, uint32 flags, port_id targetPort,
|
||||
uint32 token, fs_cookie *cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_OPEN_QUERY))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2417,6 +2580,10 @@ Volume::ReadQuery(fs_cookie cookie, void* buffer, size_t bufferSize,
|
||||
{
|
||||
*countRead = 0;
|
||||
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_READ_QUERY))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2560,6 +2727,10 @@ Volume::_Unmount()
|
||||
status_t
|
||||
Volume::_ReadFSInfo(fs_info* info)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_READ_FS_INFO))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2669,6 +2840,10 @@ Volume::_WriteVNode(fs_vnode node, bool reenter)
|
||||
status_t
|
||||
Volume::_ReadStat(fs_vnode node, struct stat* st)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_READ_STAT))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2704,6 +2879,10 @@ Volume::_ReadStat(fs_vnode node, struct stat* st)
|
||||
status_t
|
||||
Volume::_Close(fs_vnode node, fs_cookie cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_CLOSE))
|
||||
return B_OK;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2739,6 +2918,10 @@ Volume::_Close(fs_vnode node, fs_cookie cookie)
|
||||
status_t
|
||||
Volume::_FreeCookie(fs_vnode node, fs_cookie cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_FREE_COOKIE))
|
||||
return B_OK;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2774,6 +2957,10 @@ Volume::_FreeCookie(fs_vnode node, fs_cookie cookie)
|
||||
status_t
|
||||
Volume::_CloseDir(fs_vnode node, fs_vnode cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_CLOSE_DIR))
|
||||
return B_OK;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2809,6 +2996,10 @@ Volume::_CloseDir(fs_vnode node, fs_vnode cookie)
|
||||
status_t
|
||||
Volume::_FreeDirCookie(fs_vnode node, fs_vnode cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_FREE_DIR_COOKIE))
|
||||
return B_OK;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2844,6 +3035,10 @@ Volume::_FreeDirCookie(fs_vnode node, fs_vnode cookie)
|
||||
status_t
|
||||
Volume::_CloseAttrDir(fs_vnode node, fs_cookie cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_CLOSE_ATTR_DIR))
|
||||
return B_OK;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2879,6 +3074,10 @@ Volume::_CloseAttrDir(fs_vnode node, fs_cookie cookie)
|
||||
status_t
|
||||
Volume::_FreeAttrDirCookie(fs_vnode node, fs_cookie cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_FREE_ATTR_DIR_COOKIE))
|
||||
return B_OK;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2914,6 +3113,10 @@ Volume::_FreeAttrDirCookie(fs_vnode node, fs_cookie cookie)
|
||||
status_t
|
||||
Volume::_CloseAttr(fs_vnode node, fs_cookie cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_CLOSE_ATTR))
|
||||
return B_OK;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2949,6 +3152,10 @@ Volume::_CloseAttr(fs_vnode node, fs_cookie cookie)
|
||||
status_t
|
||||
Volume::_FreeAttrCookie(fs_vnode node, fs_cookie cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_FREE_ATTR_COOKIE))
|
||||
return B_OK;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -2984,6 +3191,10 @@ Volume::_FreeAttrCookie(fs_vnode node, fs_cookie cookie)
|
||||
status_t
|
||||
Volume::_CloseIndexDir(fs_cookie cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_CLOSE_INDEX_DIR))
|
||||
return B_OK;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -3018,6 +3229,10 @@ Volume::_CloseIndexDir(fs_cookie cookie)
|
||||
status_t
|
||||
Volume::_FreeIndexDirCookie(fs_cookie cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_FREE_INDEX_DIR_COOKIE))
|
||||
return B_OK;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -3052,6 +3267,10 @@ Volume::_FreeIndexDirCookie(fs_cookie cookie)
|
||||
status_t
|
||||
Volume::_CloseQuery(fs_cookie cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_CLOSE_QUERY))
|
||||
return B_OK;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
@ -3086,6 +3305,10 @@ Volume::_CloseQuery(fs_cookie cookie)
|
||||
status_t
|
||||
Volume::_FreeQueryCookie(fs_cookie cookie)
|
||||
{
|
||||
// check capability
|
||||
if (!fFileSystem->HasCapability(FS_CAPABILITY_FREE_QUERY_COOKIE))
|
||||
return B_OK;
|
||||
|
||||
// get a free port
|
||||
RequestPort* port = fFileSystem->GetPortPool()->AcquirePort();
|
||||
if (!port)
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <new>
|
||||
|
||||
#include "beos_fs_interface.h"
|
||||
#include "BeOSKernelVolume.h"
|
||||
|
||||
using std::nothrow;
|
||||
@ -13,6 +14,7 @@ BeOSKernelFileSystem::BeOSKernelFileSystem(beos_vnode_ops* fsOps)
|
||||
: FileSystem(),
|
||||
fFSOps(fsOps)
|
||||
{
|
||||
_InitCapabilities(fsOps);
|
||||
}
|
||||
|
||||
// destructor
|
||||
@ -45,3 +47,114 @@ BeOSKernelFileSystem::DeleteVolume(Volume* volume)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// _InitCapabilities
|
||||
void
|
||||
BeOSKernelFileSystem::_InitCapabilities(beos_vnode_ops* fsOps)
|
||||
{
|
||||
fCapabilities.ClearAll();
|
||||
|
||||
// FS interface type
|
||||
fCapabilities.clientFSType = CLIENT_FS_BEOS_KERNEL;
|
||||
|
||||
// FS operations
|
||||
fCapabilities.Set(FS_CAPABILITY_MOUNT, fsOps->mount);
|
||||
fCapabilities.Set(FS_CAPABILITY_UNMOUNT, fsOps->unmount);
|
||||
|
||||
fCapabilities.Set(FS_CAPABILITY_READ_FS_INFO, fsOps->rfsstat);
|
||||
fCapabilities.Set(FS_CAPABILITY_WRITE_FS_INFO, fsOps->wfsstat);
|
||||
fCapabilities.Set(FS_CAPABILITY_SYNC, fsOps->sync);
|
||||
|
||||
// vnode operations
|
||||
fCapabilities.Set(FS_CAPABILITY_LOOKUP, fsOps->walk);
|
||||
// missing: FS_CAPABILITY_GET_VNODE_NAME,
|
||||
|
||||
fCapabilities.Set(FS_CAPABILITY_GET_VNODE, fsOps->read_vnode);
|
||||
fCapabilities.Set(FS_CAPABILITY_PUT_VNODE, fsOps->write_vnode);
|
||||
fCapabilities.Set(FS_CAPABILITY_REMOVE_VNODE, fsOps->remove_vnode);
|
||||
|
||||
// VM file access
|
||||
// missing: FS_CAPABILITY_CAN_PAGE,
|
||||
// missing: FS_CAPABILITY_READ_PAGES,
|
||||
// missing: FS_CAPABILITY_WRITE_PAGES,
|
||||
|
||||
// cache file access
|
||||
// missing: FS_CAPABILITY_GET_FILE_MAP,
|
||||
|
||||
// common operations
|
||||
fCapabilities.Set(FS_CAPABILITY_IOCTL, fsOps->ioctl);
|
||||
fCapabilities.Set(FS_CAPABILITY_SET_FLAGS, fsOps->setflags);
|
||||
fCapabilities.Set(FS_CAPABILITY_SELECT, fsOps->select);
|
||||
fCapabilities.Set(FS_CAPABILITY_DESELECT, fsOps->deselect);
|
||||
fCapabilities.Set(FS_CAPABILITY_FSYNC, fsOps->fsync);
|
||||
|
||||
fCapabilities.Set(FS_CAPABILITY_READ_SYMLINK, fsOps->readlink);
|
||||
fCapabilities.Set(FS_CAPABILITY_CREATE_SYMLINK, fsOps->symlink);
|
||||
|
||||
fCapabilities.Set(FS_CAPABILITY_LINK, fsOps->link);
|
||||
fCapabilities.Set(FS_CAPABILITY_UNLINK, fsOps->unlink);
|
||||
fCapabilities.Set(FS_CAPABILITY_RENAME, fsOps->rename);
|
||||
|
||||
fCapabilities.Set(FS_CAPABILITY_ACCESS, fsOps->access);
|
||||
fCapabilities.Set(FS_CAPABILITY_READ_STAT, fsOps->rstat);
|
||||
fCapabilities.Set(FS_CAPABILITY_WRITE_STAT, fsOps->wstat);
|
||||
|
||||
// file operations
|
||||
fCapabilities.Set(FS_CAPABILITY_CREATE, fsOps->create);
|
||||
fCapabilities.Set(FS_CAPABILITY_OPEN, fsOps->open);
|
||||
fCapabilities.Set(FS_CAPABILITY_CLOSE, fsOps->close);
|
||||
fCapabilities.Set(FS_CAPABILITY_FREE_COOKIE, fsOps->free_cookie);
|
||||
fCapabilities.Set(FS_CAPABILITY_READ, fsOps->read);
|
||||
fCapabilities.Set(FS_CAPABILITY_WRITE, fsOps->write);
|
||||
|
||||
// directory operations
|
||||
fCapabilities.Set(FS_CAPABILITY_CREATE_DIR, fsOps->mkdir);
|
||||
fCapabilities.Set(FS_CAPABILITY_REMOVE_DIR, fsOps->rmdir);
|
||||
fCapabilities.Set(FS_CAPABILITY_OPEN_DIR, fsOps->opendir);
|
||||
fCapabilities.Set(FS_CAPABILITY_CLOSE_DIR, fsOps->closedir);
|
||||
fCapabilities.Set(FS_CAPABILITY_FREE_DIR_COOKIE, fsOps->free_dircookie);
|
||||
fCapabilities.Set(FS_CAPABILITY_READ_DIR, fsOps->readdir);
|
||||
fCapabilities.Set(FS_CAPABILITY_REWIND_DIR, fsOps->rewinddir);
|
||||
|
||||
// attribute directory operations
|
||||
fCapabilities.Set(FS_CAPABILITY_OPEN_ATTR_DIR, fsOps->open_attrdir);
|
||||
fCapabilities.Set(FS_CAPABILITY_CLOSE_ATTR_DIR, fsOps->close_attrdir);
|
||||
fCapabilities.Set(FS_CAPABILITY_FREE_ATTR_DIR_COOKIE,
|
||||
fsOps->free_attrdircookie);
|
||||
fCapabilities.Set(FS_CAPABILITY_READ_ATTR_DIR, fsOps->read_attrdir);
|
||||
fCapabilities.Set(FS_CAPABILITY_REWIND_ATTR_DIR, fsOps->rewind_attrdir);
|
||||
|
||||
// attribute operations
|
||||
// we emulate open_attr() and free_attr_dir_cookie() if either read_attr()
|
||||
// or write_attr() is present
|
||||
bool hasAttributes = (fsOps->read_attr || fsOps->write_attr);
|
||||
fCapabilities.Set(FS_CAPABILITY_CREATE_ATTR, hasAttributes);
|
||||
fCapabilities.Set(FS_CAPABILITY_OPEN_ATTR, hasAttributes);
|
||||
fCapabilities.Set(FS_CAPABILITY_CLOSE_ATTR, false);
|
||||
fCapabilities.Set(FS_CAPABILITY_FREE_ATTR_COOKIE, hasAttributes);
|
||||
fCapabilities.Set(FS_CAPABILITY_READ_ATTR, fsOps->read_attr);
|
||||
fCapabilities.Set(FS_CAPABILITY_WRITE_ATTR, fsOps->write_attr);
|
||||
|
||||
fCapabilities.Set(FS_CAPABILITY_READ_ATTR_STAT, fsOps->stat_attr);
|
||||
// missing: FS_CAPABILITY_WRITE_ATTR_STAT
|
||||
fCapabilities.Set(FS_CAPABILITY_RENAME_ATTR, fsOps->rename_attr);
|
||||
fCapabilities.Set(FS_CAPABILITY_REMOVE_ATTR, fsOps->remove_attr);
|
||||
|
||||
// index directory & index operations
|
||||
fCapabilities.Set(FS_CAPABILITY_OPEN_INDEX_DIR, fsOps->open_indexdir);
|
||||
fCapabilities.Set(FS_CAPABILITY_CLOSE_INDEX_DIR, fsOps->close_indexdir);
|
||||
fCapabilities.Set(FS_CAPABILITY_FREE_INDEX_DIR_COOKIE,
|
||||
fsOps->free_indexdircookie);
|
||||
fCapabilities.Set(FS_CAPABILITY_READ_INDEX_DIR, fsOps->read_indexdir);
|
||||
fCapabilities.Set(FS_CAPABILITY_REWIND_INDEX_DIR, fsOps->rewind_indexdir);
|
||||
|
||||
fCapabilities.Set(FS_CAPABILITY_CREATE_INDEX, fsOps->create_index);
|
||||
fCapabilities.Set(FS_CAPABILITY_REMOVE_INDEX, fsOps->remove_index);
|
||||
fCapabilities.Set(FS_CAPABILITY_READ_INDEX_STAT, fsOps->stat_index);
|
||||
|
||||
// query operations
|
||||
fCapabilities.Set(FS_CAPABILITY_OPEN_QUERY, fsOps->open_query);
|
||||
fCapabilities.Set(FS_CAPABILITY_CLOSE_QUERY, fsOps->close_query);
|
||||
fCapabilities.Set(FS_CAPABILITY_FREE_QUERY_COOKIE, fsOps->free_querycookie);
|
||||
fCapabilities.Set(FS_CAPABILITY_READ_QUERY, fsOps->read_query);
|
||||
// missing: FS_CAPABILITY_REWIND_QUERY,
|
||||
}
|
||||
|
@ -17,6 +17,9 @@ public:
|
||||
virtual status_t CreateVolume(Volume** volume, mount_id id);
|
||||
virtual status_t DeleteVolume(Volume* volume);
|
||||
|
||||
private:
|
||||
void _InitCapabilities(beos_vnode_ops* fsOps);
|
||||
|
||||
private:
|
||||
beos_vnode_ops* fFSOps;
|
||||
};
|
||||
|
@ -294,7 +294,7 @@ status_t
|
||||
BeOSKernelVolume::Access(fs_vnode node, int mode)
|
||||
{
|
||||
if (!fFSOps->access)
|
||||
return B_BAD_VALUE;
|
||||
return B_OK;
|
||||
return fFSOps->access(fVolumeCookie, node, mode);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <Message.h>
|
||||
|
||||
#include "FSCapabilities.h"
|
||||
#include "Port.h"
|
||||
#include "String.h"
|
||||
|
||||
@ -25,12 +26,13 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
FSInfo(const char* fsName, const Port::Info* infos, int32 count)
|
||||
FSInfo(const char* fsName, const Port::Info* infos, int32 count,
|
||||
const FSCapabilities& capabilities)
|
||||
: fName(),
|
||||
fInfos(NULL),
|
||||
fCount(0)
|
||||
{
|
||||
SetTo(fsName, infos, count);
|
||||
SetTo(fsName, infos, count, capabilities);
|
||||
}
|
||||
|
||||
FSInfo(const BMessage* message)
|
||||
@ -46,7 +48,7 @@ public:
|
||||
fInfos(NULL),
|
||||
fCount(0)
|
||||
{
|
||||
SetTo(other.GetName(), other.fInfos, other.fCount);
|
||||
SetTo(other.GetName(), other.fInfos, other.fCount, other.fCapabilities);
|
||||
}
|
||||
|
||||
~FSInfo()
|
||||
@ -54,17 +56,24 @@ public:
|
||||
Unset();
|
||||
}
|
||||
|
||||
status_t SetTo(const char* fsName, const Port::Info* infos, int32 count)
|
||||
status_t SetTo(const char* fsName, const Port::Info* infos, int32 count,
|
||||
const FSCapabilities& capabilities)
|
||||
{
|
||||
Unset();
|
||||
|
||||
if (!fsName || !infos || count <= 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (!fName.SetTo(fsName))
|
||||
return B_NO_MEMORY;
|
||||
|
||||
fInfos = new(nothrow) Port::Info[count];
|
||||
if (!fInfos)
|
||||
return B_NO_MEMORY;
|
||||
memcpy(fInfos, infos, sizeof(Port::Info) * count);
|
||||
|
||||
fCapabilities = capabilities;
|
||||
|
||||
fCount = count;
|
||||
return B_OK;
|
||||
}
|
||||
@ -72,17 +81,25 @@ public:
|
||||
status_t SetTo(const BMessage* message)
|
||||
{
|
||||
Unset();
|
||||
|
||||
if (!message)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
const void* infos;
|
||||
ssize_t size;
|
||||
const char* fsName;
|
||||
const void* capabilities;
|
||||
ssize_t capabilitiesSize;
|
||||
|
||||
if (message->FindData("infos", B_RAW_TYPE, &infos, &size) != B_OK
|
||||
|| size < 0 || message->FindString("fsName", &fsName) != B_OK) {
|
||||
|| size < 0 || message->FindString("fsName", &fsName) != B_OK
|
||||
|| message->FindData("capabilities", B_RAW_TYPE, &capabilities,
|
||||
&capabilitiesSize) != B_OK
|
||||
|| capabilitiesSize != sizeof(FSCapabilities)) {
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
return SetTo(fsName, (const Port::Info*)infos,
|
||||
size / sizeof(Port::Info));
|
||||
size / sizeof(Port::Info), *(const FSCapabilities*)capabilities);
|
||||
}
|
||||
|
||||
void Unset()
|
||||
@ -108,26 +125,39 @@ public:
|
||||
return fCount;
|
||||
}
|
||||
|
||||
int32 GetSize() const
|
||||
int32 GetInfosSize() const
|
||||
{
|
||||
return fCount * sizeof(Port::Info);
|
||||
}
|
||||
|
||||
const FSCapabilities& GetCapabilities() const
|
||||
{
|
||||
return fCapabilities;
|
||||
}
|
||||
|
||||
status_t Archive(BMessage* archive)
|
||||
{
|
||||
if (!fName.GetString() || !fInfos)
|
||||
return B_NO_INIT;
|
||||
|
||||
status_t error = archive->AddString("fsName", fName.GetString());
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
return archive->AddData("infos", B_RAW_TYPE, fInfos,
|
||||
|
||||
error = archive->AddData("infos", B_RAW_TYPE, fInfos,
|
||||
fCount * sizeof(Port::Info));
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
return archive->AddData("capabilities", B_RAW_TYPE, &fCapabilities,
|
||||
sizeof(FSCapabilities));
|
||||
}
|
||||
|
||||
private:
|
||||
String fName;
|
||||
Port::Info* fInfos;
|
||||
int32 fCount;
|
||||
FSCapabilities fCapabilities;
|
||||
};
|
||||
|
||||
} // namespace UserlandFS
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <fs_interface.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include "FSCapabilities.h"
|
||||
|
||||
namespace UserlandFS {
|
||||
|
||||
class Volume;
|
||||
@ -17,6 +19,13 @@ public:
|
||||
|
||||
virtual status_t CreateVolume(Volume** volume, mount_id id) = 0;
|
||||
virtual status_t DeleteVolume(Volume* volume) = 0;
|
||||
|
||||
void GetCapabilities(
|
||||
FSCapabilities& capabilities) const
|
||||
{ capabilities = fCapabilities; }
|
||||
|
||||
protected:
|
||||
FSCapabilities fCapabilities;
|
||||
};
|
||||
|
||||
} // namespace UserlandFS
|
||||
|
@ -319,6 +319,7 @@ UserlandFSDispatcher::_ProcessRequests()
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
RequestReleaser _(fRequestPort, request);
|
||||
|
||||
// check the request type
|
||||
if (request->GetType() == UFS_DISCONNECT_REQUEST)
|
||||
return B_OK;
|
||||
@ -326,6 +327,7 @@ UserlandFSDispatcher::_ProcessRequests()
|
||||
RETURN_ERROR(B_BAD_VALUE);
|
||||
PRINT(("UserlandFSDispatcher::_ProcessRequests(): received FS connect "
|
||||
"request\n"));
|
||||
|
||||
// it's an FS connect request
|
||||
FSConnectRequest* connectRequest = (FSConnectRequest*)request;
|
||||
// get the FS name
|
||||
@ -338,24 +340,27 @@ UserlandFSDispatcher::_ProcessRequests()
|
||||
fsName.SetTo((const char*)connectRequest->fsName.GetData(), len);
|
||||
if (result == B_OK && fsName.GetLength() == 0)
|
||||
result = B_BAD_DATA;
|
||||
|
||||
// prepare the reply
|
||||
RequestAllocator allocator(fRequestPort->GetPort());
|
||||
FSConnectReply* reply;
|
||||
error = AllocateRequest(allocator, &reply);
|
||||
if (error != B_OK)
|
||||
RETURN_ERROR(error);
|
||||
|
||||
FileSystem* fileSystem = NULL;
|
||||
if (result == B_OK)
|
||||
result = _GetFileSystem(fsName.GetString(), &fileSystem);
|
||||
if (result == B_OK) {
|
||||
const FSInfo* info = fileSystem->GetInfo();
|
||||
result = allocator.AllocateData(reply->portInfos,
|
||||
info->GetInfos(), info->GetSize(), sizeof(Port::Info));
|
||||
if (result == B_OK)
|
||||
reply->portInfoCount = info->CountInfos();
|
||||
info->GetInfos(), info->GetInfosSize(), sizeof(Port::Info));
|
||||
reply->portInfoCount = info->CountInfos();
|
||||
reply->capabilities = info->GetCapabilities();
|
||||
_PutFileSystem(fileSystem);
|
||||
}
|
||||
reply->error = result;
|
||||
|
||||
// send it
|
||||
error = fRequestPort->SendRequest(&allocator);
|
||||
if (error != B_OK)
|
||||
|
@ -183,20 +183,29 @@ UserlandFSServer::_RegisterWithDispatcher(const char* fsName)
|
||||
ERROR(("Failed to lock the clipboard.\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// get the port infos
|
||||
Port::Info infos[kRequestThreadCount + 1];
|
||||
infos[0] = *fNotificationRequestPort->GetPortInfo();
|
||||
for (int32 i = 0; i < kRequestThreadCount; i++)
|
||||
infos[i + 1] = *fRequestThreads[i].GetPortInfo();
|
||||
|
||||
// FS capabilities
|
||||
FSCapabilities capabilities;
|
||||
fFileSystem->GetCapabilities(capabilities);
|
||||
|
||||
// init an FS info
|
||||
FSInfo info;
|
||||
status_t error = info.SetTo(fsName, infos, kRequestThreadCount + 1);
|
||||
status_t error = info.SetTo(fsName, infos, kRequestThreadCount + 1,
|
||||
capabilities);
|
||||
|
||||
// prepare the message
|
||||
BMessage message(UFS_REGISTER_FS);
|
||||
if (error == B_OK)
|
||||
error = message.AddInt32("team", Team());
|
||||
if (error == B_OK)
|
||||
error = info.Archive(&message);
|
||||
|
||||
// send the message
|
||||
BMessage reply;
|
||||
error = messenger.SendMessage(&message, &reply);
|
||||
|
Loading…
Reference in New Issue
Block a user