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:
Ingo Weinhold
2007-03-05 05:16:08 +00:00
parent cf4ccd6575
commit 4e0e80ed6c
13 changed files with 629 additions and 19 deletions
@@ -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;
};