diff --git a/headers/private/userlandfs/private/Requests.h b/headers/private/userlandfs/private/Requests.h index eac36d4fd2..58b6f620aa 100644 --- a/headers/private/userlandfs/private/Requests.h +++ b/headers/private/userlandfs/private/Requests.h @@ -11,9 +11,6 @@ #include "Compatibility.h" #include "Request.h" -// TODO: Actually rename: -typedef mount_id nspace_id; - enum { MAX_REQUEST_ADDRESS_COUNT = 4, @@ -27,35 +24,61 @@ enum { UFS_DISCONNECT_REQUEST = 0, FS_CONNECT_REQUEST, FS_CONNECT_REPLY, + // FS MOUNT_VOLUME_REQUEST, MOUNT_VOLUME_REPLY, UNMOUNT_VOLUME_REQUEST, UNMOUNT_VOLUME_REPLY, - INITIALIZE_VOLUME_REQUEST, - INITIALIZE_VOLUME_REPLY, +// INITIALIZE_VOLUME_REQUEST, +// INITIALIZE_VOLUME_REPLY, SYNC_VOLUME_REQUEST, SYNC_VOLUME_REPLY, - READ_FS_STAT_REQUEST, - READ_FS_STAT_REPLY, - WRITE_FS_STAT_REQUEST, - WRITE_FS_STAT_REPLY, + READ_FS_INFO_REQUEST, + READ_FS_INFO_REPLY, + WRITE_FS_INFO_REQUEST, + WRITE_FS_INFO_REPLY, + // vnodes + LOOKUP_REQUEST, + LOOKUP_REPLY, READ_VNODE_REQUEST, READ_VNODE_REPLY, WRITE_VNODE_REQUEST, WRITE_VNODE_REPLY, FS_REMOVE_VNODE_REQUEST, FS_REMOVE_VNODE_REPLY, + // nodes + IOCTL_REQUEST, + IOCTL_REPLY, + SET_FLAGS_REQUEST, + SET_FLAGS_REPLY, + SELECT_REQUEST, + SELECT_REPLY, + DESELECT_REQUEST, + DESELECT_REPLY, FSYNC_REQUEST, FSYNC_REPLY, + + READ_SYMLINK_REQUEST, + READ_SYMLINK_REPLY, + CREATE_SYMLINK_REQUEST, + CREATE_SYMLINK_REPLY, + LINK_REQUEST, + LINK_REPLY, + UNLINK_REQUEST, + UNLINK_REPLY, + RENAME_REQUEST, + RENAME_REPLY, + + ACCESS_REQUEST, + ACCESS_REPLY, READ_STAT_REQUEST, READ_STAT_REPLY, WRITE_STAT_REQUEST, WRITE_STAT_REPLY, - ACCESS_REQUEST, - ACCESS_REPLY, + // files CREATE_REQUEST, CREATE_REPLY, @@ -69,30 +92,12 @@ enum { READ_REPLY, WRITE_REQUEST, WRITE_REPLY, - IOCTL_REQUEST, - IOCTL_REPLY, - SET_FLAGS_REQUEST, - SET_FLAGS_REPLY, - SELECT_REQUEST, - SELECT_REPLY, - DESELECT_REQUEST, - DESELECT_REPLY, - // hard links / symlinks - LINK_REQUEST, - LINK_REPLY, - SYMLINK_REQUEST, - SYMLINK_REPLY, - UNLINK_REQUEST, - UNLINK_REPLY, - READ_LINK_REQUEST, - READ_LINK_REPLY, - RENAME_REQUEST, - RENAME_REPLY, + // directories - MKDIR_REQUEST, - MKDIR_REPLY, - RMDIR_REQUEST, - RMDIR_REPLY, + CREATE_DIR_REQUEST, + CREATE_DIR_REPLY, + REMOVE_DIR_REQUEST, + REMOVE_DIR_REPLY, OPEN_DIR_REQUEST, OPEN_DIR_REPLY, CLOSE_DIR_REQUEST, @@ -103,9 +108,8 @@ enum { READ_DIR_REPLY, REWIND_DIR_REQUEST, REWIND_DIR_REPLY, - WALK_REQUEST, - WALK_REPLY, - // attributes + + // attribute directories OPEN_ATTR_DIR_REQUEST, OPEN_ATTR_DIR_REPLY, CLOSE_ATTR_DIR_REQUEST, @@ -116,16 +120,19 @@ enum { READ_ATTR_DIR_REPLY, REWIND_ATTR_DIR_REQUEST, REWIND_ATTR_DIR_REPLY, + + // attributes READ_ATTR_REQUEST, READ_ATTR_REPLY, WRITE_ATTR_REQUEST, WRITE_ATTR_REPLY, - REMOVE_ATTR_REQUEST, - REMOVE_ATTR_REPLY, + READ_ATTR_STAT_REQUEST, + READ_ATTR_STAT_REPLY, RENAME_ATTR_REQUEST, RENAME_ATTR_REPLY, - STAT_ATTR_REQUEST, - STAT_ATTR_REPLY, + REMOVE_ATTR_REQUEST, + REMOVE_ATTR_REPLY, + // indices OPEN_INDEX_DIR_REQUEST, OPEN_INDEX_DIR_REPLY, @@ -141,10 +148,9 @@ enum { CREATE_INDEX_REPLY, REMOVE_INDEX_REQUEST, REMOVE_INDEX_REPLY, - RENAME_INDEX_REQUEST, - RENAME_INDEX_REPLY, - STAT_INDEX_REQUEST, - STAT_INDEX_REPLY, + READ_INDEX_STAT_REQUEST, + READ_INDEX_STAT_REPLY, + // queries OPEN_QUERY_REQUEST, OPEN_QUERY_REPLY, @@ -163,6 +169,7 @@ enum { NOTIFY_SELECT_EVENT_REPLY, SEND_NOTIFICATION_REQUEST, SEND_NOTIFICATION_REPLY, + // vnodes GET_VNODE_REQUEST, GET_VNODE_REPLY, @@ -194,15 +201,16 @@ public: status_t error; }; -// #pragma mark - -// #pragma mark ----- kernel requests ----- + +// #pragma mark - kernel requests + // VolumeRequest class VolumeRequest : public Request { public: VolumeRequest(uint32 type) : Request(type) {} - void* volume; + fs_volume volume; }; // NodeRequest @@ -210,7 +218,7 @@ class NodeRequest : public VolumeRequest { public: NodeRequest(uint32 type) : VolumeRequest(type) {} - void* node; + fs_vnode node; }; // FileRequest @@ -218,7 +226,7 @@ class FileRequest : public NodeRequest { public: FileRequest(uint32 type) : NodeRequest(type) {} - void* fileCookie; + fs_cookie fileCookie; }; // DirRequest @@ -226,7 +234,7 @@ class DirRequest : public NodeRequest { public: DirRequest(uint32 type) : NodeRequest(type) {} - void* dirCookie; + fs_cookie dirCookie; }; // AttrDirRequest @@ -234,7 +242,15 @@ class AttrDirRequest : public NodeRequest { public: AttrDirRequest(uint32 type) : NodeRequest(type) {} - void* attrDirCookie; + fs_cookie attrDirCookie; +}; + +// AttributeRequest +class AttributeRequest : public NodeRequest { +public: + AttributeRequest(uint32 type) : NodeRequest(type) {} + + fs_cookie attrCookie; }; // IndexDirRequest @@ -242,11 +258,20 @@ class IndexDirRequest : public VolumeRequest { public: IndexDirRequest(uint32 type) : VolumeRequest(type) {} - void* indexDirCookie; + fs_cookie indexDirCookie; }; -// #pragma mark - -// #pragma mark ----- administrative ----- +// QueryRequest +class QueryRequest : public VolumeRequest { +public: + QueryRequest(uint32 type) : VolumeRequest(type) {} + + fs_cookie queryCookie; +}; + + +// #pragma mark - administrative + // UFSDisconnectRequest class UFSDisconnectRequest : public Request { @@ -273,8 +298,9 @@ public: int32 portInfoCount; }; -// #pragma mark - -// #pragma mark ----- FS ----- + +// #pragma mark - FS + // MountVolumeRequest class MountVolumeRequest : public Request { @@ -282,10 +308,10 @@ public: MountVolumeRequest() : Request(MOUNT_VOLUME_REQUEST) {} status_t GetAddressInfos(AddressInfo* infos, int32* count); - nspace_id nsid; + mount_id nsid; Address cwd; // current working dir of the mount() caller Address device; - ulong flags; + uint32 flags; Address parameters; }; @@ -295,7 +321,7 @@ public: MountVolumeReply() : ReplyRequest(MOUNT_VOLUME_REPLY) {} vnode_id rootID; - void* volume; + fs_volume volume; }; // UnmountVolumeRequest @@ -310,7 +336,7 @@ public: UnmountVolumeReply() : ReplyRequest(UNMOUNT_VOLUME_REPLY) {} }; -// InitializeVolumeRequest +/*// InitializeVolumeRequest class InitializeVolumeRequest : public Request { public: InitializeVolumeRequest() : Request(INITIALIZE_VOLUME_REQUEST) {} @@ -324,7 +350,7 @@ public: class InitializeVolumeReply : public ReplyRequest { public: InitializeVolumeReply() : ReplyRequest(INITIALIZE_VOLUME_REPLY) {} -}; +};*/ // SyncVolumeRequest class SyncVolumeRequest : public VolumeRequest { @@ -338,37 +364,58 @@ public: SyncVolumeReply() : ReplyRequest(SYNC_VOLUME_REPLY) {} }; -// ReadFSStatRequest -class ReadFSStatRequest : public VolumeRequest { +// ReadFSInfoRequest +class ReadFSInfoRequest : public VolumeRequest { public: - ReadFSStatRequest() : VolumeRequest(READ_FS_STAT_REQUEST) {} + ReadFSInfoRequest() : VolumeRequest(READ_FS_INFO_REQUEST) {} }; -// ReadFSStatReply -class ReadFSStatReply : public ReplyRequest { +// ReadFSInfoReply +class ReadFSInfoReply : public ReplyRequest { public: - ReadFSStatReply() : ReplyRequest(READ_FS_STAT_REPLY) {} + ReadFSInfoReply() : ReplyRequest(READ_FS_INFO_REPLY) {} fs_info info; }; -// WriteFSStatRequest -class WriteFSStatRequest : public VolumeRequest { +// WriteFSInfoRequest +class WriteFSInfoRequest : public VolumeRequest { public: - WriteFSStatRequest() : VolumeRequest(WRITE_FS_STAT_REQUEST) {} + WriteFSInfoRequest() : VolumeRequest(WRITE_FS_INFO_REQUEST) {} fs_info info; long mask; }; -// WriteFSStatReply -class WriteFSStatReply : public ReplyRequest { +// WriteFSInfoReply +class WriteFSInfoReply : public ReplyRequest { public: - WriteFSStatReply() : ReplyRequest(WRITE_FS_STAT_REPLY) {} + WriteFSInfoReply() : ReplyRequest(WRITE_FS_INFO_REPLY) {} }; -// #pragma mark - -// #pragma mark ----- vnodes ----- + +// #pragma mark - vnodes + + +// LookupRequest +class LookupRequest : public NodeRequest { +public: + LookupRequest() : NodeRequest(LOOKUP_REQUEST) {} + status_t GetAddressInfos(AddressInfo* infos, int32* count); + + Address entryName; + bool traverseLink; +}; + +// LookupReply +class LookupReply : public ReplyRequest { +public: + LookupReply() : ReplyRequest(LOOKUP_REPLY) {} + + Address resolvedPath; + vnode_id vnid; + int type; +}; // ReadVNodeRequest class ReadVNodeRequest : public VolumeRequest { @@ -384,7 +431,7 @@ class ReadVNodeReply : public ReplyRequest { public: ReadVNodeReply() : ReplyRequest(READ_VNODE_REPLY) {} - void* node; + fs_vnode node; }; // WriteVNodeRequest @@ -415,163 +462,9 @@ public: FSRemoveVNodeReply() : ReplyRequest(FS_REMOVE_VNODE_REPLY) {} }; -// #pragma mark - -// #pragma mark ----- nodes ----- -// FSyncRequest -class FSyncRequest : public NodeRequest { -public: - FSyncRequest() : NodeRequest(FSYNC_REQUEST) {} -}; +// #pragma mark - nodes -// FSyncReply -class FSyncReply : public ReplyRequest { -public: - FSyncReply() : ReplyRequest(FSYNC_REPLY) {} -}; - -// ReadStatRequest -class ReadStatRequest : public NodeRequest { -public: - ReadStatRequest() : NodeRequest(READ_STAT_REQUEST) {} -}; - -// ReadStatReply -class ReadStatReply : public ReplyRequest { -public: - ReadStatReply() : ReplyRequest(READ_STAT_REPLY) {} - - struct stat st; -}; - -// WriteStatRequest -class WriteStatRequest : public NodeRequest { -public: - WriteStatRequest() : NodeRequest(WRITE_STAT_REQUEST) {} - - struct stat st; - long mask; -}; - -// WriteStatReply -class WriteStatReply : public ReplyRequest { -public: - WriteStatReply() : ReplyRequest(WRITE_STAT_REPLY) {} -}; - -// AccessRequest -class AccessRequest : public NodeRequest { -public: - AccessRequest() : NodeRequest(ACCESS_REQUEST) {} - - int mode; -}; - -// AccessReply -class AccessReply : public ReplyRequest { -public: - AccessReply() : ReplyRequest(ACCESS_REPLY) {} -}; - -// #pragma mark - -// #pragma mark ----- files ----- - -// CreateRequest -class CreateRequest : public NodeRequest { -public: - CreateRequest() : NodeRequest(CREATE_REQUEST) {} - status_t GetAddressInfos(AddressInfo* infos, int32* count); - - Address name; - int openMode; - int mode; -}; - -// CreateReply -class CreateReply : public ReplyRequest { -public: - CreateReply() : ReplyRequest(CREATE_REPLY) {} - - vnode_id vnid; - void* fileCookie; -}; - -// OpenRequest -class OpenRequest : public NodeRequest { -public: - OpenRequest() : NodeRequest(OPEN_REQUEST) {} - - int openMode; -}; - -// OpenReply -class OpenReply : public ReplyRequest { -public: - OpenReply() : ReplyRequest(OPEN_REPLY) {} - - void* fileCookie; -}; - -// CloseRequest -class CloseRequest : public FileRequest { -public: - CloseRequest() : FileRequest(CLOSE_REQUEST) {} -}; - -// CloseReply -class CloseReply : public ReplyRequest { -public: - CloseReply() : ReplyRequest(CLOSE_REPLY) {} -}; - -// FreeCookieRequest -class FreeCookieRequest : public FileRequest { -public: - FreeCookieRequest() : FileRequest(FREE_COOKIE_REQUEST) {} -}; - -// FreeCookieReply -class FreeCookieReply : public ReplyRequest { -public: - FreeCookieReply() : ReplyRequest(FREE_COOKIE_REPLY) {} -}; - -// ReadRequest -class ReadRequest : public FileRequest { -public: - ReadRequest() : FileRequest(READ_REQUEST) {} - - off_t pos; - size_t size; -}; - -// ReadReply -class ReadReply : public ReplyRequest { -public: - ReadReply() : ReplyRequest(READ_REPLY) {} - status_t GetAddressInfos(AddressInfo* infos, int32* count); - - Address buffer; - size_t bytesRead; -}; - -// WriteRequest -class WriteRequest : public FileRequest { -public: - WriteRequest() : FileRequest(WRITE_REQUEST) {} - status_t GetAddressInfos(AddressInfo* infos, int32* count); - - Address buffer; - off_t pos; -}; - -// WriteReply -class WriteReply : public ReplyRequest { -public: - WriteReply() : ReplyRequest(WRITE_REPLY) {} - - size_t bytesWritten; -}; // IOCtlRequest class IOCtlRequest : public FileRequest { @@ -579,7 +472,7 @@ public: IOCtlRequest() : FileRequest(IOCTL_REQUEST) {} status_t GetAddressInfos(AddressInfo* infos, int32* count); - int command; + uint32 command; void* bufferParameter; size_t lenParameter; bool isBuffer; // if false, just pass bufferParameter @@ -645,8 +538,52 @@ public: DeselectReply() : ReplyRequest(DESELECT_REPLY) {} }; -// #pragma mark - -// #pragma mark ----- hard links / symlinks ----- +// FSyncRequest +class FSyncRequest : public NodeRequest { +public: + FSyncRequest() : NodeRequest(FSYNC_REQUEST) {} +}; + +// FSyncReply +class FSyncReply : public ReplyRequest { +public: + FSyncReply() : ReplyRequest(FSYNC_REPLY) {} +}; + +// ReadSymlinkRequest +class ReadSymlinkRequest : public NodeRequest { +public: + ReadSymlinkRequest() : NodeRequest(READ_SYMLINK_REQUEST) {} + + size_t size; +}; + +// ReadSymlinkReply +class ReadSymlinkReply : public ReplyRequest { +public: + ReadSymlinkReply() : ReplyRequest(READ_SYMLINK_REPLY) {} + status_t GetAddressInfos(AddressInfo* infos, int32* count); + + Address buffer; + size_t bytesRead; +}; + +// CreateSymlinkRequest +class CreateSymlinkRequest : public NodeRequest { +public: + CreateSymlinkRequest() : NodeRequest(CREATE_SYMLINK_REQUEST) {} + status_t GetAddressInfos(AddressInfo* infos, int32* count); + + Address name; + Address target; + int mode; +}; + +// CreateSymlinkReply +class CreateSymlinkReply : public ReplyRequest { +public: + CreateSymlinkReply() : ReplyRequest(CREATE_SYMLINK_REPLY) {} +}; // LinkRequest class LinkRequest : public NodeRequest { @@ -655,7 +592,7 @@ public: status_t GetAddressInfos(AddressInfo* infos, int32* count); Address name; - void* target; + fs_vnode target; }; // LinkReply @@ -679,49 +616,15 @@ public: UnlinkReply() : ReplyRequest(UNLINK_REPLY) {} }; -// SymlinkRequest -class SymlinkRequest : public NodeRequest { -public: - SymlinkRequest() : NodeRequest(SYMLINK_REQUEST) {} - status_t GetAddressInfos(AddressInfo* infos, int32* count); - - Address name; - Address target; -}; - -// SymlinkReply -class SymlinkReply : public ReplyRequest { -public: - SymlinkReply() : ReplyRequest(SYMLINK_REPLY) {} -}; - -// ReadLinkRequest -class ReadLinkRequest : public NodeRequest { -public: - ReadLinkRequest() : NodeRequest(READ_LINK_REQUEST) {} - - size_t size; -}; - -// ReadLinkReply -class ReadLinkReply : public ReplyRequest { -public: - ReadLinkReply() : ReplyRequest(READ_LINK_REPLY) {} - status_t GetAddressInfos(AddressInfo* infos, int32* count); - - Address buffer; - size_t bytesRead; -}; - // RenameRequest class RenameRequest : public VolumeRequest { public: RenameRequest() : VolumeRequest(RENAME_REQUEST) {} status_t GetAddressInfos(AddressInfo* infos, int32* count); - void* oldDir; + fs_vnode oldDir; Address oldName; - void* newDir; + fs_vnode newDir; Address newName; }; @@ -731,38 +634,185 @@ public: RenameReply() : ReplyRequest(RENAME_REPLY) {} }; -// #pragma mark - -// #pragma mark ----- directories ----- - -// MkDirRequest -class MkDirRequest : public NodeRequest { +// AccessRequest +class AccessRequest : public NodeRequest { public: - MkDirRequest() : NodeRequest(MKDIR_REQUEST) {} + AccessRequest() : NodeRequest(ACCESS_REQUEST) {} + + int mode; +}; + +// AccessReply +class AccessReply : public ReplyRequest { +public: + AccessReply() : ReplyRequest(ACCESS_REPLY) {} +}; + +// ReadStatRequest +class ReadStatRequest : public NodeRequest { +public: + ReadStatRequest() : NodeRequest(READ_STAT_REQUEST) {} +}; + +// ReadStatReply +class ReadStatReply : public ReplyRequest { +public: + ReadStatReply() : ReplyRequest(READ_STAT_REPLY) {} + + struct stat st; +}; + +// WriteStatRequest +class WriteStatRequest : public NodeRequest { +public: + WriteStatRequest() : NodeRequest(WRITE_STAT_REQUEST) {} + + struct stat st; + uint32 mask; +}; + +// WriteStatReply +class WriteStatReply : public ReplyRequest { +public: + WriteStatReply() : ReplyRequest(WRITE_STAT_REPLY) {} +}; + + +// #pragma mark - files + + +// CreateRequest +class CreateRequest : public NodeRequest { +public: + CreateRequest() : NodeRequest(CREATE_REQUEST) {} + status_t GetAddressInfos(AddressInfo* infos, int32* count); + + Address name; + int openMode; + int mode; +}; + +// CreateReply +class CreateReply : public ReplyRequest { +public: + CreateReply() : ReplyRequest(CREATE_REPLY) {} + + vnode_id vnid; + fs_cookie fileCookie; +}; + +// OpenRequest +class OpenRequest : public NodeRequest { +public: + OpenRequest() : NodeRequest(OPEN_REQUEST) {} + + int openMode; +}; + +// OpenReply +class OpenReply : public ReplyRequest { +public: + OpenReply() : ReplyRequest(OPEN_REPLY) {} + + fs_cookie fileCookie; +}; + +// CloseRequest +class CloseRequest : public FileRequest { +public: + CloseRequest() : FileRequest(CLOSE_REQUEST) {} +}; + +// CloseReply +class CloseReply : public ReplyRequest { +public: + CloseReply() : ReplyRequest(CLOSE_REPLY) {} +}; + +// FreeCookieRequest +class FreeCookieRequest : public FileRequest { +public: + FreeCookieRequest() : FileRequest(FREE_COOKIE_REQUEST) {} +}; + +// FreeCookieReply +class FreeCookieReply : public ReplyRequest { +public: + FreeCookieReply() : ReplyRequest(FREE_COOKIE_REPLY) {} +}; + +// ReadRequest +class ReadRequest : public FileRequest { +public: + ReadRequest() : FileRequest(READ_REQUEST) {} + + off_t pos; + size_t size; +}; + +// ReadReply +class ReadReply : public ReplyRequest { +public: + ReadReply() : ReplyRequest(READ_REPLY) {} + status_t GetAddressInfos(AddressInfo* infos, int32* count); + + Address buffer; + size_t bytesRead; +}; + +// WriteRequest +class WriteRequest : public FileRequest { +public: + WriteRequest() : FileRequest(WRITE_REQUEST) {} + status_t GetAddressInfos(AddressInfo* infos, int32* count); + + Address buffer; + off_t pos; +}; + +// WriteReply +class WriteReply : public ReplyRequest { +public: + WriteReply() : ReplyRequest(WRITE_REPLY) {} + + size_t bytesWritten; +}; + + +// #pragma mark - directories + + +// CreateDirRequest +class CreateDirRequest : public NodeRequest { +public: + CreateDirRequest() : NodeRequest(CREATE_DIR_REQUEST) {} status_t GetAddressInfos(AddressInfo* infos, int32* count); Address name; int mode; }; -// MkDirReply -class MkDirReply : public ReplyRequest { +// CreateDirReply +class CreateDirReply : public ReplyRequest { public: - MkDirReply() : ReplyRequest(MKDIR_REPLY) {} + CreateDirReply() : ReplyRequest(CREATE_DIR_REPLY) {} + + vnode_id newDir; }; -// RmDirRequest -class RmDirRequest : public NodeRequest { +// RemoveDirRequest +class RemoveDirRequest : public NodeRequest { public: - RmDirRequest() : NodeRequest(RMDIR_REQUEST) {} + RemoveDirRequest() : NodeRequest(REMOVE_DIR_REQUEST) {} status_t GetAddressInfos(AddressInfo* infos, int32* count); Address name; }; -// RmDirReply -class RmDirReply : public ReplyRequest { +// RemoveDirReply +class RemoveDirReply : public ReplyRequest { public: - RmDirReply() : ReplyRequest(RMDIR_REPLY) {} + RemoveDirReply() : ReplyRequest(REMOVE_DIR_REPLY) {} }; // OpenDirRequest @@ -776,7 +826,7 @@ class OpenDirReply : public ReplyRequest { public: OpenDirReply() : ReplyRequest(OPEN_DIR_REPLY) {} - void* dirCookie; + fs_cookie dirCookie; }; // CloseDirRequest @@ -809,7 +859,7 @@ public: ReadDirRequest() : DirRequest(READ_DIR_REQUEST) {} size_t bufferSize; - int32 count; + uint32 count; }; // ReadDirReply @@ -818,7 +868,7 @@ public: ReadDirReply() : ReplyRequest(READ_DIR_REPLY) {} status_t GetAddressInfos(AddressInfo* infos, int32* count); - int32 count; + uint32 count; Address buffer; }; @@ -834,28 +884,9 @@ public: RewindDirReply() : ReplyRequest(REWIND_DIR_REPLY) {} }; -// WalkRequest -class WalkRequest : public NodeRequest { -public: - WalkRequest() : NodeRequest(WALK_REQUEST) {} - status_t GetAddressInfos(AddressInfo* infos, int32* count); - Address entryName; - bool traverseLink; -}; +// #pragma mark - attribute directories -// WalkReply -class WalkReply : public ReplyRequest { -public: - WalkReply() : ReplyRequest(WALK_REPLY) {} - status_t GetAddressInfos(AddressInfo* infos, int32* count); - - Address resolvedPath; - vnode_id vnid; -}; - -// #pragma mark - -// #pragma mark ----- attributes ----- // OpenAttrDirRequest class OpenAttrDirRequest : public NodeRequest { @@ -868,7 +899,7 @@ class OpenAttrDirReply : public ReplyRequest { public: OpenAttrDirReply() : ReplyRequest(OPEN_ATTR_DIR_REPLY) {} - void* attrDirCookie; + fs_cookie attrDirCookie; }; // CloseAttrDirRequest @@ -901,7 +932,7 @@ public: ReadAttrDirRequest() : AttrDirRequest(READ_ATTR_DIR_REQUEST) {} size_t bufferSize; - int32 count; + uint32 count; }; // ReadAttrDirReply @@ -910,7 +941,7 @@ public: ReadAttrDirReply() : ReplyRequest(READ_ATTR_DIR_REPLY) {} status_t GetAddressInfos(AddressInfo* infos, int32* count); - int32 count; + uint32 count; Address buffer; }; @@ -926,14 +957,15 @@ public: RewindAttrDirReply() : ReplyRequest(REWIND_ATTR_DIR_REPLY) {} }; -// ReadAttrRequest -class ReadAttrRequest : public NodeRequest { -public: - ReadAttrRequest() : NodeRequest(READ_ATTR_REQUEST) {} - status_t GetAddressInfos(AddressInfo* infos, int32* count); - Address name; - int type; +// #pragma mark - attributes + + +// ReadAttrRequest +class ReadAttrRequest : public AttributeRequest { +public: + ReadAttrRequest() : AttributeRequest(READ_ATTR_REQUEST) {} + off_t pos; size_t size; }; @@ -949,13 +981,11 @@ public: }; // WriteAttrRequest -class WriteAttrRequest : public NodeRequest { +class WriteAttrRequest : public AttributeRequest { public: - WriteAttrRequest() : NodeRequest(WRITE_ATTR_REQUEST) {} + WriteAttrRequest() : AttributeRequest(WRITE_ATTR_REQUEST) {} status_t GetAddressInfos(AddressInfo* infos, int32* count); - Address name; - int type; Address buffer; off_t pos; size_t size; @@ -969,6 +999,38 @@ public: size_t bytesWritten; }; +// ReadAttrStatRequest +class ReadAttrStatRequest : public AttributeRequest { +public: + ReadAttrStatRequest() : AttributeRequest(READ_ATTR_STAT_REQUEST) {} +}; + +// ReadAttrStatReply +class ReadAttrStatReply : public ReplyRequest { +public: + ReadAttrStatReply() : ReplyRequest(READ_ATTR_STAT_REPLY) {} + + struct stat st; +}; + +// RenameAttrRequest +class RenameAttrRequest : public VolumeRequest { +public: + RenameAttrRequest() : VolumeRequest(RENAME_ATTR_REQUEST) {} + status_t GetAddressInfos(AddressInfo* infos, int32* count); + + fs_vnode oldNode; + fs_vnode newNode; + Address oldName; + Address newName; +}; + +// RenameAttrReply +class RenameAttrReply : public ReplyRequest { +public: + RenameAttrReply() : ReplyRequest(RENAME_ATTR_REPLY) {} +}; + // RemoveAttrRequest class RemoveAttrRequest : public NodeRequest { public: @@ -984,41 +1046,9 @@ public: RemoveAttrReply() : ReplyRequest(REMOVE_ATTR_REPLY) {} }; -// RenameAttrRequest -class RenameAttrRequest : public NodeRequest { -public: - RenameAttrRequest() : NodeRequest(RENAME_ATTR_REQUEST) {} - status_t GetAddressInfos(AddressInfo* infos, int32* count); - Address oldName; - Address newName; -}; +// #pragma mark - indices -// RenameAttrReply -class RenameAttrReply : public ReplyRequest { -public: - RenameAttrReply() : ReplyRequest(RENAME_ATTR_REPLY) {} -}; - -// StatAttrRequest -class StatAttrRequest : public NodeRequest { -public: - StatAttrRequest() : NodeRequest(STAT_ATTR_REQUEST) {} - status_t GetAddressInfos(AddressInfo* infos, int32* count); - - Address name; -}; - -// StatAttrReply -class StatAttrReply : public ReplyRequest { -public: - StatAttrReply() : ReplyRequest(STAT_ATTR_REPLY) {} - - attr_info info; -}; - -// #pragma mark - -// #pragma mark ----- indices ----- // OpenIndexDirRequest class OpenIndexDirRequest : public VolumeRequest { @@ -1031,7 +1061,7 @@ class OpenIndexDirReply : public ReplyRequest { public: OpenIndexDirReply() : ReplyRequest(OPEN_INDEX_DIR_REPLY) {} - void* indexDirCookie; + fs_cookie indexDirCookie; }; // CloseIndexDirRequest @@ -1065,7 +1095,7 @@ public: ReadIndexDirRequest() : IndexDirRequest(READ_INDEX_DIR_REQUEST) {} size_t bufferSize; - int32 count; + uint32 count; }; // ReadIndexDirReply @@ -1074,7 +1104,7 @@ public: ReadIndexDirReply() : ReplyRequest(READ_INDEX_DIR_REPLY) {} status_t GetAddressInfos(AddressInfo* infos, int32* count); - int32 count; + uint32 count; Address buffer; }; @@ -1097,8 +1127,8 @@ public: status_t GetAddressInfos(AddressInfo* infos, int32* count); Address name; - int type; - int flags; + uint32 type; + uint32 flags; }; // CreateIndexReply @@ -1122,41 +1152,26 @@ public: RemoveIndexReply() : ReplyRequest(REMOVE_INDEX_REPLY) {} }; -// RenameIndexRequest -class RenameIndexRequest : public VolumeRequest { +// ReadIndexStatRequest +class ReadIndexStatRequest : public VolumeRequest { public: - RenameIndexRequest() : VolumeRequest(RENAME_INDEX_REQUEST) {} - status_t GetAddressInfos(AddressInfo* infos, int32* count); - - Address oldName; - Address newName; -}; - -// RenameIndexReply -class RenameIndexReply : public ReplyRequest { -public: - RenameIndexReply() : ReplyRequest(RENAME_INDEX_REPLY) {} -}; - -// StatIndexRequest -class StatIndexRequest : public VolumeRequest { -public: - StatIndexRequest() : VolumeRequest(STAT_INDEX_REQUEST) {} + ReadIndexStatRequest() : VolumeRequest(READ_INDEX_STAT_REQUEST) {} status_t GetAddressInfos(AddressInfo* infos, int32* count); Address name; }; -// StatIndexReply -class StatIndexReply : public ReplyRequest { +// ReadIndexStatReply +class ReadIndexStatReply : public ReplyRequest { public: - StatIndexReply() : ReplyRequest(STAT_INDEX_REPLY) {} + ReadIndexStatReply() : ReplyRequest(READ_INDEX_STAT_REPLY) {} - index_info info; + struct stat st; }; -// #pragma mark - -// #pragma mark ----- queries ----- + +// #pragma mark - queries + // OpenQueryRequest class OpenQueryRequest : public VolumeRequest { @@ -1165,9 +1180,9 @@ public: status_t GetAddressInfos(AddressInfo* infos, int32* count); Address queryString; - ulong flags; + uint32 flags; port_id port; - long token; + uint32 token; }; // OpenQueryReply @@ -1175,15 +1190,13 @@ class OpenQueryReply : public ReplyRequest { public: OpenQueryReply() : ReplyRequest(OPEN_QUERY_REPLY) {} - void* queryCookie; + fs_cookie queryCookie; }; // CloseQueryRequest -class CloseQueryRequest : public VolumeRequest { +class CloseQueryRequest : public QueryRequest { public: - CloseQueryRequest() : VolumeRequest(CLOSE_QUERY_REQUEST) {} - - void* queryCookie; + CloseQueryRequest() : QueryRequest(CLOSE_QUERY_REQUEST) {} }; // CloseQueryReply @@ -1193,11 +1206,9 @@ public: }; // FreeQueryCookieRequest -class FreeQueryCookieRequest : public VolumeRequest { +class FreeQueryCookieRequest : public QueryRequest { public: - FreeQueryCookieRequest() : VolumeRequest(FREE_QUERY_COOKIE_REQUEST) {} - - void* queryCookie; + FreeQueryCookieRequest() : QueryRequest(FREE_QUERY_COOKIE_REQUEST) {} }; // FreeQueryCookieReply @@ -1207,13 +1218,12 @@ public: }; // ReadQueryRequest -class ReadQueryRequest : public VolumeRequest { +class ReadQueryRequest : public QueryRequest { public: - ReadQueryRequest() : VolumeRequest(READ_QUERY_REQUEST) {} + ReadQueryRequest() : QueryRequest(READ_QUERY_REQUEST) {} - void* queryCookie; size_t bufferSize; - int32 count; + uint32 count; }; // ReadQueryReply @@ -1222,7 +1232,7 @@ public: ReadQueryReply() : ReplyRequest(READ_QUERY_REPLY) {} status_t GetAddressInfos(AddressInfo* infos, int32* count); - int32 count; + uint32 count; Address buffer; }; @@ -1233,6 +1243,8 @@ public: // #pragma mark - // #pragma mark ----- notifications ----- +// TODO: notify_listener() and send_notifications() are obsolete! + // NotifyListenerRequest class NotifyListenerRequest : public Request { public: @@ -1240,7 +1252,7 @@ public: status_t GetAddressInfos(AddressInfo* infos, int32* count); int32 operation; - nspace_id nsid; + mount_id nsid; vnode_id vnida; vnode_id vnidb; vnode_id vnidc; @@ -1260,6 +1272,7 @@ public: selectsync* sync; uint32 ref; + uint8 event; }; // NotifySelectEventReply @@ -1278,8 +1291,8 @@ public: int32 token; uint32 what; int32 operation; - nspace_id nsida; - nspace_id nsidb; + mount_id nsida; + mount_id nsidb; vnode_id vnida; vnode_id vnidb; vnode_id vnidc; @@ -1301,7 +1314,7 @@ class GetVNodeRequest : public Request { public: GetVNodeRequest() : Request(GET_VNODE_REQUEST) {} - nspace_id nsid; + mount_id nsid; vnode_id vnid; }; @@ -1310,7 +1323,7 @@ class GetVNodeReply : public ReplyRequest { public: GetVNodeReply() : ReplyRequest(GET_VNODE_REPLY) {} - void* node; + fs_vnode node; }; // PutVNodeRequest @@ -1318,7 +1331,7 @@ class PutVNodeRequest : public Request { public: PutVNodeRequest() : Request(PUT_VNODE_REQUEST) {} - nspace_id nsid; + mount_id nsid; vnode_id vnid; }; @@ -1333,9 +1346,9 @@ class NewVNodeRequest : public Request { public: NewVNodeRequest() : Request(NEW_VNODE_REQUEST) {} - nspace_id nsid; + mount_id nsid; vnode_id vnid; - void* node; + fs_vnode node; }; // NewVNodeReply @@ -1349,7 +1362,7 @@ class RemoveVNodeRequest : public Request { public: RemoveVNodeRequest() : Request(REMOVE_VNODE_REQUEST) {} - nspace_id nsid; + mount_id nsid; vnode_id vnid; }; @@ -1364,7 +1377,7 @@ class UnremoveVNodeRequest : public Request { public: UnremoveVNodeRequest() : Request(UNREMOVE_VNODE_REQUEST) {} - nspace_id nsid; + mount_id nsid; vnode_id vnid; }; @@ -1379,7 +1392,7 @@ class IsVNodeRemovedRequest : public Request { public: IsVNodeRemovedRequest() : Request(IS_VNODE_REMOVED_REQUEST) {} - nspace_id nsid; + mount_id nsid; vnode_id vnid; }; @@ -1431,23 +1444,27 @@ do_for_request(Request* request, Task& task) return task((UnmountVolumeRequest*)request); case UNMOUNT_VOLUME_REPLY: return task((UnmountVolumeReply*)request); - case INITIALIZE_VOLUME_REQUEST: - return task((InitializeVolumeRequest*)request); - case INITIALIZE_VOLUME_REPLY: - return task((InitializeVolumeReply*)request); +// case INITIALIZE_VOLUME_REQUEST: +// return task((InitializeVolumeRequest*)request); +// case INITIALIZE_VOLUME_REPLY: +// return task((InitializeVolumeReply*)request); case SYNC_VOLUME_REQUEST: return task((SyncVolumeRequest*)request); case SYNC_VOLUME_REPLY: return task((SyncVolumeReply*)request); - case READ_FS_STAT_REQUEST: - return task((ReadFSStatRequest*)request); - case READ_FS_STAT_REPLY: - return task((ReadFSStatReply*)request); - case WRITE_FS_STAT_REQUEST: - return task((WriteFSStatRequest*)request); - case WRITE_FS_STAT_REPLY: - return task((WriteFSStatReply*)request); + case READ_FS_INFO_REQUEST: + return task((ReadFSInfoRequest*)request); + case READ_FS_INFO_REPLY: + return task((ReadFSInfoReply*)request); + case WRITE_FS_INFO_REQUEST: + return task((WriteFSInfoRequest*)request); + case WRITE_FS_INFO_REPLY: + return task((WriteFSInfoReply*)request); // vnodes + case LOOKUP_REQUEST: + return task((LookupRequest*)request); + case LOOKUP_REPLY: + return task((LookupReply*)request); case READ_VNODE_REQUEST: return task((ReadVNodeRequest*)request); case READ_VNODE_REPLY: @@ -1461,10 +1478,50 @@ do_for_request(Request* request, Task& task) case FS_REMOVE_VNODE_REPLY: return task((FSRemoveVNodeReply*)request); // nodes + case IOCTL_REQUEST: + return task((IOCtlRequest*)request); + case IOCTL_REPLY: + return task((IOCtlReply*)request); + case SET_FLAGS_REQUEST: + return task((SetFlagsRequest*)request); + case SET_FLAGS_REPLY: + return task((SetFlagsReply*)request); + case SELECT_REQUEST: + return task((SelectRequest*)request); + case SELECT_REPLY: + return task((SelectReply*)request); + case DESELECT_REQUEST: + return task((DeselectRequest*)request); + case DESELECT_REPLY: + return task((DeselectReply*)request); case FSYNC_REQUEST: return task((FSyncRequest*)request); case FSYNC_REPLY: return task((FSyncReply*)request); + case READ_SYMLINK_REQUEST: + return task((ReadSymlinkRequest*)request); + case READ_SYMLINK_REPLY: + return task((ReadSymlinkReply*)request); + case CREATE_SYMLINK_REQUEST: + return task((CreateSymlinkRequest*)request); + case CREATE_SYMLINK_REPLY: + return task((CreateSymlinkReply*)request); + case LINK_REQUEST: + return task((LinkRequest*)request); + case LINK_REPLY: + return task((LinkReply*)request); + case UNLINK_REQUEST: + return task((UnlinkRequest*)request); + case UNLINK_REPLY: + return task((UnlinkReply*)request); + case RENAME_REQUEST: + return task((RenameRequest*)request); + case RENAME_REPLY: + return task((RenameReply*)request); + case ACCESS_REQUEST: + return task((AccessRequest*)request); + case ACCESS_REPLY: + return task((AccessReply*)request); case READ_STAT_REQUEST: return task((ReadStatRequest*)request); case READ_STAT_REPLY: @@ -1473,10 +1530,6 @@ do_for_request(Request* request, Task& task) return task((WriteStatRequest*)request); case WRITE_STAT_REPLY: return task((WriteStatReply*)request); - case ACCESS_REQUEST: - return task((AccessRequest*)request); - case ACCESS_REPLY: - return task((AccessReply*)request); // files case CREATE_REQUEST: return task((CreateRequest*)request); @@ -1502,52 +1555,15 @@ do_for_request(Request* request, Task& task) return task((WriteRequest*)request); case WRITE_REPLY: return task((WriteReply*)request); - case IOCTL_REQUEST: - return task((IOCtlRequest*)request); - case IOCTL_REPLY: - return task((IOCtlReply*)request); - case SET_FLAGS_REQUEST: - return task((SetFlagsRequest*)request); - case SET_FLAGS_REPLY: - return task((SetFlagsReply*)request); - case SELECT_REQUEST: - return task((SelectRequest*)request); - case SELECT_REPLY: - return task((SelectReply*)request); - case DESELECT_REQUEST: - return task((DeselectRequest*)request); - case DESELECT_REPLY: - return task((DeselectReply*)request); - // hard links / symlinks - case LINK_REQUEST: - return task((LinkRequest*)request); - case LINK_REPLY: - return task((LinkReply*)request); - case UNLINK_REQUEST: - return task((UnlinkRequest*)request); - case UNLINK_REPLY: - return task((UnlinkReply*)request); - case SYMLINK_REQUEST: - return task((SymlinkRequest*)request); - case SYMLINK_REPLY: - return task((SymlinkReply*)request); - case READ_LINK_REQUEST: - return task((ReadLinkRequest*)request); - case READ_LINK_REPLY: - return task((ReadLinkReply*)request); - case RENAME_REQUEST: - return task((RenameRequest*)request); - case RENAME_REPLY: - return task((RenameReply*)request); // directories - case MKDIR_REQUEST: - return task((MkDirRequest*)request); - case MKDIR_REPLY: - return task((MkDirReply*)request); - case RMDIR_REQUEST: - return task((RmDirRequest*)request); - case RMDIR_REPLY: - return task((RmDirReply*)request); + case CREATE_DIR_REQUEST: + return task((CreateDirRequest*)request); + case CREATE_DIR_REPLY: + return task((CreateDirReply*)request); + case REMOVE_DIR_REQUEST: + return task((RemoveDirRequest*)request); + case REMOVE_DIR_REPLY: + return task((RemoveDirReply*)request); case OPEN_DIR_REQUEST: return task((OpenDirRequest*)request); case OPEN_DIR_REPLY: @@ -1568,11 +1584,7 @@ do_for_request(Request* request, Task& task) return task((RewindDirRequest*)request); case REWIND_DIR_REPLY: return task((RewindDirReply*)request); - case WALK_REQUEST: - return task((WalkRequest*)request); - case WALK_REPLY: - return task((WalkReply*)request); - // attributes + // attribute directories case OPEN_ATTR_DIR_REQUEST: return task((OpenAttrDirRequest*)request); case OPEN_ATTR_DIR_REPLY: @@ -1593,6 +1605,7 @@ do_for_request(Request* request, Task& task) return task((RewindAttrDirRequest*)request); case REWIND_ATTR_DIR_REPLY: return task((RewindAttrDirReply*)request); + // attributes case READ_ATTR_REQUEST: return task((ReadAttrRequest*)request); case READ_ATTR_REPLY: @@ -1601,18 +1614,18 @@ do_for_request(Request* request, Task& task) return task((WriteAttrRequest*)request); case WRITE_ATTR_REPLY: return task((WriteAttrReply*)request); - case REMOVE_ATTR_REQUEST: - return task((RemoveAttrRequest*)request); - case REMOVE_ATTR_REPLY: - return task((RemoveAttrReply*)request); + case READ_ATTR_STAT_REQUEST: + return task((ReadAttrStatRequest*)request); + case READ_ATTR_STAT_REPLY: + return task((ReadAttrStatReply*)request); case RENAME_ATTR_REQUEST: return task((RenameAttrRequest*)request); case RENAME_ATTR_REPLY: return task((RenameAttrReply*)request); - case STAT_ATTR_REQUEST: - return task((StatAttrRequest*)request); - case STAT_ATTR_REPLY: - return task((StatAttrReply*)request); + case REMOVE_ATTR_REQUEST: + return task((RemoveAttrRequest*)request); + case REMOVE_ATTR_REPLY: + return task((RemoveAttrReply*)request); // indices case OPEN_INDEX_DIR_REQUEST: return task((OpenIndexDirRequest*)request); @@ -1642,14 +1655,10 @@ do_for_request(Request* request, Task& task) return task((RemoveIndexRequest*)request); case REMOVE_INDEX_REPLY: return task((RemoveIndexReply*)request); - case RENAME_INDEX_REQUEST: - return task((RenameIndexRequest*)request); - case RENAME_INDEX_REPLY: - return task((RenameIndexReply*)request); - case STAT_INDEX_REQUEST: - return task((StatIndexRequest*)request); - case STAT_INDEX_REPLY: - return task((StatIndexReply*)request); + case READ_INDEX_STAT_REQUEST: + return task((ReadIndexStatRequest*)request); + case READ_INDEX_STAT_REPLY: + return task((ReadIndexStatReply*)request); // queries case OPEN_QUERY_REQUEST: return task((OpenQueryRequest*)request); @@ -1742,15 +1751,17 @@ using UserlandFSUtil::MountVolumeRequest; using UserlandFSUtil::MountVolumeReply; using UserlandFSUtil::UnmountVolumeRequest; using UserlandFSUtil::UnmountVolumeReply; -using UserlandFSUtil::InitializeVolumeRequest; -using UserlandFSUtil::InitializeVolumeReply; +//using UserlandFSUtil::InitializeVolumeRequest; +//using UserlandFSUtil::InitializeVolumeReply; using UserlandFSUtil::SyncVolumeRequest; using UserlandFSUtil::SyncVolumeReply; -using UserlandFSUtil::ReadFSStatRequest; -using UserlandFSUtil::ReadFSStatReply; -using UserlandFSUtil::WriteFSStatRequest; -using UserlandFSUtil::WriteFSStatReply; +using UserlandFSUtil::ReadFSInfoRequest; +using UserlandFSUtil::ReadFSInfoReply; +using UserlandFSUtil::WriteFSInfoRequest; +using UserlandFSUtil::WriteFSInfoReply; // vnodes +using UserlandFSUtil::LookupRequest; +using UserlandFSUtil::LookupReply; using UserlandFSUtil::ReadVNodeRequest; using UserlandFSUtil::ReadVNodeReply; using UserlandFSUtil::WriteVNodeRequest; @@ -1758,14 +1769,32 @@ using UserlandFSUtil::WriteVNodeReply; using UserlandFSUtil::FSRemoveVNodeRequest; using UserlandFSUtil::FSRemoveVNodeReply; // nodes +using UserlandFSUtil::IOCtlRequest; +using UserlandFSUtil::IOCtlReply; +using UserlandFSUtil::SetFlagsRequest; +using UserlandFSUtil::SetFlagsReply; +using UserlandFSUtil::SelectRequest; +using UserlandFSUtil::SelectReply; +using UserlandFSUtil::DeselectRequest; +using UserlandFSUtil::DeselectReply; using UserlandFSUtil::FSyncRequest; using UserlandFSUtil::FSyncReply; +using UserlandFSUtil::ReadSymlinkRequest; +using UserlandFSUtil::ReadSymlinkReply; +using UserlandFSUtil::CreateSymlinkRequest; +using UserlandFSUtil::CreateSymlinkReply; +using UserlandFSUtil::LinkRequest; +using UserlandFSUtil::LinkReply; +using UserlandFSUtil::UnlinkRequest; +using UserlandFSUtil::UnlinkReply; +using UserlandFSUtil::RenameRequest; +using UserlandFSUtil::RenameReply; +using UserlandFSUtil::AccessRequest; +using UserlandFSUtil::AccessReply; using UserlandFSUtil::ReadStatRequest; using UserlandFSUtil::ReadStatReply; using UserlandFSUtil::WriteStatRequest; using UserlandFSUtil::WriteStatReply; -using UserlandFSUtil::AccessRequest; -using UserlandFSUtil::AccessReply; // files using UserlandFSUtil::CreateRequest; using UserlandFSUtil::CreateReply; @@ -1779,30 +1808,11 @@ using UserlandFSUtil::ReadRequest; using UserlandFSUtil::ReadReply; using UserlandFSUtil::WriteRequest; using UserlandFSUtil::WriteReply; -using UserlandFSUtil::IOCtlRequest; -using UserlandFSUtil::IOCtlReply; -using UserlandFSUtil::SetFlagsRequest; -using UserlandFSUtil::SetFlagsReply; -using UserlandFSUtil::SelectRequest; -using UserlandFSUtil::SelectReply; -using UserlandFSUtil::DeselectRequest; -using UserlandFSUtil::DeselectReply; -// hard links / symlinks -using UserlandFSUtil::LinkRequest; -using UserlandFSUtil::LinkReply; -using UserlandFSUtil::UnlinkRequest; -using UserlandFSUtil::UnlinkReply; -using UserlandFSUtil::SymlinkRequest; -using UserlandFSUtil::SymlinkReply; -using UserlandFSUtil::ReadLinkRequest; -using UserlandFSUtil::ReadLinkReply; -using UserlandFSUtil::RenameRequest; -using UserlandFSUtil::RenameReply; // directories -using UserlandFSUtil::MkDirRequest; -using UserlandFSUtil::MkDirReply; -using UserlandFSUtil::RmDirRequest; -using UserlandFSUtil::RmDirReply; +using UserlandFSUtil::CreateDirRequest; +using UserlandFSUtil::CreateDirReply; +using UserlandFSUtil::RemoveDirRequest; +using UserlandFSUtil::RemoveDirReply; using UserlandFSUtil::OpenDirRequest; using UserlandFSUtil::OpenDirReply; using UserlandFSUtil::CloseDirRequest; @@ -1813,9 +1823,7 @@ using UserlandFSUtil::ReadDirRequest; using UserlandFSUtil::ReadDirReply; using UserlandFSUtil::RewindDirRequest; using UserlandFSUtil::RewindDirReply; -using UserlandFSUtil::WalkRequest; -using UserlandFSUtil::WalkReply; -// attributes +// attribute directories using UserlandFSUtil::OpenAttrDirRequest; using UserlandFSUtil::OpenAttrDirReply; using UserlandFSUtil::CloseAttrDirRequest; @@ -1826,16 +1834,17 @@ using UserlandFSUtil::ReadAttrDirRequest; using UserlandFSUtil::ReadAttrDirReply; using UserlandFSUtil::RewindAttrDirRequest; using UserlandFSUtil::RewindAttrDirReply; +// attributes using UserlandFSUtil::ReadAttrRequest; using UserlandFSUtil::ReadAttrReply; using UserlandFSUtil::WriteAttrRequest; using UserlandFSUtil::WriteAttrReply; -using UserlandFSUtil::RemoveAttrRequest; -using UserlandFSUtil::RemoveAttrReply; +using UserlandFSUtil::ReadAttrStatRequest; +using UserlandFSUtil::ReadAttrStatReply; using UserlandFSUtil::RenameAttrRequest; using UserlandFSUtil::RenameAttrReply; -using UserlandFSUtil::StatAttrRequest; -using UserlandFSUtil::StatAttrReply; +using UserlandFSUtil::RemoveAttrRequest; +using UserlandFSUtil::RemoveAttrReply; // indices using UserlandFSUtil::OpenIndexDirRequest; using UserlandFSUtil::OpenIndexDirReply; @@ -1851,10 +1860,8 @@ using UserlandFSUtil::CreateIndexRequest; using UserlandFSUtil::CreateIndexReply; using UserlandFSUtil::RemoveIndexRequest; using UserlandFSUtil::RemoveIndexReply; -using UserlandFSUtil::RenameIndexRequest; -using UserlandFSUtil::RenameIndexReply; -using UserlandFSUtil::StatIndexRequest; -using UserlandFSUtil::StatIndexReply; +using UserlandFSUtil::ReadIndexStatRequest; +using UserlandFSUtil::ReadIndexStatReply; // queries using UserlandFSUtil::OpenQueryRequest; using UserlandFSUtil::OpenQueryReply; diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/FileSystem.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/FileSystem.cpp index 0ef2442d34..a5e453a7d9 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/FileSystem.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/FileSystem.cpp @@ -81,26 +81,29 @@ FileSystem::GetPortPool() // Mount status_t -FileSystem::Mount(nspace_id id, const char* device, ulong flags, - const char* parameters, int32 len, Volume** _volume) +FileSystem::Mount(mount_id id, const char* device, uint32 flags, + const char* parameters, Volume** _volume) { // check initialization and parameters if (InitCheck() != B_OK) return InitCheck(); if (!_volume) return B_BAD_VALUE; + // create volume Volume* volume = new(nothrow) Volume(this, id); if (!volume) return B_NO_MEMORY; + // add volume to the volume list fVolumeLock.Lock(); status_t error = fVolumes.PushBack(volume); fVolumeLock.Unlock(); if (error != B_OK) return error; + // mount volume - error = volume->Mount(device, flags, parameters, len); + error = volume->Mount(device, flags, parameters); if (error != B_OK) { fVolumeLock.Lock(); fVolumes.Remove(volume); @@ -108,12 +111,13 @@ FileSystem::Mount(nspace_id id, const char* device, ulong flags, volume->RemoveReference(); return error; } + *_volume = volume; return error; } // Initialize -status_t +/*status_t FileSystem::Initialize(const char* deviceName, const char* parameters, size_t len) { @@ -144,7 +148,7 @@ FileSystem::Initialize(const char* deviceName, const char* parameters, if (reply->error != B_OK) return reply->error; return error; -} +}*/ // VolumeUnmounted void @@ -157,7 +161,7 @@ FileSystem::VolumeUnmounted(Volume* volume) // GetVolume Volume* -FileSystem::GetVolume(nspace_id id) +FileSystem::GetVolume(mount_id id) { AutoLocker _(fVolumeLock); for (Vector::Iterator it = fVolumes.Begin(); diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/FileSystem.h b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/FileSystem.h index 47fe5db665..cda97242fe 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/FileSystem.h +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/FileSystem.h @@ -3,7 +3,7 @@ #ifndef USERLAND_FS_FILE_SYSTEM_H #define USERLAND_FS_FILE_SYSTEM_H -#include +#include #include "LazyInitializable.h" #include "Locker.h" @@ -35,14 +35,14 @@ public: RequestPortPool* GetPortPool(); - status_t Mount(nspace_id id, const char* device, + status_t Mount(mount_id id, const char* device, ulong flags, const char* parameters, - int32 len, Volume** volume); - status_t Initialize(const char* deviceName, - const char* parameters, size_t len); + Volume** volume); +// status_t Initialize(const char* deviceName, +// const char* parameters, size_t len); void VolumeUnmounted(Volume* volume); - Volume* GetVolume(nspace_id id); + Volume* GetVolume(mount_id id); const IOCtlInfo* GetIOCtlInfo(int command) const; diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp index 9049a5b444..92140327a0 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp @@ -8,6 +8,8 @@ #include "Requests.h" #include "Volume.h" +#include + // VolumePutter class VolumePutter { public: @@ -140,7 +142,7 @@ KernelRequestHandler::_HandleRequest(NotifySelectEventRequest* request) status_t result = B_OK; if (fFileSystem->KnowsSelectSyncEntry(request->sync)) { PRINT(("notify_select_event(%p, %lu)\n", request->sync, request->ref)); - notify_select_event(request->sync, request->ref); + notify_select_event(request->sync, request->ref, request->event); } else result = B_BAD_VALUE; // prepare the reply @@ -338,7 +340,7 @@ KernelRequestHandler::_HandleRequest(IsVNodeRemovedRequest* request) // _GetVolume status_t -KernelRequestHandler::_GetVolume(nspace_id id, Volume** volume) +KernelRequestHandler::_GetVolume(mount_id id, Volume** volume) { if (fVolume) { if (fVolume->GetID() != id) { diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h index dd5ed99ed7..3beb6caead 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h @@ -3,7 +3,7 @@ #ifndef USERLAND_FS_KERNEL_REQUEST_HANDLER_H #define USERLAND_FS_KERNEL_REQUEST_HANDLER_H -#include +#include #include "RequestHandler.h" @@ -59,7 +59,7 @@ private: status_t _HandleRequest(UnremoveVNodeRequest* request); status_t _HandleRequest(IsVNodeRemovedRequest* request); - status_t _GetVolume(nspace_id id, Volume** volume); + status_t _GetVolume(mount_id id, Volume** volume); private: FileSystem* fFileSystem; diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Settings.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Settings.cpp index a826edb05f..9e75851373 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Settings.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Settings.cpp @@ -202,16 +202,18 @@ Settings::GetIOCtlInfo(int command) const void Settings::Dump() const { - PRINT(("Settings:\n")); - if (fIOCtlInfos) { - for (IOCtlInfoMap::Iterator it = fIOCtlInfos->GetIterator(); - it.HasNext();) { - IOCtlInfoMap::Entry entry = it.Next(); - IOCtlInfo* info = entry.value; - PRINT((" ioctl %d: buffer size: %ld, write buffer size: %ld\n", - info->command, info->bufferSize, info->writeBufferSize)); + D( + PRINT(("Settings:\n")); + if (fIOCtlInfos) { + for (IOCtlInfoMap::Iterator it = fIOCtlInfos->GetIterator(); + it.HasNext();) { + IOCtlInfoMap::Entry entry = it.Next(); + IOCtlInfo* info = entry.value; + PRINT((" ioctl %d: buffer size: %ld, write buffer size: %ld\n", + info->command, info->bufferSize, info->writeBufferSize)); + } } - } + ) } // _Init diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/UserlandFS.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/UserlandFS.cpp index c64ab1f5ec..aa94da1d3e 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/UserlandFS.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/UserlandFS.cpp @@ -14,18 +14,14 @@ typedef AutoLocker FileSystemLocker; -UserlandFS* volatile UserlandFS::sUserlandFS = NULL; -spinlock UserlandFS::sUserlandFSLock = 0; -vint32 UserlandFS::sMountedFileSystems = 0; +UserlandFS* UserlandFS::sUserlandFS = NULL; // constructor UserlandFS::UserlandFS() - : LazyInitializable(), - fPort(NULL), + : fPort(NULL), fFileSystems(NULL), fDebuggerCommandsAdded(false) { - // beware what you do here: the caller holds a spin lock } // destructor @@ -50,88 +46,34 @@ PRINT(("UserlandFS::~UserlandFS()\n")) KernelDebug::RemoveDebuggerCommands(); } -// RegisterUserlandFS +// InitUserlandFS status_t -UserlandFS::RegisterUserlandFS(UserlandFS** _userlandFS) +UserlandFS::InitUserlandFS(UserlandFS** _userlandFS) { - // first check, if there's already an instance - bool create = false; + // create the singleton instance + sUserlandFS = new(nothrow) UserlandFS; + if (!sUserlandFS) + return B_NO_MEMORY; - cpu_status cpuStatus = disable_interrupts(); - acquire_spinlock(&sUserlandFSLock); - - if (sUserlandFS) - sMountedFileSystems++; - else - create = true; - - release_spinlock(&sUserlandFSLock); - restore_interrupts(cpuStatus); - - // if there's not, create a new - status_t error = B_OK; - if (create) { - // first create an instance - // Note, that we can't even construct a LazyInitializable with a - // spinlock being held, since it allocates a semaphore, which may - // allocate memory, which will acquire a semaphore. - UserlandFS* userlandFS = new(nothrow) UserlandFS; - if (userlandFS) { - // now set the instance unless someone else beat us to it - bool deleteInstance = false; - - cpu_status cpuStatus = disable_interrupts(); - acquire_spinlock(&sUserlandFSLock); - - sMountedFileSystems++; - if (sUserlandFS) - deleteInstance = true; - else - sUserlandFS = userlandFS; - - release_spinlock(&sUserlandFSLock); - restore_interrupts(cpuStatus); - - // delete the new instance, if there was one already - if (deleteInstance) - delete userlandFS; - } else - error = B_NO_MEMORY; - } - if (error != B_OK) + // init the thing + status_t error = sUserlandFS->_Init(); + if (error != B_OK) { + delete sUserlandFS; + sUserlandFS = NULL; return error; + } - // init the thing, if necessary - error = sUserlandFS->Access(); - if (error == B_OK) - *_userlandFS = sUserlandFS; - else - UnregisterUserlandFS(); - return error; + *_userlandFS = sUserlandFS; + + return B_OK; } -// UnregisterUserlandFS +// UninitUserlandFS void -UserlandFS::UnregisterUserlandFS() +UserlandFS::UninitUserlandFS() { - cpu_status cpuStatus = disable_interrupts(); - acquire_spinlock(&sUserlandFSLock); - - --sMountedFileSystems; - UserlandFS* userlandFS = NULL; - if (sMountedFileSystems == 0 && sUserlandFS) { - userlandFS = sUserlandFS; - sUserlandFS = NULL; - } - - release_spinlock(&sUserlandFSLock); - restore_interrupts(cpuStatus); - - // delete, if the last FS has been unmounted - if (userlandFS) { - userlandFS->~UserlandFS(); - delete[] (uint8*)userlandFS; - } + delete sUserlandFS; + sUserlandFS = NULL; } // GetUserlandFS @@ -145,11 +87,10 @@ UserlandFS::GetUserlandFS() status_t UserlandFS::RegisterFileSystem(const char* name, FileSystem** _fileSystem) { - // check initialization and parameters - if (InitCheck() != B_OK) - return InitCheck(); + // check parameters if (!name || !_fileSystem) return B_BAD_VALUE; + // check, if we do already know this file system, and create it, if not FileSystem* fileSystem; { @@ -170,12 +111,14 @@ UserlandFS::RegisterFileSystem(const char* name, FileSystem** _fileSystem) } } } + // prepare the file system status_t error = fileSystem->Access(); if (error != B_OK) { UnregisterFileSystem(fileSystem); return error; } + *_fileSystem = fileSystem; return error; } @@ -186,6 +129,7 @@ UserlandFS::UnregisterFileSystem(FileSystem* fileSystem) { if (!fileSystem) return B_BAD_VALUE; + // find the FS and decrement its reference counter bool deleteFS = false; { @@ -197,6 +141,7 @@ UserlandFS::UnregisterFileSystem(FileSystem* fileSystem) if (deleteFS) fFileSystems->Remove(fileSystem->GetName()); } + // delete the FS, if the last reference has been removed if (deleteFS) delete fileSystem; @@ -210,13 +155,14 @@ UserlandFS::CountFileSystems() const return fFileSystems->Size(); } -// FirstTimeInit +// _Init status_t -UserlandFS::FirstTimeInit() +UserlandFS::_Init() { // add debugger commands KernelDebug::AddDebuggerCommands(); fDebuggerCommandsAdded = true; + // create file system map fFileSystems = new(nothrow) FileSystemMap; if (!fFileSystems) @@ -224,6 +170,7 @@ UserlandFS::FirstTimeInit() status_t error = fFileSystems->InitCheck(); if (error != B_OK) RETURN_ERROR(error); + // find the dispatcher ports port_id port = find_port(kUserlandFSDispatcherPortName); if (port < 0) @@ -231,11 +178,13 @@ UserlandFS::FirstTimeInit() port_id replyPort = find_port(kUserlandFSDispatcherReplyPortName); if (replyPort < 0) RETURN_ERROR(B_ERROR); + // create a reply port // send a connection request error = write_port(port, UFS_DISPATCHER_CONNECT, NULL, 0); if (error != B_OK) RETURN_ERROR(error); + // receive the reply int32 replyCode; Port::Info portInfo; @@ -247,12 +196,14 @@ UserlandFS::FirstTimeInit() RETURN_ERROR(B_BAD_DATA); if (bytesRead != sizeof(Port::Info)) RETURN_ERROR(B_BAD_DATA); + // create a request port fPort = new(nothrow) RequestPort(&portInfo); if (!fPort) RETURN_ERROR(B_NO_MEMORY); if ((error = fPort->InitCheck()) != B_OK) RETURN_ERROR(error); + RETURN_ERROR(error); } diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/UserlandFS.h b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/UserlandFS.h index 5982376747..1486894030 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/UserlandFS.h +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/UserlandFS.h @@ -6,7 +6,6 @@ #include #include "HashMap.h" -#include "LazyInitializable.h" #include "String.h" namespace UserlandFSUtil { @@ -19,14 +18,14 @@ using UserlandFSUtil::RequestPort; class FileSystem; -class UserlandFS : public LazyInitializable { +class UserlandFS { private: UserlandFS(); ~UserlandFS(); public: - static status_t RegisterUserlandFS(UserlandFS** userlandFS); - static void UnregisterUserlandFS(); + static status_t InitUserlandFS(UserlandFS** userlandFS); + static void UninitUserlandFS(); static UserlandFS* GetUserlandFS(); status_t RegisterFileSystem(const char* name, @@ -35,16 +34,14 @@ public: int32 CountFileSystems() const; -protected: - virtual status_t FirstTimeInit(); +private: + status_t _Init(); private: friend class KernelDebug; typedef SynchronizedHashMap FileSystemMap; - static UserlandFS* volatile sUserlandFS; - static spinlock sUserlandFSLock; - static vint32 sMountedFileSystems; + static UserlandFS* sUserlandFS; RequestPort* fPort; FileSystemMap* fFileSystems; diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp index c741db9932..bf2bd08f9a 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp @@ -17,6 +17,12 @@ #include "userlandfs_ioctl.h" #include "Volume.h" +// missing ioctl()s +// TODO: Place somewhere else. +#define IOCTL_FILE_UNCACHED_IO 10000 +#define IOCTL_CREATE_TIME 10002 +#define IOCTL_MODIFIED_TIME 10003 + // If a thread of the userland server enters userland FS kernel code and // is sending a request, this is the time after which it shall time out // waiting for a reply. @@ -57,7 +63,7 @@ private: }; // constructor -Volume::Volume(FileSystem* fileSystem, nspace_id id) +Volume::Volume(FileSystem* fileSystem, mount_id id) : Referencable(true), fFileSystem(fileSystem), fID(id), @@ -88,7 +94,7 @@ Volume::GetFileSystem() const } // GetID -nspace_id +mount_id Volume::GetID() const { return fID; @@ -116,12 +122,11 @@ Volume::IsMounting() const } -// #pragma mark - -// #pragma mark ----- client methods ----- +// #pragma mark - client methods // GetVNode status_t -Volume::GetVNode(vnode_id vnid, void** node) +Volume::GetVNode(vnode_id vnid, fs_vnode* node) { PRINT(("get_vnode(%ld, %Ld)\n", fID, vnid)); if (IsMounting() && !fMountVNodes->ContainsKey(vnid)) { @@ -147,7 +152,7 @@ PRINT(("put_vnode(%ld, %Ld)\n", fID, vnid)); // NewVNode status_t -Volume::NewVNode(vnode_id vnid, void* node) +Volume::NewVNode(vnode_id vnid, fs_vnode node) { PRINT(("new_vnode(%ld, %Ld)\n", fID, vnid)); status_t error = new_vnode(fID, vnid, node); @@ -187,16 +192,18 @@ status_t Volume::IsVNodeRemoved(vnode_id vnid) { PRINT(("is_vnode_removed(%ld, %Ld)\n", fID, vnid)); - return is_vnode_removed(fID, vnid); +// return is_vnode_removed(fID, vnid); +// TODO: Add this function? +return false; } -// #pragma mark - -// #pragma mark ----- FS ----- + +// #pragma mark - FS + // Mount status_t -Volume::Mount(const char* device, ulong flags, const char* parameters, - int32 len) +Volume::Mount(const char* device, uint32 flags, const char* parameters) { // Create a map that holds vnode_id->void* mappings of all vnodes // created while mounting. We need it to get the root node. @@ -204,8 +211,9 @@ Volume::Mount(const char* device, ulong flags, const char* parameters, status_t error = vnodeMap.InitCheck(); if (error != B_OK) RETURN_ERROR(error); + fMountVNodes = &vnodeMap; - error = _Mount(device, flags, parameters, len); + error = _Mount(device, flags, parameters); fMountVNodes = NULL; if (error == B_OK) { // fetch the root node, so that we can serve Walk() requests on it, @@ -254,13 +262,16 @@ Volume::Sync() if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); SyncVolumeRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; + // send the request KernelRequestHandler handler(this, SYNC_VOLUME_REPLY); SyncVolumeReply* reply; @@ -268,35 +279,40 @@ Volume::Sync() if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; return error; } -// ReadFSStat +// ReadFSInfo status_t -Volume::ReadFSStat(fs_info* info) +Volume::ReadFSInfo(fs_info* info) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); - ReadFSStatRequest* request; + ReadFSInfoRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; + // send the request - KernelRequestHandler handler(this, READ_FS_STAT_REPLY); - ReadFSStatReply* reply; + KernelRequestHandler handler(this, READ_FS_INFO_REPLY); + ReadFSInfoReply* reply; error = _SendRequest(port, &allocator, &handler, (Request**)&reply); if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -304,58 +320,88 @@ Volume::ReadFSStat(fs_info* info) return error; } -// WriteFSStat +// WriteFSInfo status_t -Volume::WriteFSStat(struct fs_info *info, long mask) +Volume::WriteFSInfo(const struct fs_info *info, uint32 mask) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); - WriteFSStatRequest* request; + WriteFSInfoRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->info = *info; request->mask = mask; + // send the request - KernelRequestHandler handler(this, WRITE_FS_STAT_REPLY); - WriteFSStatReply* reply; + KernelRequestHandler handler(this, WRITE_FS_INFO_REPLY); + WriteFSInfoReply* reply; error = _SendRequest(port, &allocator, &handler, (Request**)&reply); if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; return error; } -// #pragma mark - -// #pragma mark ----- vnodes ----- + +// #pragma mark - vnodes + + +// Lookup +status_t +Volume::Lookup(fs_vnode dir, const char* entryName, vnode_id* vnid, int* type) +{ + // When the connection to the userland server is lost, we serve + // lookup(fRootNode, `.') requests manually to allow clean unmounting. + status_t error = _Lookup(dir, entryName, vnid, type); + if (error != B_OK && fFileSystem->GetPortPool()->IsDisconnected() + && dir == fRootNode && strcmp(entryName, ".") == 0) { + WARN(("Volume::Lookup(): connection lost, emulating lookup `.'\n")); + void* entryNode; + if (GetVNode(fRootID, &entryNode) != B_OK) + RETURN_ERROR(B_BAD_VALUE); + *vnid = fRootID; + *type = S_IFDIR; + // The VFS will balance the get_vnode() call for the FS. + _DecrementVNodeCount(*vnid); + return B_OK; + } + return error; +} // ReadVNode status_t -Volume::ReadVNode(vnode_id vnid, char reenter, void** node) +Volume::ReadVNode(vnode_id vnid, bool reenter, fs_vnode* node) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); ReadVNodeRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->vnid = vnid; request->reenter = reenter; + // send the request KernelRequestHandler handler(this, READ_VNODE_REPLY); ReadVNodeReply* reply; @@ -363,6 +409,7 @@ Volume::ReadVNode(vnode_id vnid, char reenter, void** node) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -372,7 +419,7 @@ Volume::ReadVNode(vnode_id vnid, char reenter, void** node) // WriteVNode status_t -Volume::WriteVNode(void* node, char reenter) +Volume::WriteVNode(fs_vnode node, bool reenter) { status_t error = _WriteVNode(node, reenter); if (error != B_OK && fFileSystem->GetPortPool()->IsDisconnected()) { @@ -387,22 +434,25 @@ Volume::WriteVNode(void* node, char reenter) // RemoveVNode status_t -Volume::RemoveVNode(void* node, char reenter) +Volume::RemoveVNode(fs_vnode node, bool reenter) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); FSRemoveVNodeRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->reenter = reenter; + // send the request KernelRequestHandler handler(this, FS_REMOVE_VNODE_REPLY); FSRemoveVNodeReply* reply; @@ -410,335 +460,20 @@ Volume::RemoveVNode(void* node, char reenter) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; return error; } -// #pragma mark - -// #pragma mark ----- nodes ----- -// FSync -status_t -Volume::FSync(void* node) -{ - // get a free port - RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); - if (!port) - return B_ERROR; - PortReleaser _(fFileSystem->GetPortPool(), port); - // prepare the request - RequestAllocator allocator(port->GetPort()); - FSyncRequest* request; - status_t error = AllocateRequest(allocator, &request); - if (error != B_OK) - return error; - request->volume = fUserlandVolume; - request->node = node; - // send the request - KernelRequestHandler handler(this, FSYNC_REPLY); - FSyncReply* reply; - error = _SendRequest(port, &allocator, &handler, (Request**)&reply); - if (error != B_OK) - return error; - RequestReleaser requestReleaser(port, reply); - // process the reply - if (reply->error != B_OK) - return reply->error; - return error; -} +// #pragma mark - nodes -// ReadStat -status_t -Volume::ReadStat(void* node, struct stat* st) -{ - // get a free port - RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); - if (!port) - return B_ERROR; - PortReleaser _(fFileSystem->GetPortPool(), port); - // prepare the request - RequestAllocator allocator(port->GetPort()); - ReadStatRequest* request; - status_t error = AllocateRequest(allocator, &request); - if (error != B_OK) - return error; - request->volume = fUserlandVolume; - request->node = node; - // send the request - KernelRequestHandler handler(this, READ_STAT_REPLY); - ReadStatReply* reply; - error = _SendRequest(port, &allocator, &handler, (Request**)&reply); - if (error != B_OK) - return error; - RequestReleaser requestReleaser(port, reply); - // process the reply - if (reply->error != B_OK) - return reply->error; - *st = reply->st; - return error; -} - -// WriteStat -status_t -Volume::WriteStat(void* node, struct stat* st, long mask) -{ - // get a free port - RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); - if (!port) - return B_ERROR; - PortReleaser _(fFileSystem->GetPortPool(), port); - // prepare the request - RequestAllocator allocator(port->GetPort()); - WriteStatRequest* request; - status_t error = AllocateRequest(allocator, &request); - if (error != B_OK) - return error; - request->volume = fUserlandVolume; - request->node = node; - request->st = *st; - request->mask = mask; - // send the request - KernelRequestHandler handler(this, WRITE_STAT_REPLY); - WriteStatReply* reply; - error = _SendRequest(port, &allocator, &handler, (Request**)&reply); - if (error != B_OK) - return error; - RequestReleaser requestReleaser(port, reply); - // process the reply - if (reply->error != B_OK) - return reply->error; - return error; -} - -// Access -status_t -Volume::Access(void* node, int mode) -{ - // get a free port - RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); - if (!port) - return B_ERROR; - PortReleaser _(fFileSystem->GetPortPool(), port); - // prepare the request - RequestAllocator allocator(port->GetPort()); - AccessRequest* request; - status_t error = AllocateRequest(allocator, &request); - if (error != B_OK) - return error; - request->volume = fUserlandVolume; - request->node = node; - request->mode = mode; - // send the request - KernelRequestHandler handler(this, ACCESS_REPLY); - AccessReply* reply; - error = _SendRequest(port, &allocator, &handler, (Request**)&reply); - if (error != B_OK) - return error; - RequestReleaser requestReleaser(port, reply); - // process the reply - if (reply->error != B_OK) - return reply->error; - return error; -} - -// #pragma mark - -// #pragma mark ----- files ----- - -// Create -status_t -Volume::Create(void* dir, const char* name, int openMode, int mode, - vnode_id* vnid, void** cookie) -{ - // get a free port - RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); - if (!port) - return B_ERROR; - PortReleaser _(fFileSystem->GetPortPool(), port); - // prepare the request - RequestAllocator allocator(port->GetPort()); - CreateRequest* request; - status_t error = AllocateRequest(allocator, &request); - if (error != B_OK) - return error; - request->volume = fUserlandVolume; - request->node = dir; - error = allocator.AllocateString(request->name, name); - request->openMode = openMode; - request->mode = mode; - if (error != B_OK) - return error; - // send the request - KernelRequestHandler handler(this, CREATE_REPLY); - CreateReply* reply; - error = _SendRequest(port, &allocator, &handler, (Request**)&reply); - if (error != B_OK) - return error; - RequestReleaser requestReleaser(port, reply); - // process the reply - if (reply->error != B_OK) - return reply->error; - *vnid = reply->vnid; - *cookie = reply->fileCookie; - if (error == B_OK) - _DecrementVNodeCount(*vnid); - return error; -} - -// Open -status_t -Volume::Open(void* node, int openMode, void** cookie) -{ - // get a free port - RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); - if (!port) - return B_ERROR; - PortReleaser _(fFileSystem->GetPortPool(), port); - AutoIncrementer incrementer(&fOpenFiles); - // prepare the request - RequestAllocator allocator(port->GetPort()); - OpenRequest* request; - status_t error = AllocateRequest(allocator, &request); - if (error != B_OK) - return error; - request->volume = fUserlandVolume; - request->node = node; - request->openMode = openMode; - // send the request - KernelRequestHandler handler(this, OPEN_REPLY); - OpenReply* reply; - error = _SendRequest(port, &allocator, &handler, (Request**)&reply); - if (error != B_OK) - return error; - RequestReleaser requestReleaser(port, reply); - // process the reply - if (reply->error != B_OK) - return reply->error; - incrementer.Keep(); - *cookie = reply->fileCookie; - return error; -} - -// Close -status_t -Volume::Close(void* node, void* cookie) -{ - status_t error = _Close(node, cookie); - if (error != B_OK && fFileSystem->GetPortPool()->IsDisconnected()) { - // This isn't really necessary, as the return value is irrelevant to - // the VFS. OBOS ignores it completely. The fsshell returns it to the - // userland, but considers the node closed anyway. - WARN(("Volume::Close(): connection lost, forcing close\n")); - return B_OK; - } - return error; -} - -// FreeCookie -status_t -Volume::FreeCookie(void* node, void* cookie) -{ - status_t error = _FreeCookie(node, cookie); - bool disconnected = false; - if (error != B_OK && fFileSystem->GetPortPool()->IsDisconnected()) { - // This isn't really necessary, as the return value is irrelevant to - // the VFS. It's completely ignored by OBOS as well as by the fsshell. - WARN(("Volume::FreeCookie(): connection lost, forcing free cookie\n")); - error = B_OK; - disconnected = true; - } - int32 openFiles = atomic_add(&fOpenFiles, -1); - if (openFiles <= 1 && disconnected) - _PutAllPendingVNodes(); - return error; -} - -// Read -status_t -Volume::Read(void* node, void* cookie, off_t pos, void* buffer, - size_t bufferSize, size_t* bytesRead) -{ - *bytesRead = 0; - // get a free port - RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); - if (!port) - return B_ERROR; - PortReleaser _(fFileSystem->GetPortPool(), port); - // prepare the request - RequestAllocator allocator(port->GetPort()); - ReadRequest* request; - status_t error = AllocateRequest(allocator, &request); - if (error != B_OK) - return error; - request->volume = fUserlandVolume; - request->node = node; - request->fileCookie = cookie; - request->pos = pos; - request->size = bufferSize; - // send the request - KernelRequestHandler handler(this, READ_REPLY); - ReadReply* reply; - error = _SendRequest(port, &allocator, &handler, (Request**)&reply); - if (error != B_OK) - return error; - RequestReleaser requestReleaser(port, reply); - // process the reply - if (reply->error != B_OK) - return reply->error; - void* readBuffer = reply->buffer.GetData(); - if (reply->bytesRead > (uint32)reply->buffer.GetSize() - || reply->bytesRead > bufferSize) { - return B_BAD_DATA; - } - if (reply->bytesRead > 0) - memcpy(buffer, readBuffer, reply->bytesRead); - *bytesRead = reply->bytesRead; - _SendReceiptAck(port); - return error; -} - -// Write -status_t -Volume::Write(void* node, void* cookie, off_t pos, const void* buffer, - size_t size, size_t* bytesWritten) -{ - *bytesWritten = 0; - // get a free port - RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); - if (!port) - return B_ERROR; - PortReleaser _(fFileSystem->GetPortPool(), port); - // prepare the request - RequestAllocator allocator(port->GetPort()); - WriteRequest* request; - status_t error = AllocateRequest(allocator, &request); - if (error != B_OK) - return error; - request->volume = fUserlandVolume; - request->node = node; - request->fileCookie = cookie; - request->pos = pos; - error = allocator.AllocateData(request->buffer, buffer, size, 1); - if (error != B_OK) - return error; - // send the request - KernelRequestHandler handler(this, WRITE_REPLY); - WriteReply* reply; - error = _SendRequest(port, &allocator, &handler, (Request**)&reply); - if (error != B_OK) - return error; - RequestReleaser requestReleaser(port, reply); - // process the reply - if (reply->error != B_OK) - return reply->error; - *bytesWritten = reply->bytesWritten; - return error; -} // IOCtl status_t -Volume::IOCtl(void* node, void* cookie, int command, void *buffer, +Volume::IOCtl(fs_vnode node, fs_cookie cookie, uint32 command, void *buffer, size_t len) { // check the command and its parameters @@ -786,31 +521,37 @@ Volume::IOCtl(void* node, void* cookie, int command, void *buffer, PRINT(("Volume::IOCtl(): unknown command\n")); return B_BAD_VALUE; } + isBuffer = info->isBuffer; bufferSize = info->bufferSize; writeSize = info->writeBufferSize; + // If the buffer shall indeed specify a buffer, check it. if (info->isBuffer) { if (!buffer) { PRINT(("Volume::IOCtl(): buffer is NULL\n")); return B_BAD_VALUE; } + area_id area = area_for(buffer); if (area < 0) { PRINT(("Volume::IOCtl(): bad area\n")); return B_BAD_VALUE; } + area_info info; if (get_area_info(area, &info) != B_OK) { PRINT(("Volume::IOCtl(): failed to get area info\n")); return B_BAD_VALUE; } + int32 areaSize = info.size - ((uint8*)buffer - (uint8*)info.address); if (bufferSize > areaSize || writeSize > areaSize) { PRINT(("Volume::IOCtl(): bad buffer size\n")); return B_BAD_VALUE; } + if (writeSize > 0 && !(info.protection & B_WRITE_AREA)) { PRINT(("Volume::IOCtl(): buffer not writable\n")); return B_BAD_VALUE; @@ -819,17 +560,20 @@ Volume::IOCtl(void* node, void* cookie, int command, void *buffer, break; } } + // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); IOCtlRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->fileCookie = cookie; @@ -838,11 +582,13 @@ Volume::IOCtl(void* node, void* cookie, int command, void *buffer, request->isBuffer = isBuffer; request->lenParameter = len; request->writeSize = writeSize; + if (isBuffer && bufferSize > 0) { error = allocator.AllocateData(request->buffer, buffer, bufferSize, 8); if (error != B_OK) return error; } + // send the request KernelRequestHandler handler(this, IOCTL_REPLY); IOCtlReply* reply; @@ -850,9 +596,11 @@ Volume::IOCtl(void* node, void* cookie, int command, void *buffer, if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; + // Copy back the buffer even if the result is not B_OK. The protocol // is defined by the FS developer and may include writing data into // the buffer in some error cases. @@ -867,23 +615,26 @@ Volume::IOCtl(void* node, void* cookie, int command, void *buffer, // SetFlags status_t -Volume::SetFlags(void* node, void* cookie, int flags) +Volume::SetFlags(fs_vnode node, fs_cookie cookie, int flags) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); SetFlagsRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->fileCookie = cookie; request->flags = flags; + // send the request KernelRequestHandler handler(this, SET_FLAGS_REPLY); SetFlagsReply* reply; @@ -891,6 +642,7 @@ Volume::SetFlags(void* node, void* cookie, int flags) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -899,7 +651,7 @@ Volume::SetFlags(void* node, void* cookie, int flags) // Select status_t -Volume::Select(void* node, void* cookie, uint8 event, uint32 ref, +Volume::Select(fs_vnode node, fs_cookie cookie, uint8 event, uint32 ref, selectsync* sync) { // get a free port @@ -907,22 +659,26 @@ Volume::Select(void* node, void* cookie, uint8 event, uint32 ref, if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); SelectRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->fileCookie = cookie; request->event = event; request->ref = ref; request->sync = sync; + // add a selectsync entry error = fFileSystem->AddSelectSyncEntry(sync); if (error != B_OK) return error; + // send the request KernelRequestHandler handler(this, SELECT_REPLY); SelectReply* reply; @@ -932,6 +688,7 @@ Volume::Select(void* node, void* cookie, uint8 event, uint32 ref, return error; } RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) { fFileSystem->RemoveSelectSyncEntry(sync); @@ -942,7 +699,7 @@ Volume::Select(void* node, void* cookie, uint8 event, uint32 ref, // Deselect status_t -Volume::Deselect(void* node, void* cookie, uint8 event, selectsync* sync) +Volume::Deselect(fs_vnode node, fs_cookie cookie, uint8 event, selectsync* sync) { struct SyncRemover { SyncRemover(FileSystem* fs, selectsync* sync) @@ -952,22 +709,26 @@ Volume::Deselect(void* node, void* cookie, uint8 event, selectsync* sync) FileSystem* fs; selectsync* sync; } syncRemover(fFileSystem, sync); + // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); DeselectRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->fileCookie = cookie; request->event = event; request->sync = sync; + // send the request KernelRequestHandler handler(this, DESELECT_REPLY); DeselectReply* reply; @@ -975,120 +736,51 @@ Volume::Deselect(void* node, void* cookie, uint8 event, selectsync* sync) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; return error; } -// #pragma mark - -// #pragma mark ----- hard links / symlinks ----- - -// Link +// FSync status_t -Volume::Link(void* dir, const char* name, void* node) +Volume::FSync(fs_vnode node) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); - LinkRequest* request; + FSyncRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; - request->node = dir; - error = allocator.AllocateString(request->name, name); - request->target = node; - if (error != B_OK) - return error; + request->node = node; + // send the request - KernelRequestHandler handler(this, LINK_REPLY); - LinkReply* reply; + KernelRequestHandler handler(this, FSYNC_REPLY); + FSyncReply* reply; error = _SendRequest(port, &allocator, &handler, (Request**)&reply); if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; return error; } -// Unlink +// ReadSymlink status_t -Volume::Unlink(void* dir, const char* name) -{ - // get a free port - RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); - if (!port) - return B_ERROR; - PortReleaser _(fFileSystem->GetPortPool(), port); - // prepare the request - RequestAllocator allocator(port->GetPort()); - UnlinkRequest* request; - status_t error = AllocateRequest(allocator, &request); - if (error != B_OK) - return error; - request->volume = fUserlandVolume; - request->node = dir; - error = allocator.AllocateString(request->name, name); - if (error != B_OK) - return error; - // send the request - KernelRequestHandler handler(this, UNLINK_REPLY); - UnlinkReply* reply; - error = _SendRequest(port, &allocator, &handler, (Request**)&reply); - if (error != B_OK) - return error; - RequestReleaser requestReleaser(port, reply); - // process the reply - if (reply->error != B_OK) - return reply->error; - return error; -} - -// Symlink -status_t -Volume::Symlink(void* dir, const char* name, const char* target) -{ - // get a free port - RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); - if (!port) - return B_ERROR; - PortReleaser _(fFileSystem->GetPortPool(), port); - // prepare the request - RequestAllocator allocator(port->GetPort()); - SymlinkRequest* request; - status_t error = AllocateRequest(allocator, &request); - if (error != B_OK) - return error; - request->volume = fUserlandVolume; - request->node = dir; - error = allocator.AllocateString(request->name, name); - if (error == B_OK) - error = allocator.AllocateString(request->target, target); - if (error != B_OK) - return error; - // send the request - KernelRequestHandler handler(this, SYMLINK_REPLY); - SymlinkReply* reply; - error = _SendRequest(port, &allocator, &handler, (Request**)&reply); - if (error != B_OK) - return error; - RequestReleaser requestReleaser(port, reply); - // process the reply - if (reply->error != B_OK) - return reply->error; - return error; -} - -// ReadLink -status_t -Volume::ReadLink(void* node, char* buffer, size_t bufferSize, size_t* bytesRead) +Volume::ReadSymlink(fs_vnode node, char* buffer, size_t bufferSize, + size_t* bytesRead) { *bytesRead = 0; // get a free port @@ -1096,22 +788,26 @@ Volume::ReadLink(void* node, char* buffer, size_t bufferSize, size_t* bytesRead) if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); - ReadLinkRequest* request; + ReadSymlinkRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->size = bufferSize; + // send the request - KernelRequestHandler handler(this, READ_LINK_REPLY); - ReadLinkReply* reply; + KernelRequestHandler handler(this, READ_SYMLINK_REPLY); + ReadSymlinkReply* reply; error = _SendRequest(port, &allocator, &handler, (Request**)&reply); if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -1127,9 +823,125 @@ Volume::ReadLink(void* node, char* buffer, size_t bufferSize, size_t* bytesRead) return error; } +// CreateSymlink +status_t +Volume::CreateSymlink(fs_vnode dir, const char* name, const char* target, + int mode) +{ + // get a free port + RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); + if (!port) + return B_ERROR; + PortReleaser _(fFileSystem->GetPortPool(), port); + + // prepare the request + RequestAllocator allocator(port->GetPort()); + CreateSymlinkRequest* request; + status_t error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + + request->volume = fUserlandVolume; + request->node = dir; + error = allocator.AllocateString(request->name, name); + if (error == B_OK) + error = allocator.AllocateString(request->target, target); + if (error != B_OK) + return error; + request->mode = mode; + + // send the request + KernelRequestHandler handler(this, CREATE_SYMLINK_REPLY); + CreateSymlinkReply* reply; + error = _SendRequest(port, &allocator, &handler, (Request**)&reply); + if (error != B_OK) + return error; + RequestReleaser requestReleaser(port, reply); + + // process the reply + if (reply->error != B_OK) + return reply->error; + return error; +} + +// Link +status_t +Volume::Link(fs_vnode dir, const char* name, fs_vnode node) +{ + // get a free port + RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); + if (!port) + return B_ERROR; + PortReleaser _(fFileSystem->GetPortPool(), port); + + // prepare the request + RequestAllocator allocator(port->GetPort()); + LinkRequest* request; + status_t error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + + request->volume = fUserlandVolume; + request->node = dir; + error = allocator.AllocateString(request->name, name); + request->target = node; + if (error != B_OK) + return error; + + // send the request + KernelRequestHandler handler(this, LINK_REPLY); + LinkReply* reply; + error = _SendRequest(port, &allocator, &handler, (Request**)&reply); + if (error != B_OK) + return error; + RequestReleaser requestReleaser(port, reply); + + // process the reply + if (reply->error != B_OK) + return reply->error; + return error; +} + +// Unlink +status_t +Volume::Unlink(fs_vnode dir, const char* name) +{ + // get a free port + RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); + if (!port) + return B_ERROR; + PortReleaser _(fFileSystem->GetPortPool(), port); + + // prepare the request + RequestAllocator allocator(port->GetPort()); + UnlinkRequest* request; + status_t error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + + request->volume = fUserlandVolume; + request->node = dir; + error = allocator.AllocateString(request->name, name); + if (error != B_OK) + return error; + + // send the request + KernelRequestHandler handler(this, UNLINK_REPLY); + UnlinkReply* reply; + error = _SendRequest(port, &allocator, &handler, (Request**)&reply); + if (error != B_OK) + return error; + RequestReleaser requestReleaser(port, reply); + + // process the reply + if (reply->error != B_OK) + return reply->error; + return error; +} + // Rename status_t -Volume::Rename(void* oldDir, const char* oldName, void* newDir, +Volume::Rename(fs_vnode oldDir, const char* oldName, fs_vnode newDir, const char* newName) { // get a free port @@ -1137,12 +949,14 @@ Volume::Rename(void* oldDir, const char* oldName, void* newDir, if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); RenameRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->oldDir = oldDir; request->newDir = newDir; @@ -1151,6 +965,7 @@ Volume::Rename(void* oldDir, const char* oldName, void* newDir, error = allocator.AllocateString(request->newName, newName); if (error != B_OK) return error; + // send the request KernelRequestHandler handler(this, RENAME_REPLY); RenameReply* reply; @@ -1158,76 +973,403 @@ Volume::Rename(void* oldDir, const char* oldName, void* newDir, if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; return error; } -// #pragma mark - -// #pragma mark ----- directories ----- - -// MkDir +// Access status_t -Volume::MkDir(void* dir, const char* name, int mode) +Volume::Access(fs_vnode node, int mode) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); - MkDirRequest* request; + AccessRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + + request->volume = fUserlandVolume; + request->node = node; + request->mode = mode; + + // send the request + KernelRequestHandler handler(this, ACCESS_REPLY); + AccessReply* reply; + error = _SendRequest(port, &allocator, &handler, (Request**)&reply); + if (error != B_OK) + return error; + RequestReleaser requestReleaser(port, reply); + + // process the reply + if (reply->error != B_OK) + return reply->error; + return error; +} + +// ReadStat +status_t +Volume::ReadStat(fs_vnode node, struct stat* st) +{ + // get a free port + RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); + if (!port) + return B_ERROR; + PortReleaser _(fFileSystem->GetPortPool(), port); + + // prepare the request + RequestAllocator allocator(port->GetPort()); + ReadStatRequest* request; + status_t error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + + request->volume = fUserlandVolume; + request->node = node; + + // send the request + KernelRequestHandler handler(this, READ_STAT_REPLY); + ReadStatReply* reply; + error = _SendRequest(port, &allocator, &handler, (Request**)&reply); + if (error != B_OK) + return error; + RequestReleaser requestReleaser(port, reply); + + // process the reply + if (reply->error != B_OK) + return reply->error; + *st = reply->st; + return error; +} + +// WriteStat +status_t +Volume::WriteStat(fs_vnode node, const struct stat* st, uint32 mask) +{ + // get a free port + RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); + if (!port) + return B_ERROR; + PortReleaser _(fFileSystem->GetPortPool(), port); + + // prepare the request + RequestAllocator allocator(port->GetPort()); + WriteStatRequest* request; + status_t error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + + request->volume = fUserlandVolume; + request->node = node; + request->st = *st; + request->mask = mask; + + // send the request + KernelRequestHandler handler(this, WRITE_STAT_REPLY); + WriteStatReply* reply; + error = _SendRequest(port, &allocator, &handler, (Request**)&reply); + if (error != B_OK) + return error; + RequestReleaser requestReleaser(port, reply); + + // process the reply + if (reply->error != B_OK) + return reply->error; + return error; +} + + +// #pragma mark - files + +// Create +status_t +Volume::Create(fs_vnode dir, const char* name, int openMode, int mode, + void** cookie, vnode_id* vnid) +{ + // get a free port + RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); + if (!port) + return B_ERROR; + PortReleaser _(fFileSystem->GetPortPool(), port); + + // prepare the request + RequestAllocator allocator(port->GetPort()); + CreateRequest* request; + status_t error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + + request->volume = fUserlandVolume; + request->node = dir; + error = allocator.AllocateString(request->name, name); + request->openMode = openMode; + request->mode = mode; + if (error != B_OK) + return error; + + // send the request + KernelRequestHandler handler(this, CREATE_REPLY); + CreateReply* reply; + error = _SendRequest(port, &allocator, &handler, (Request**)&reply); + if (error != B_OK) + return error; + RequestReleaser requestReleaser(port, reply); + + // process the reply + if (reply->error != B_OK) + return reply->error; + *vnid = reply->vnid; + *cookie = reply->fileCookie; + // The VFS will balance the new_vnode() call for the FS. + if (error == B_OK) + _DecrementVNodeCount(*vnid); + return error; +} + +// Open +status_t +Volume::Open(fs_vnode node, int openMode, fs_cookie* cookie) +{ + // get a free port + RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); + if (!port) + return B_ERROR; + PortReleaser _(fFileSystem->GetPortPool(), port); + AutoIncrementer incrementer(&fOpenFiles); + + // prepare the request + RequestAllocator allocator(port->GetPort()); + OpenRequest* request; + status_t error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + request->volume = fUserlandVolume; + request->node = node; + request->openMode = openMode; + + // send the request + KernelRequestHandler handler(this, OPEN_REPLY); + OpenReply* reply; + error = _SendRequest(port, &allocator, &handler, (Request**)&reply); + if (error != B_OK) + return error; + RequestReleaser requestReleaser(port, reply); + + // process the reply + if (reply->error != B_OK) + return reply->error; + incrementer.Keep(); + *cookie = reply->fileCookie; + return error; +} + +// Close +status_t +Volume::Close(fs_vnode node, fs_cookie cookie) +{ + status_t error = _Close(node, cookie); + if (error != B_OK && fFileSystem->GetPortPool()->IsDisconnected()) { + // This isn't really necessary, as the return value is irrelevant to + // the VFS. OBOS ignores it completely. The fsshell returns it to the + // userland, but considers the node closed anyway. + WARN(("Volume::Close(): connection lost, forcing close\n")); + return B_OK; + } + return error; +} + +// FreeCookie +status_t +Volume::FreeCookie(fs_vnode node, fs_cookie cookie) +{ + status_t error = _FreeCookie(node, cookie); + bool disconnected = false; + if (error != B_OK && fFileSystem->GetPortPool()->IsDisconnected()) { + // This isn't really necessary, as the return value is irrelevant to + // the VFS. It's completely ignored by OBOS as well as by the fsshell. + WARN(("Volume::FreeCookie(): connection lost, forcing free cookie\n")); + error = B_OK; + disconnected = true; + } + int32 openFiles = atomic_add(&fOpenFiles, -1); + if (openFiles <= 1 && disconnected) + _PutAllPendingVNodes(); + return error; +} + +// Read +status_t +Volume::Read(fs_vnode node, fs_cookie cookie, off_t pos, void* buffer, + size_t bufferSize, size_t* bytesRead) +{ + *bytesRead = 0; + + // get a free port + RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); + if (!port) + return B_ERROR; + PortReleaser _(fFileSystem->GetPortPool(), port); + + // prepare the request + RequestAllocator allocator(port->GetPort()); + ReadRequest* request; + status_t error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + + request->volume = fUserlandVolume; + request->node = node; + request->fileCookie = cookie; + request->pos = pos; + request->size = bufferSize; + + // send the request + KernelRequestHandler handler(this, READ_REPLY); + ReadReply* reply; + error = _SendRequest(port, &allocator, &handler, (Request**)&reply); + if (error != B_OK) + return error; + RequestReleaser requestReleaser(port, reply); + + // process the reply + if (reply->error != B_OK) + return reply->error; + void* readBuffer = reply->buffer.GetData(); + if (reply->bytesRead > (uint32)reply->buffer.GetSize() + || reply->bytesRead > bufferSize) { + return B_BAD_DATA; + } + if (reply->bytesRead > 0) + memcpy(buffer, readBuffer, reply->bytesRead); + *bytesRead = reply->bytesRead; + _SendReceiptAck(port); + return error; +} + +// Write +status_t +Volume::Write(fs_vnode node, fs_cookie cookie, off_t pos, const void* buffer, + size_t size, size_t* bytesWritten) +{ + *bytesWritten = 0; + + // get a free port + RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); + if (!port) + return B_ERROR; + PortReleaser _(fFileSystem->GetPortPool(), port); + + // prepare the request + RequestAllocator allocator(port->GetPort()); + WriteRequest* request; + status_t error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + + request->volume = fUserlandVolume; + request->node = node; + request->fileCookie = cookie; + request->pos = pos; + error = allocator.AllocateData(request->buffer, buffer, size, 1); + if (error != B_OK) + return error; + + // send the request + KernelRequestHandler handler(this, WRITE_REPLY); + WriteReply* reply; + error = _SendRequest(port, &allocator, &handler, (Request**)&reply); + if (error != B_OK) + return error; + RequestReleaser requestReleaser(port, reply); + + // process the reply + if (reply->error != B_OK) + return reply->error; + *bytesWritten = reply->bytesWritten; + return error; +} + + +// #pragma mark - directories + +// CreateDir +status_t +Volume::CreateDir(fs_vnode dir, const char* name, int mode, vnode_id *newDir) +{ + // get a free port + RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); + if (!port) + return B_ERROR; + PortReleaser _(fFileSystem->GetPortPool(), port); + + // prepare the request + RequestAllocator allocator(port->GetPort()); + CreateDirRequest* request; + status_t error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + request->volume = fUserlandVolume; request->node = dir; error = allocator.AllocateString(request->name, name); request->mode = mode; if (error != B_OK) return error; + // send the request - KernelRequestHandler handler(this, MKDIR_REPLY); - MkDirReply* reply; + KernelRequestHandler handler(this, CREATE_DIR_REPLY); + CreateDirReply* reply; error = _SendRequest(port, &allocator, &handler, (Request**)&reply); if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; + *newDir = reply->newDir; return error; } -// RmDir +// RemoveDir status_t -Volume::RmDir(void* dir, const char* name) +Volume::RemoveDir(fs_vnode dir, const char* name) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); - RmDirRequest* request; + RemoveDirRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = dir; error = allocator.AllocateString(request->name, name); if (error != B_OK) return error; + // send the request - KernelRequestHandler handler(this, RMDIR_REPLY); - RmDirReply* reply; + KernelRequestHandler handler(this, REMOVE_DIR_REPLY); + RemoveDirReply* reply; error = _SendRequest(port, &allocator, &handler, (Request**)&reply); if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -1236,7 +1378,7 @@ Volume::RmDir(void* dir, const char* name) // OpenDir status_t -Volume::OpenDir(void* node, void** cookie) +Volume::OpenDir(fs_vnode node, fs_cookie* cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); @@ -1244,14 +1386,17 @@ Volume::OpenDir(void* node, void** cookie) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); AutoIncrementer incrementer(&fOpenDirectories); + // prepare the request RequestAllocator allocator(port->GetPort()); OpenDirRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; + // send the request KernelRequestHandler handler(this, OPEN_DIR_REPLY); OpenDirReply* reply; @@ -1259,6 +1404,7 @@ Volume::OpenDir(void* node, void** cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -1269,7 +1415,7 @@ Volume::OpenDir(void* node, void** cookie) // CloseDir status_t -Volume::CloseDir(void* node, void* cookie) +Volume::CloseDir(fs_vnode node, fs_vnode cookie) { status_t error = _CloseDir(node, cookie); if (error != B_OK && fFileSystem->GetPortPool()->IsDisconnected()) { @@ -1304,26 +1450,30 @@ Volume::FreeDirCookie(void* node, void* cookie) // ReadDir status_t -Volume::ReadDir(void* node, void* cookie, void* buffer, size_t bufferSize, - int32 count, int32* countRead) +Volume::ReadDir(fs_vnode node, fs_vnode cookie, void* buffer, size_t bufferSize, + uint32 count, uint32* countRead) { *countRead = 0; + // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); ReadDirRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->dirCookie = cookie; request->bufferSize = bufferSize; request->count = count; + // send the request KernelRequestHandler handler(this, READ_DIR_REPLY); ReadDirReply* reply; @@ -1331,6 +1481,7 @@ Volume::ReadDir(void* node, void* cookie, void* buffer, size_t bufferSize, if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -1340,12 +1491,13 @@ Volume::ReadDir(void* node, void* cookie, void* buffer, size_t bufferSize, return B_BAD_DATA; PRINT(("Volume::ReadDir(): buffer returned: %ld bytes\n", reply->buffer.GetSize())); + *countRead = reply->count; if (*countRead > 0) { // copy the buffer -- limit the number of bytes to copy - int32 maxBytes = *countRead + uint32 maxBytes = *countRead * (sizeof(struct dirent) + B_FILE_NAME_LENGTH); - int32 copyBytes = reply->buffer.GetSize(); + uint32 copyBytes = reply->buffer.GetSize(); if (copyBytes > maxBytes) copyBytes = maxBytes; memcpy(buffer, reply->buffer.GetData(), copyBytes); @@ -1356,22 +1508,25 @@ reply->buffer.GetSize())); // RewindDir status_t -Volume::RewindDir(void* node, void* cookie) +Volume::RewindDir(fs_vnode node, fs_vnode cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); RewindDirRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->dirCookie = cookie; + // send the request KernelRequestHandler handler(this, REWIND_DIR_REPLY); RewindDirReply* reply; @@ -1379,39 +1534,20 @@ Volume::RewindDir(void* node, void* cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; return error; } -// Walk -status_t -Volume::Walk(void* dir, const char* entryName, char** resolvedPath, - vnode_id* vnid) -{ - // When the connection to the userland server is lost, we serve - // walk(fRootNode, `.') requests manually to allow clean unmounting. - status_t error = _Walk(dir, entryName, resolvedPath, vnid); - if (error != B_OK && fFileSystem->GetPortPool()->IsDisconnected() - && dir == fRootNode && strcmp(entryName, ".") == 0) { - WARN(("Volume::Walk(): connection lost, emulating walk `.'\n")); - void* entryNode; - if (GetVNode(fRootID, &entryNode) != B_OK) - RETURN_ERROR(B_BAD_VALUE); - *vnid = fRootID; - _DecrementVNodeCount(*vnid); - return B_OK; - } - return error; -} -// #pragma mark - -// #pragma mark ----- attributes ----- +// #pragma mark - attribute directories + // OpenAttrDir status_t -Volume::OpenAttrDir(void* node, void** cookie) +Volume::OpenAttrDir(fs_vnode node, fs_cookie *cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); @@ -1419,14 +1555,17 @@ Volume::OpenAttrDir(void* node, void** cookie) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); AutoIncrementer incrementer(&fOpenAttributeDirectories); + // prepare the request RequestAllocator allocator(port->GetPort()); OpenAttrDirRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; + // send the request KernelRequestHandler handler(this, OPEN_ATTR_DIR_REPLY); OpenAttrDirReply* reply; @@ -1434,6 +1573,7 @@ Volume::OpenAttrDir(void* node, void** cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -1444,7 +1584,7 @@ Volume::OpenAttrDir(void* node, void** cookie) // CloseAttrDir status_t -Volume::CloseAttrDir(void* node, void* cookie) +Volume::CloseAttrDir(fs_vnode node, fs_cookie cookie) { status_t error = _CloseAttrDir(node, cookie); if (error != B_OK && fFileSystem->GetPortPool()->IsDisconnected()) { @@ -1472,6 +1612,7 @@ Volume::FreeAttrDirCookie(void* node, void* cookie) error = B_OK; disconnected = true; } + int32 openAttrDirs = atomic_add(&fOpenAttributeDirectories, -1); if (openAttrDirs <= 1 && disconnected) _PutAllPendingVNodes(); @@ -1480,8 +1621,8 @@ Volume::FreeAttrDirCookie(void* node, void* cookie) // ReadAttrDir status_t -Volume::ReadAttrDir(void* node, void* cookie, void* buffer, size_t bufferSize, - int32 count, int32* countRead) +Volume::ReadAttrDir(fs_vnode node, fs_cookie cookie, void* buffer, + size_t bufferSize, uint32 count, uint32* countRead) { *countRead = 0; // get a free port @@ -1489,17 +1630,20 @@ Volume::ReadAttrDir(void* node, void* cookie, void* buffer, size_t bufferSize, if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); ReadAttrDirRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->attrDirCookie = cookie; request->bufferSize = bufferSize; request->count = count; + // send the request KernelRequestHandler handler(this, READ_ATTR_DIR_REPLY); ReadAttrDirReply* reply; @@ -1507,6 +1651,7 @@ Volume::ReadAttrDir(void* node, void* cookie, void* buffer, size_t bufferSize, if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -1514,12 +1659,13 @@ Volume::ReadAttrDir(void* node, void* cookie, void* buffer, size_t bufferSize, return B_BAD_DATA; if ((int32)bufferSize < reply->buffer.GetSize()) return B_BAD_DATA; + *countRead = reply->count; if (*countRead > 0) { // copy the buffer -- limit the number of bytes to copy - int32 maxBytes = *countRead + uint32 maxBytes = *countRead * (sizeof(struct dirent) + B_ATTR_NAME_LENGTH); - int32 copyBytes = reply->buffer.GetSize(); + uint32 copyBytes = reply->buffer.GetSize(); if (copyBytes > maxBytes) copyBytes = maxBytes; memcpy(buffer, reply->buffer.GetData(), copyBytes); @@ -1530,22 +1676,25 @@ Volume::ReadAttrDir(void* node, void* cookie, void* buffer, size_t bufferSize, // RewindAttrDir status_t -Volume::RewindAttrDir(void* node, void* cookie) +Volume::RewindAttrDir(fs_vnode node, fs_cookie cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); RewindAttrDirRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->attrDirCookie = cookie; + // send the request KernelRequestHandler handler(this, REWIND_ATTR_DIR_REPLY); RewindAttrDirReply* reply; @@ -1553,37 +1702,43 @@ Volume::RewindAttrDir(void* node, void* cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; return error; } + +// #pragma mark - attributes + + // ReadAttr status_t -Volume::ReadAttr(void* node, const char* name, int type, off_t pos, +Volume::ReadAttr(fs_vnode node, fs_cookie cookie, off_t pos, void* buffer, size_t bufferSize, size_t* bytesRead) { *bytesRead = 0; + // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); ReadAttrRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; - error = allocator.AllocateString(request->name, name); - request->type = type; + request->attrCookie = node; request->pos = pos; request->size = bufferSize; - if (error != B_OK) - return error; + // send the request KernelRequestHandler handler(this, READ_ATTR_REPLY); ReadAttrReply* reply; @@ -1591,6 +1746,7 @@ Volume::ReadAttr(void* node, const char* name, int type, off_t pos, if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -1608,30 +1764,32 @@ Volume::ReadAttr(void* node, const char* name, int type, off_t pos, // WriteAttr status_t -Volume::WriteAttr(void* node, const char* name, int type, off_t pos, +Volume::WriteAttr(fs_vnode node, fs_cookie cookie, off_t pos, const void* buffer, size_t bufferSize, size_t* bytesWritten) { *bytesWritten = 0; + // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); WriteAttrRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; - error = allocator.AllocateString(request->name, name); - request->type = type; + request->attrCookie = cookie; request->pos = pos; - if (error == B_OK) - error = allocator.AllocateData(request->buffer, buffer, bufferSize, 1); + error = allocator.AllocateData(request->buffer, buffer, bufferSize, 1); if (error != B_OK) return error; + // send the request KernelRequestHandler handler(this, WRITE_ATTR_REPLY); WriteAttrReply* reply; @@ -1639,6 +1797,7 @@ Volume::WriteAttr(void* node, const char* name, int type, off_t pos, if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -1646,61 +1805,69 @@ Volume::WriteAttr(void* node, const char* name, int type, off_t pos, return error; } -// RemoveAttr +// ReadAttrStat status_t -Volume::RemoveAttr(void* node, const char* name) +Volume::ReadAttrStat(fs_vnode node, fs_cookie cookie, struct stat *st) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); - RemoveAttrRequest* request; + ReadAttrStatRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; - error = allocator.AllocateString(request->name, name); - if (error != B_OK) - return error; + request->attrCookie = cookie; + // send the request - KernelRequestHandler handler(this, REMOVE_ATTR_REPLY); - RemoveAttrReply* reply; + KernelRequestHandler handler(this, READ_ATTR_STAT_REPLY); + ReadAttrStatReply* reply; error = _SendRequest(port, &allocator, &handler, (Request**)&reply); if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; + *st = reply->st; return error; } // RenameAttr status_t -Volume::RenameAttr(void* node, const char* oldName, const char* newName) +Volume::RenameAttr(fs_vnode oldNode, const char* oldName, fs_vnode newNode, + const char* newName) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); RenameAttrRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; - request->node = node; + request->oldNode = oldNode; + request->newNode = newNode; error = allocator.AllocateString(request->oldName, oldName); if (error == B_OK) error = allocator.AllocateString(request->newName, newName); if (error != B_OK) return error; + // send the request KernelRequestHandler handler(this, RENAME_ATTR_REPLY); RenameAttrReply* reply; @@ -1708,52 +1875,57 @@ Volume::RenameAttr(void* node, const char* oldName, const char* newName) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; return error; } -// StatAttr +// RemoveAttr status_t -Volume::StatAttr(void* node, const char* name, struct attr_info* attrInfo) +Volume::RemoveAttr(fs_vnode node, const char* name) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); - StatAttrRequest* request; + RemoveAttrRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; error = allocator.AllocateString(request->name, name); if (error != B_OK) return error; + // send the request - KernelRequestHandler handler(this, STAT_ATTR_REPLY); - StatAttrReply* reply; + KernelRequestHandler handler(this, REMOVE_ATTR_REPLY); + RemoveAttrReply* reply; error = _SendRequest(port, &allocator, &handler, (Request**)&reply); if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; - *attrInfo = reply->info; return error; } -// #pragma mark - -// #pragma mark ----- indices ----- + +// #pragma mark - indices + // OpenIndexDir status_t -Volume::OpenIndexDir(void** cookie) +Volume::OpenIndexDir(fs_cookie *cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); @@ -1761,13 +1933,16 @@ Volume::OpenIndexDir(void** cookie) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); AutoIncrementer incrementer(&fOpenIndexDirectories); + // prepare the request RequestAllocator allocator(port->GetPort()); OpenIndexDirRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; + // send the request KernelRequestHandler handler(this, OPEN_INDEX_DIR_REPLY); OpenIndexDirReply* reply; @@ -1775,6 +1950,7 @@ Volume::OpenIndexDir(void** cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -1785,7 +1961,7 @@ Volume::OpenIndexDir(void** cookie) // CloseIndexDir status_t -Volume::CloseIndexDir(void* cookie) +Volume::CloseIndexDir(fs_cookie cookie) { status_t error = _CloseIndexDir(cookie); if (error != B_OK && fFileSystem->GetPortPool()->IsDisconnected()) { @@ -1801,7 +1977,7 @@ Volume::CloseIndexDir(void* cookie) // FreeIndexDirCookie status_t -Volume::FreeIndexDirCookie(void* cookie) +Volume::FreeIndexDirCookie(fs_cookie cookie) { status_t error = _FreeIndexDirCookie(cookie); bool disconnected = false; @@ -1813,6 +1989,7 @@ Volume::FreeIndexDirCookie(void* cookie) error = B_OK; disconnected = true; } + int32 openIndexDirs = atomic_add(&fOpenIndexDirectories, -1); if (openIndexDirs <= 1 && disconnected) _PutAllPendingVNodes(); @@ -1821,25 +1998,29 @@ Volume::FreeIndexDirCookie(void* cookie) // ReadIndexDir status_t -Volume::ReadIndexDir(void* cookie, void* buffer, size_t bufferSize, int32 count, - int32* countRead) +Volume::ReadIndexDir(fs_cookie cookie, void* buffer, size_t bufferSize, + uint32 count, uint32* countRead) { *countRead = 0; + // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); ReadIndexDirRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->indexDirCookie = cookie; request->bufferSize = bufferSize; request->count = count; + // send the request KernelRequestHandler handler(this, READ_INDEX_DIR_REPLY); ReadIndexDirReply* reply; @@ -1847,6 +2028,7 @@ Volume::ReadIndexDir(void* cookie, void* buffer, size_t bufferSize, int32 count, if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -1854,12 +2036,13 @@ Volume::ReadIndexDir(void* cookie, void* buffer, size_t bufferSize, int32 count, return B_BAD_DATA; if ((int32)bufferSize < reply->buffer.GetSize()) return B_BAD_DATA; + *countRead = reply->count; if (*countRead > 0) { // copy the buffer -- limit the number of bytes to copy - int32 maxBytes = *countRead + uint32 maxBytes = *countRead * (sizeof(struct dirent) + B_FILE_NAME_LENGTH); - int32 copyBytes = reply->buffer.GetSize(); + uint32 copyBytes = reply->buffer.GetSize(); if (copyBytes > maxBytes) copyBytes = maxBytes; memcpy(buffer, reply->buffer.GetData(), copyBytes); @@ -1870,21 +2053,24 @@ Volume::ReadIndexDir(void* cookie, void* buffer, size_t bufferSize, int32 count, // RewindIndexDir status_t -Volume::RewindIndexDir(void* cookie) +Volume::RewindIndexDir(fs_cookie cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); RewindIndexDirRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->indexDirCookie = cookie; + // send the request KernelRequestHandler handler(this, REWIND_INDEX_DIR_REPLY); RewindIndexDirReply* reply; @@ -1892,6 +2078,7 @@ Volume::RewindIndexDir(void* cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -1900,25 +2087,28 @@ Volume::RewindIndexDir(void* cookie) // CreateIndex status_t -Volume::CreateIndex(const char* name, int type, int flags) +Volume::CreateIndex(const char* name, uint32 type, uint32 flags) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); CreateIndexRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; error = allocator.AllocateString(request->name, name); request->type = type; request->flags = flags; if (error != B_OK) return error; + // send the request KernelRequestHandler handler(this, CREATE_INDEX_REPLY); CreateIndexReply* reply; @@ -1926,6 +2116,7 @@ Volume::CreateIndex(const char* name, int type, int flags) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -1941,16 +2132,19 @@ Volume::RemoveIndex(const char* name) if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); RemoveIndexRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; error = allocator.AllocateString(request->name, name); if (error != B_OK) return error; + // send the request KernelRequestHandler handler(this, REMOVE_INDEX_REPLY); RemoveIndexReply* reply; @@ -1958,86 +2152,58 @@ Volume::RemoveIndex(const char* name) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; return error; } -// RenameIndex +// ReadIndexStat status_t -Volume::RenameIndex(const char* oldName, const char* newName) +Volume::ReadIndexStat(const char* name, struct stat *st) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); - // prepare the request - RequestAllocator allocator(port->GetPort()); - RenameIndexRequest* request; - status_t error = AllocateRequest(allocator, &request); - if (error != B_OK) - return error; - request->volume = fUserlandVolume; - error = allocator.AllocateString(request->oldName, oldName); - if (error == B_OK) - error = allocator.AllocateString(request->newName, newName); - if (error != B_OK) - return error; - // send the request - KernelRequestHandler handler(this, RENAME_INDEX_REPLY); - RenameIndexReply* reply; - error = _SendRequest(port, &allocator, &handler, (Request**)&reply); - if (error != B_OK) - return error; - RequestReleaser requestReleaser(port, reply); - // process the reply - if (reply->error != B_OK) - return reply->error; - return error; -} -// StatIndex -status_t -Volume::StatIndex(const char *name, struct index_info* indexInfo) -{ - // get a free port - RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); - if (!port) - return B_ERROR; - PortReleaser _(fFileSystem->GetPortPool(), port); // prepare the request RequestAllocator allocator(port->GetPort()); - StatIndexRequest* request; + ReadIndexStatRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; error = allocator.AllocateString(request->name, name); if (error != B_OK) return error; + // send the request - KernelRequestHandler handler(this, STAT_INDEX_REPLY); - StatIndexReply* reply; + KernelRequestHandler handler(this, READ_INDEX_STAT_REPLY); + ReadIndexStatReply* reply; error = _SendRequest(port, &allocator, &handler, (Request**)&reply); if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; - *indexInfo = reply->info; + *st = reply->st; return error; } -// #pragma mark - -// #pragma mark ----- queries ----- + +// #pragma mark - queries + // OpenQuery status_t -Volume::OpenQuery(const char* queryString, ulong flags, port_id targetPort, - long token, void** cookie) +Volume::OpenQuery(const char* queryString, uint32 flags, port_id targetPort, + uint32 token, fs_cookie *cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); @@ -2045,12 +2211,14 @@ Volume::OpenQuery(const char* queryString, ulong flags, port_id targetPort, return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); AutoIncrementer incrementer(&fOpenQueries); + // prepare the request RequestAllocator allocator(port->GetPort()); OpenQueryRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; error = allocator.AllocateString(request->queryString, queryString); if (error != B_OK) @@ -2058,6 +2226,7 @@ Volume::OpenQuery(const char* queryString, ulong flags, port_id targetPort, request->flags = flags; request->port = targetPort; request->token = token; + // send the request KernelRequestHandler handler(this, OPEN_QUERY_REPLY); OpenQueryReply* reply; @@ -2065,6 +2234,7 @@ Volume::OpenQuery(const char* queryString, ulong flags, port_id targetPort, if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -2075,7 +2245,7 @@ Volume::OpenQuery(const char* queryString, ulong flags, port_id targetPort, // CloseQuery status_t -Volume::CloseQuery(void* cookie) +Volume::CloseQuery(fs_cookie cookie) { status_t error = _CloseQuery(cookie); if (error != B_OK && fFileSystem->GetPortPool()->IsDisconnected()) { @@ -2090,7 +2260,7 @@ Volume::CloseQuery(void* cookie) // FreeQueryCookie status_t -Volume::FreeQueryCookie(void* cookie) +Volume::FreeQueryCookie(fs_cookie cookie) { status_t error = _FreeQueryCookie(cookie); bool disconnected = false; @@ -2102,6 +2272,7 @@ Volume::FreeQueryCookie(void* cookie) error = B_OK; disconnected = true; } + int32 openQueries = atomic_add(&fOpenQueries, -1); if (openQueries <= 1 && disconnected) _PutAllPendingVNodes(); @@ -2110,25 +2281,29 @@ Volume::FreeQueryCookie(void* cookie) // ReadQuery status_t -Volume::ReadQuery(void* cookie, void* buffer, size_t bufferSize, int32 count, - int32* countRead) +Volume::ReadQuery(fs_cookie cookie, void* buffer, size_t bufferSize, + uint32 count, uint32* countRead) { *countRead = 0; + // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); ReadQueryRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->queryCookie = cookie; request->bufferSize = bufferSize; request->count = count; + // send the request KernelRequestHandler handler(this, READ_QUERY_REPLY); ReadQueryReply* reply; @@ -2136,6 +2311,7 @@ Volume::ReadQuery(void* cookie, void* buffer, size_t bufferSize, int32 count, if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -2143,12 +2319,13 @@ Volume::ReadQuery(void* cookie, void* buffer, size_t bufferSize, int32 count, return B_BAD_DATA; if ((int32)bufferSize < reply->buffer.GetSize()) return B_BAD_DATA; + *countRead = reply->count; if (*countRead > 0) { // copy the buffer -- limit the number of bytes to copy - int32 maxBytes = *countRead + uint32 maxBytes = *countRead * (sizeof(struct dirent) + B_FILE_NAME_LENGTH); - int32 copyBytes = reply->buffer.GetSize(); + uint32 copyBytes = reply->buffer.GetSize(); if (copyBytes > maxBytes) copyBytes = maxBytes; memcpy(buffer, reply->buffer.GetData(), copyBytes); @@ -2162,8 +2339,7 @@ Volume::ReadQuery(void* cookie, void* buffer, size_t bufferSize, int32 count, // _Mount status_t -Volume::_Mount(const char* device, ulong flags, const char* parameters, - int32 len) +Volume::_Mount(const char* device, uint32 flags, const char* parameters) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); @@ -2182,13 +2358,14 @@ Volume::_Mount(const char* device, ulong flags, const char* parameters, status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->nsid = fID; error = allocator.AllocateString(request->cwd, cwd); if (error == B_OK) error = allocator.AllocateString(request->device, device); request->flags = flags; if (error == B_OK) - error = allocator.AllocateData(request->parameters, parameters, len, 1); + error = allocator.AllocateString(request->parameters, parameters); if (error != B_OK) return error; @@ -2224,13 +2401,16 @@ Volume::_Unmount() if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); UnmountVolumeRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; + // send the request KernelRequestHandler handler(this, UNMOUNT_VOLUME_REPLY); UnmountVolumeReply* reply; @@ -2238,21 +2418,64 @@ Volume::_Unmount() if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; return error; } -// _WriteVNode +// _Lookup status_t -Volume::_WriteVNode(void* node, char reenter) +Volume::_Lookup(fs_vnode dir, const char* entryName, vnode_id* vnid, int* type) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + + // prepare the request + RequestAllocator allocator(port->GetPort()); + LookupRequest* request; + status_t error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + request->volume = fUserlandVolume; + request->node = dir; + error = allocator.AllocateString(request->entryName, entryName); + if (error != B_OK) + return error; + + // send the request + KernelRequestHandler handler(this, LOOKUP_REPLY); + LookupReply* reply; + error = _SendRequest(port, &allocator, &handler, (Request**)&reply); + if (error != B_OK) + return error; + RequestReleaser requestReleaser(port, reply); + + // process the reply + if (reply->error != B_OK) + return reply->error; + *vnid = reply->vnid; + *type = reply->type; + + // The VFS will balance the get_vnode() call for the FS. + _DecrementVNodeCount(*vnid); + return error; +} + +// _WriteVNode +status_t +Volume::_WriteVNode(fs_vnode node, bool reenter) +{ + // get a free port + RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); + if (!port) + return B_ERROR; + PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); WriteVNodeRequest* request; @@ -2262,6 +2485,7 @@ Volume::_WriteVNode(void* node, char reenter) request->volume = fUserlandVolume; request->node = node; request->reenter = reenter; + // send the request KernelRequestHandler handler(this, WRITE_VNODE_REPLY); WriteVNodeReply* reply; @@ -2269,6 +2493,7 @@ Volume::_WriteVNode(void* node, char reenter) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -2277,22 +2502,25 @@ Volume::_WriteVNode(void* node, char reenter) // _Close status_t -Volume::_Close(void* node, void* cookie) +Volume::_Close(fs_vnode node, fs_cookie cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); CloseRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->fileCookie = cookie; + // send the request KernelRequestHandler handler(this, CLOSE_REPLY); CloseReply* reply; @@ -2300,6 +2528,7 @@ Volume::_Close(void* node, void* cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -2308,22 +2537,25 @@ Volume::_Close(void* node, void* cookie) // _FreeCookie status_t -Volume::_FreeCookie(void* node, void* cookie) +Volume::_FreeCookie(fs_vnode node, fs_cookie cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); FreeCookieRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->fileCookie = cookie; + // send the request KernelRequestHandler handler(this, FREE_COOKIE_REPLY); FreeCookieReply* reply; @@ -2331,6 +2563,7 @@ Volume::_FreeCookie(void* node, void* cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -2339,22 +2572,25 @@ Volume::_FreeCookie(void* node, void* cookie) // _CloseDir status_t -Volume::_CloseDir(void* node, void* cookie) +Volume::_CloseDir(fs_vnode node, fs_vnode cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); CloseDirRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->dirCookie = cookie; + // send the request KernelRequestHandler handler(this, CLOSE_DIR_REPLY); CloseDirReply* reply; @@ -2362,6 +2598,7 @@ Volume::_CloseDir(void* node, void* cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -2370,22 +2607,25 @@ Volume::_CloseDir(void* node, void* cookie) // _FreeDirCookie status_t -Volume::_FreeDirCookie(void* node, void* cookie) +Volume::_FreeDirCookie(fs_vnode node, fs_vnode cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); FreeDirCookieRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->dirCookie = cookie; + // send the request KernelRequestHandler handler(this, FREE_DIR_COOKIE_REPLY); FreeDirCookieReply* reply; @@ -2393,81 +2633,34 @@ Volume::_FreeDirCookie(void* node, void* cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); - // process the reply - if (reply->error != B_OK) - return reply->error; - return error; -} -// _Walk -status_t -Volume::_Walk(void* dir, const char* entryName, char** resolvedPath, - vnode_id* vnid) -{ - // get a free port - RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); - if (!port) - return B_ERROR; - PortReleaser _(fFileSystem->GetPortPool(), port); - // prepare the request - RequestAllocator allocator(port->GetPort()); - WalkRequest* request; - status_t error = AllocateRequest(allocator, &request); - if (error != B_OK) - return error; - request->volume = fUserlandVolume; - request->node = dir; - error = allocator.AllocateString(request->entryName, entryName); - request->traverseLink = resolvedPath; - if (error != B_OK) - return error; - // send the request - KernelRequestHandler handler(this, WALK_REPLY); - WalkReply* reply; - error = _SendRequest(port, &allocator, &handler, (Request**)&reply); - if (error != B_OK) - return error; - RequestReleaser requestReleaser(port, reply); // process the reply if (reply->error != B_OK) return reply->error; - *vnid = reply->vnid; - if (resolvedPath) { - const char* readPath = (const char*)reply->resolvedPath.GetData(); - if (readPath) { - int32 len = strnlen(readPath, reply->resolvedPath.GetSize()); - *resolvedPath = (char*)malloc(len + 1); - if (*resolvedPath) { - memcpy(*resolvedPath, readPath, len); - (*resolvedPath)[len] = '\0'; - } else - error = B_NO_MEMORY; - _SendReceiptAck(port); - } else - _DecrementVNodeCount(*vnid); - } else - _DecrementVNodeCount(*vnid); return error; } // _CloseAttrDir status_t -Volume::_CloseAttrDir(void* node, void* cookie) +Volume::_CloseAttrDir(fs_vnode node, fs_cookie cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); CloseAttrDirRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->attrDirCookie = cookie; + // send the request KernelRequestHandler handler(this, CLOSE_ATTR_DIR_REPLY); CloseAttrDirReply* reply; @@ -2475,6 +2668,7 @@ Volume::_CloseAttrDir(void* node, void* cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -2483,22 +2677,25 @@ Volume::_CloseAttrDir(void* node, void* cookie) // _FreeAttrDirCookie status_t -Volume::_FreeAttrDirCookie(void* node, void* cookie) +Volume::_FreeAttrDirCookie(fs_vnode node, fs_cookie cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); FreeAttrDirCookieRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->node = node; request->attrDirCookie = cookie; + // send the request KernelRequestHandler handler(this, FREE_ATTR_DIR_COOKIE_REPLY); FreeAttrDirCookieReply* reply; @@ -2506,6 +2703,7 @@ Volume::_FreeAttrDirCookie(void* node, void* cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -2514,21 +2712,24 @@ Volume::_FreeAttrDirCookie(void* node, void* cookie) // _CloseIndexDir status_t -Volume::_CloseIndexDir(void* cookie) +Volume::_CloseIndexDir(fs_cookie cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); CloseIndexDirRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->indexDirCookie = cookie; + // send the request KernelRequestHandler handler(this, CLOSE_INDEX_DIR_REPLY); CloseIndexDirReply* reply; @@ -2536,6 +2737,7 @@ Volume::_CloseIndexDir(void* cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -2544,21 +2746,24 @@ Volume::_CloseIndexDir(void* cookie) // _FreeIndexDirCookie status_t -Volume::_FreeIndexDirCookie(void* cookie) +Volume::_FreeIndexDirCookie(fs_cookie cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); FreeIndexDirCookieRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->indexDirCookie = cookie; + // send the request KernelRequestHandler handler(this, FREE_INDEX_DIR_COOKIE_REPLY); FreeIndexDirCookieReply* reply; @@ -2566,6 +2771,7 @@ Volume::_FreeIndexDirCookie(void* cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -2574,21 +2780,24 @@ Volume::_FreeIndexDirCookie(void* cookie) // _CloseQuery status_t -Volume::_CloseQuery(void* cookie) +Volume::_CloseQuery(fs_cookie cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); CloseQueryRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->queryCookie = cookie; + // send the request KernelRequestHandler handler(this, CLOSE_QUERY_REPLY); CloseQueryReply* reply; @@ -2596,6 +2805,7 @@ Volume::_CloseQuery(void* cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; @@ -2604,21 +2814,24 @@ Volume::_CloseQuery(void* cookie) // _FreeQueryCookie status_t -Volume::_FreeQueryCookie(void* cookie) +Volume::_FreeQueryCookie(fs_cookie cookie) { // get a free port RequestPort* port = fFileSystem->GetPortPool()->AcquirePort(); if (!port) return B_ERROR; PortReleaser _(fFileSystem->GetPortPool(), port); + // prepare the request RequestAllocator allocator(port->GetPort()); FreeQueryCookieRequest* request; status_t error = AllocateRequest(allocator, &request); if (error != B_OK) return error; + request->volume = fUserlandVolume; request->queryCookie = cookie; + // send the request KernelRequestHandler handler(this, FREE_QUERY_COOKIE_REPLY); FreeQueryCookieReply* reply; @@ -2626,6 +2839,7 @@ Volume::_FreeQueryCookie(void* cookie) if (error != B_OK) return error; RequestReleaser requestReleaser(port, reply); + // process the reply if (reply->error != B_OK) return reply->error; diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h index 459c218796..123536c31a 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h @@ -3,7 +3,7 @@ #ifndef USERLAND_FS_VOLUME_H #define USERLAND_FS_VOLUME_H -#include +#include #include "Referencable.h" @@ -24,11 +24,11 @@ struct userlandfs_ioctl; class Volume : public Referencable { public: - Volume(FileSystem* fileSystem, nspace_id id); + Volume(FileSystem* fileSystem, mount_id id); ~Volume(); FileSystem* GetFileSystem() const; - nspace_id GetID() const; + mount_id GetID() const; void* GetUserlandVolume() const; vnode_id GetRootID() const; @@ -43,133 +43,143 @@ public: status_t IsVNodeRemoved(vnode_id vnid); // FS - status_t Mount(const char* device, ulong flags, - const char* parameters, int32 len); + status_t Mount(const char* device, uint32 flags, + const char* parameters); status_t Unmount(); status_t Sync(); - status_t ReadFSStat(fs_info* info); - status_t WriteFSStat(struct fs_info* info, long mask); + status_t ReadFSInfo(fs_info* info); + status_t WriteFSInfo(const struct fs_info* info, + uint32 mask); // vnodes - status_t ReadVNode(vnode_id vnid, char reenter, - void** node); - status_t WriteVNode(void* node, char reenter); - status_t RemoveVNode(void* node, char reenter); + status_t Lookup(fs_vnode dir, const char* entryName, + vnode_id* vnid, int* type); + status_t ReadVNode(vnode_id vnid, bool reenter, + fs_vnode* node); + status_t WriteVNode(fs_vnode node, bool reenter); + status_t RemoveVNode(fs_vnode node, bool reenter); // nodes - status_t FSync(void* node); - status_t ReadStat(void* node, struct stat* st); - status_t WriteStat(void* node, struct stat *st, - long mask); - status_t Access(void* node, int mode); + status_t IOCtl(fs_vnode node, fs_cookie cookie, + uint32 command, void *buffer, size_t size); + status_t SetFlags(fs_vnode node, fs_cookie cookie, + int flags); + status_t Select(fs_vnode node, fs_cookie cookie, + uint8 event, uint32 ref, selectsync* sync); + status_t Deselect(fs_vnode node, fs_cookie cookie, + uint8 event, selectsync* sync); + + status_t FSync(fs_vnode node); + + status_t ReadSymlink(fs_vnode node, char* buffer, + size_t bufferSize, size_t* bytesRead); + status_t CreateSymlink(fs_vnode dir, const char* name, + const char* target, int mode); + + status_t Link(fs_vnode dir, const char* name, + fs_vnode node); + status_t Unlink(fs_vnode dir, const char* name); + status_t Rename(fs_vnode oldDir, const char* oldName, + fs_vnode newDir, const char* newName); + + status_t Access(fs_vnode node, int mode); + status_t ReadStat(fs_vnode node, struct stat* st); + status_t WriteStat(fs_vnode node, const struct stat *st, + uint32 mask); // files - status_t Create(void* dir, const char* name, - int openMode, int mode, vnode_id* vnid, - void** cookie); - status_t Open(void* node, int openMode, void** cookie); - status_t Close(void* node, void* cookie); - status_t FreeCookie(void* node, void* cookie); - status_t Read(void* node, void* cookie, off_t pos, + status_t Create(fs_vnode dir, const char* name, + int openMode, int mode, fs_cookie* cookie, + vnode_id* vnid); + status_t Open(fs_vnode node, int openMode, + fs_cookie* cookie); + status_t Close(fs_vnode node, fs_cookie cookie); + status_t FreeCookie(fs_vnode node, fs_cookie cookie); + status_t Read(fs_vnode node, fs_cookie cookie, off_t pos, void* buffer, size_t bufferSize, size_t* bytesRead); - status_t Write(void* node, void* cookie, off_t pos, - const void* buffer, size_t bufferSize, - size_t* bytesWritten); - status_t IOCtl(void* node, void* cookie, int command, - void *buffer, size_t size); - status_t SetFlags(void* node, void* cookie, int flags); - status_t Select(void* node, void* cookie, uint8 event, - uint32 ref, selectsync* sync); - status_t Deselect(void* node, void* cookie, uint8 event, - selectsync* sync); - - // hard links / symlinks - status_t Link(void* dir, const char* name, void* node); - status_t Unlink(void* dir, const char* name); - status_t Symlink(void* dir, const char* name, - const char* target); - status_t ReadLink(void* node, char* buffer, - size_t bufferSize, size_t* bytesRead); - status_t Rename(void* oldDir, const char* oldName, - void* newDir, const char* newName); + status_t Write(fs_vnode node, fs_cookie cookie, + off_t pos, const void* buffer, + size_t bufferSize, size_t* bytesWritten); // directories - status_t MkDir(void* dir, const char* name, int mode); - status_t RmDir(void* dir, const char* name); - status_t OpenDir(void* node, void** cookie); - status_t CloseDir(void* node, void* cookie); - status_t FreeDirCookie(void* node, void* cookie); - status_t ReadDir(void* node, void* cookie, + status_t CreateDir(fs_vnode dir, const char* name, + int mode, vnode_id *newDir); + status_t RemoveDir(fs_vnode dir, const char* name); + status_t OpenDir(fs_vnode node, fs_cookie* cookie); + status_t CloseDir(fs_vnode node, fs_vnode cookie); + status_t FreeDirCookie(fs_vnode node, fs_vnode cookie); + status_t ReadDir(fs_vnode node, fs_vnode cookie, void* buffer, size_t bufferSize, - int32 count, int32* countRead); - status_t RewindDir(void* node, void* cookie); - status_t Walk(void* dir, const char* entryName, - char** resolvedPath, vnode_id* vnid); + uint32 count, uint32* countRead); + status_t RewindDir(fs_vnode node, fs_vnode cookie); + + // attribute directories + status_t OpenAttrDir(fs_vnode node, fs_cookie *cookie); + status_t CloseAttrDir(fs_vnode node, fs_cookie cookie); + status_t FreeAttrDirCookie(fs_vnode node, + fs_cookie cookie); + status_t ReadAttrDir(fs_vnode node, fs_cookie cookie, + void* buffer, size_t bufferSize, + uint32 count, uint32* countRead); + status_t RewindAttrDir(fs_vnode node, fs_cookie cookie); // attributes - status_t OpenAttrDir(void* node, void** cookie); - status_t CloseAttrDir(void* node, void* cookie); - status_t FreeAttrDirCookie(void* node, void* cookie); - status_t ReadAttrDir(void* node, void* cookie, - void* buffer, size_t bufferSize, - int32 count, int32* countRead); - status_t RewindAttrDir(void* node, void* cookie); - status_t ReadAttr(void* node, const char* name, - int type, off_t pos, void* buffer, - size_t bufferSize, size_t* bytesRead); - status_t WriteAttr(void* node, const char* name, - int type, off_t pos, const void* buffer, + status_t ReadAttr(fs_vnode node, fs_cookie cookie, + off_t pos, void* buffer, size_t bufferSize, + size_t* bytesRead); + status_t WriteAttr(fs_vnode node, fs_cookie cookie, + off_t pos, const void* buffer, size_t bufferSize, size_t* bytesWritten); - status_t RemoveAttr(void* node, const char* name); - status_t RenameAttr(void* node, const char* oldName, + status_t ReadAttrStat(fs_vnode node, fs_cookie cookie, + struct stat *st); + status_t RenameAttr(fs_vnode oldNode, + const char* oldName, fs_vnode newNode, const char* newName); - status_t StatAttr(void* node, const char* name, - struct attr_info* attrInfo); + status_t RemoveAttr(fs_vnode node, const char* name); // indices - status_t OpenIndexDir(void** cookie); - status_t CloseIndexDir(void* cookie); - status_t FreeIndexDirCookie(void* cookie); - status_t ReadIndexDir(void* cookie, void* buffer, - size_t bufferSize, int32 count, - int32* countRead); - status_t RewindIndexDir(void* cookie); - status_t CreateIndex(const char* name, int type, - int flags); + status_t OpenIndexDir(fs_cookie *cookie); + status_t CloseIndexDir(fs_cookie cookie); + status_t FreeIndexDirCookie(fs_cookie cookie); + status_t ReadIndexDir(fs_cookie cookie, void* buffer, + size_t bufferSize, uint32 count, + uint32* countRead); + status_t RewindIndexDir(fs_cookie cookie); + status_t CreateIndex(const char* name, uint32 type, + uint32 flags); status_t RemoveIndex(const char* name); - status_t RenameIndex(const char* oldName, - const char* newName); - status_t StatIndex(const char *name, - struct index_info* indexInfo); + status_t ReadIndexStat(const char *name, + struct stat *st); // queries status_t OpenQuery(const char* queryString, - ulong flags, port_id port, long token, - void** cookie); - status_t CloseQuery(void* cookie); - status_t FreeQueryCookie(void* cookie); - status_t ReadQuery(void* cookie, void* buffer, - size_t bufferSize, int32 count, - int32* countRead); + uint32 flags, port_id port, uint32 token, + fs_cookie *cookie); + status_t CloseQuery(fs_cookie cookie); + status_t FreeQueryCookie(fs_cookie cookie); + status_t ReadQuery(fs_cookie cookie, void* buffer, + size_t bufferSize, uint32 count, + uint32* countRead); private: - status_t _Mount(const char* device, ulong flags, - const char* parameters, int32 len); + status_t _Mount(const char* device, uint32 flags, + const char* parameters); status_t _Unmount(); - status_t _WriteVNode(void* node, char reenter); - status_t _Close(void* node, void* cookie); - status_t _FreeCookie(void* node, void* cookie); - status_t _CloseDir(void* node, void* cookie); - status_t _FreeDirCookie(void* node, void* cookie); - status_t _Walk(void* dir, const char* entryName, - char** resolvedPath, vnode_id* vnid); - status_t _CloseAttrDir(void* node, void* cookie); - status_t _FreeAttrDirCookie(void* node, void* cookie); - status_t _CloseIndexDir(void* cookie); - status_t _FreeIndexDirCookie(void* cookie); - status_t _CloseQuery(void* cookie); - status_t _FreeQueryCookie(void* cookie); + status_t _Lookup(fs_vnode dir, const char* entryName, + vnode_id* vnid, int* type); + status_t _WriteVNode(fs_vnode node, bool reenter); + status_t _Close(fs_vnode node, fs_cookie cookie); + status_t _FreeCookie(fs_vnode node, fs_cookie cookie); + status_t _CloseDir(fs_vnode node, fs_vnode cookie); + status_t _FreeDirCookie(fs_vnode node, fs_vnode cookie); + status_t _CloseAttrDir(fs_vnode node, fs_cookie cookie); + status_t _FreeAttrDirCookie(fs_vnode node, + fs_cookie cookie); + status_t _CloseIndexDir(fs_cookie cookie); + status_t _FreeIndexDirCookie(fs_cookie cookie); + status_t _CloseQuery(fs_cookie cookie); + status_t _FreeQueryCookie(fs_cookie cookie); status_t _SendRequest(RequestPort* port, RequestAllocator* allocator, @@ -190,10 +200,10 @@ private: class AutoIncrementer; FileSystem* fFileSystem; - nspace_id fID; + mount_id fID; void* fUserlandVolume; vnode_id fRootID; - void* fRootNode; + fs_vnode fRootNode; MountVNodeMap* fMountVNodes; vint32 fOpenFiles; vint32 fOpenDirectories; @@ -201,6 +211,9 @@ private: vint32 fOpenIndexDirectories; vint32 fOpenQueries; VNodeCountMap* fVNodeCountMap; + // Tracks the number of new/get_vnode() + // calls to be balanced by the FS by + // corresponding put_vnode()s. volatile bool fVNodeCountingEnabled; }; diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/kernel_interface.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/kernel_interface.cpp index 17f0bfdab6..73415993df 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/kernel_interface.cpp @@ -1,7 +1,7 @@ // kernel_interface.cpp #include -#include +#include #include "Debug.h" #include "FileSystem.h" @@ -10,13 +10,13 @@ #include "Volume.h" -// #pragma mark - -// #pragma mark ----- fs ----- +// #pragma mark - general + // parse_parameters static status_t parse_parameters(const char *parameters, String &fsName, - const char **fsParameters, int32 *fsParameterLength) + const char **fsParameters) { // check parameters if (!parameters) @@ -102,7 +102,7 @@ userlandfs_mount(mount_id id, const char *device, uint32 flags, // userlandfs_unmount static status_t -userlandfs_unmount(void *ns) +userlandfs_unmount(fs_volume ns) { Volume* volume = (Volume*)ns; FileSystem* fileSystem = volume->GetFileSystem(); @@ -114,9 +114,763 @@ userlandfs_unmount(void *ns) return error; } +// userlandfs_sync +static status_t +userlandfs_sync(fs_volume fs) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_sync(%p)\n", fs)); + status_t error = volume->Sync(); + PRINT(("userlandfs_sync() done: %lx \n", error)); + return error; +} + +// userlandfs_read_fs_info +static status_t +userlandfs_read_fs_info(fs_volume fs, struct fs_info *info) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_read_fs_info(%p, %p)\n", fs, info)); + status_t error = volume->ReadFSInfo(info); + PRINT(("userlandfs_read_fs_info() done: %lx \n", error)); + return error; +} + +// userlandfs_write_fs_info +static status_t +userlandfs_write_fs_info(fs_volume fs, const struct fs_info *info, uint32 mask) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_write_fs_info(%p, %p, 0x%lx)\n", fs, info, mask)); + status_t error = volume->WriteFSInfo(info, mask); + PRINT(("userlandfs_write_fs_info() done: %lx \n", error)); + return error; +} + + +// #pragma mark - vnodes + + +// userlandfs_lookup +static status_t +userlandfs_lookup(fs_volume fs, fs_vnode dir, const char *entryName, + vnode_id *vnid, int *type) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_lookup(%p, %p, `%s', %p, %p)\n", fs, dir, + entryName, vnid, type)); + status_t error = volume->Lookup(dir, entryName, vnid, type); + PRINT(("userlandfs_lookup() done: (%lx, %lld, 0x%x)\n", error, *vnid, + *type)); + return error; +} + +// TODO: userlandfs_get_vnode_name() + +// userlandfs_get_vnode +static status_t +userlandfs_get_vnode(fs_volume fs, vnode_id vnid, fs_vnode *node, bool reenter) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_get_vnode(%p, %lld, %p, %d)\n", fs, vnid, node, + reenter)); + status_t error = volume->ReadVNode(vnid, reenter, node); + PRINT(("userlandfs_get_vnode() done: (%lx, %p)\n", error, *node)); + return error; +} + +// userlandfs_put_vnode +static status_t +userlandfs_put_vnode(fs_volume fs, fs_vnode node, bool reenter) +{ + Volume* volume = (Volume*)fs; +// DANGER: If dbg_printf() is used, this thread will enter another FS and +// even perform a write operation. The is dangerous here, since this hook +// may be called out of the other FSs, since, for instance a put_vnode() +// called from another FS may cause the VFS layer to free vnodes and thus +// invoke this hook. +// PRINT(("userlandfs_put_vnode(%p, %p, %d)\n", fs, node, reenter)); + status_t error = volume->WriteVNode(node, reenter); +// PRINT(("userlandfs_put_vnode() done: %lx\n", error)); + return error; +} + +// userlandfs_remove_vnode +static status_t +userlandfs_remove_vnode(fs_volume fs, fs_vnode node, bool reenter) +{ + Volume* volume = (Volume*)fs; +// DANGER: See userlandfs_write_vnode(). +// PRINT(("userlandfs_remove_vnode(%p, %p, %d)\n", fs, node, reenter)); + status_t error = volume->RemoveVNode(node, reenter); +// PRINT(("userlandfs_remove_vnode() done: %lx\n", error)); + return error; +} + + +// #pragma mark - VM file access + + +// TODO: userlandfs_can_page() +// TODO: userlandfs_read_pages() +// TODO: userlandfs_write_pages() + + +// #pragma mark - cache file access + + +// TODO: userlandfs_get_file_map() + + +// #pragma mark - common + + +// userlandfs_ioctl +static status_t +userlandfs_ioctl(fs_volume fs, fs_vnode node, fs_cookie cookie, ulong op, + void *buffer, size_t length) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_ioctl(%p, %p, %p, %lu, %p, %lu)\n", fs, node, cookie, op, + buffer, length)); + status_t error = volume->IOCtl(node, cookie, op, buffer, length); + PRINT(("userlandfs_ioctl() done: (%lx)\n", error)); + return error; +} + +// userlandfs_set_flags +static status_t +userlandfs_set_flags(fs_volume fs, fs_vnode node, fs_cookie cookie, int flags) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_set_flags(%p, %p, %p, %d)\n", fs, node, cookie, flags)); + status_t error = volume->SetFlags(node, cookie, flags); + PRINT(("userlandfs_set_flags() done: (%lx)\n", error)); + return error; +} + +// userlandfs_select +static status_t +userlandfs_select(fs_volume fs, fs_vnode node, fs_cookie cookie, + uint8 event, uint32 ref, selectsync *sync) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_select(%p, %p, %p, %hhd, %lu, %p)\n", fs, node, cookie, + event, ref, sync)); + status_t error = volume->Select(node, cookie, event, ref, sync); + PRINT(("userlandfs_select() done: (%lx)\n", error)); + return error; +} + +// userlandfs_deselect +static status_t +userlandfs_deselect(fs_volume fs, fs_vnode node, fs_cookie cookie, uint8 event, + selectsync *sync) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_deselect(%p, %p, %p, %hhd, %p)\n", fs, node, cookie, + event, sync)); + status_t error = volume->Deselect(node, cookie, event, sync); + PRINT(("userlandfs_deselect() done: (%lx)\n", error)); + return error; +} + +// userlandfs_fsync +static status_t +userlandfs_fsync(fs_volume fs, fs_vnode node) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_fsync(%p, %p)\n", fs, node)); + status_t error = volume->FSync(node); + PRINT(("userlandfs_fsync() done: %lx\n", error)); + return error; +} + +// userlandfs_read_symlink +static status_t +userlandfs_read_symlink(fs_volume fs, fs_vnode link, char *buffer, + size_t *bufferSize) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_read_symlink(%p, %p, %p, %lu)\n", fs, link, buffer, + *bufferSize)); + status_t error = volume->ReadSymlink(link, buffer, *bufferSize, bufferSize); + PRINT(("userlandfs_read_symlink() done: (%lx, %lu)\n", error, *bufferSize)); + return error; +} + +// TODO: userlandfs_write_symlink + +// userlandfs_create_symlink +static status_t +userlandfs_create_symlink(fs_volume fs, fs_vnode dir, const char *name, + const char *path, int mode) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_create_symlink(%p, %p, `%s', `%s', %d)\n", fs, dir, name, + path, mode)); + status_t error = volume->CreateSymlink(dir, name, path, mode); + PRINT(("userlandfs_create_symlink() done: (%lx)\n", error)); + return error; +} + +// userlandfs_link +static status_t +userlandfs_link(fs_volume fs, fs_vnode dir, const char *name, fs_vnode node) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_link(%p, %p, `%s', %p)\n", fs, dir, name, node)); + status_t error = volume->Link(dir, name, node); + PRINT(("userlandfs_link() done: (%lx)\n", error)); + return error; +} + +// userlandfs_unlink +static status_t +userlandfs_unlink(fs_volume fs, fs_vnode dir, const char *name) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_unlink(%p, %p, `%s')\n", fs, dir, name)); + status_t error = volume->Unlink(dir, name); + PRINT(("userlandfs_unlink() done: (%lx)\n", error)); + return error; +} + +// userlandfs_rename +static status_t +userlandfs_rename(fs_volume fs, fs_vnode fromDir, const char *fromName, + fs_vnode toDir, const char *toName) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_rename(%p, %p, `%s', %p, `%s')\n", fs, fromDir, fromName, + toDir, toName)); + status_t error = volume->Rename(fromDir, fromName, toDir, toName); + PRINT(("userlandfs_rename() done: (%lx)\n", error)); + return error; +} + +// userlandfs_access +static status_t +userlandfs_access(fs_volume fs, fs_vnode node, int mode) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_access(%p, %p, %d)\n", fs, node, mode)); + status_t error = volume->Access(node, mode); + PRINT(("userlandfs_access() done: %lx\n", error)); + return error; +} + +// userlandfs_read_stat +static status_t +userlandfs_read_stat(fs_volume fs, fs_vnode node, struct stat *st) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_read_stat(%p, %p, %p)\n", fs, node, st)); + status_t error = volume->ReadStat(node, st); + PRINT(("userlandfs_read_stat() done: %lx\n", error)); + return error; +} + +// userlandfs_write_stat +static status_t +userlandfs_write_stat(fs_volume fs, fs_vnode node, const struct stat *st, + uint32 mask) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_write_stat(%p, %p, %p, %ld)\n", fs, node, st, mask)); + status_t error = volume->WriteStat(node, st, mask); + PRINT(("userlandfs_write_stat() done: %lx\n", error)); + return error; +} + + +// #pragma mark - files + + +// userlandfs_create +static status_t +userlandfs_create(fs_volume fs, fs_vnode dir, const char *name, int openMode, + int perms, fs_cookie *cookie, vnode_id *vnid) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_create(%p, %p, `%s', %d, %d, %p, %p)\n", fs, dir, + name, openMode, perms, cookie, vnid)); + status_t error = volume->Create(dir, name, openMode, perms, cookie, vnid); + PRINT(("userlandfs_create() done: (%lx, %lld, %p)\n", error, *vnid, + *cookie)); + return error; +} + +// userlandfs_open +static status_t +userlandfs_open(fs_volume fs, fs_vnode node, int openMode, fs_cookie *cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_open(%p, %p, %d)\n", fs, node, openMode)); + status_t error = volume->Open(node, openMode, cookie); + PRINT(("userlandfs_open() done: (%lx, %p)\n", error, *cookie)); + return error; +} + +// userlandfs_close +static status_t +userlandfs_close(fs_volume fs, fs_vnode node, fs_cookie cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_close(%p, %p, %p)\n", fs, node, cookie)); + status_t error = volume->Close(node, cookie); + PRINT(("userlandfs_close() done: %lx\n", error)); + return error; +} + +// userlandfs_free_cookie +static status_t +userlandfs_free_cookie(fs_volume fs, fs_vnode node, fs_cookie cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_free_cookie(%p, %p, %p)\n", fs, node, cookie)); + status_t error = volume->FreeCookie(node, cookie); + PRINT(("userlandfs_free_cookie() done: %lx\n", error)); + return error; +} + +// userlandfs_read +static status_t +userlandfs_read(fs_volume fs, fs_vnode node, fs_cookie cookie, off_t pos, + void *buffer, size_t *length) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_read(%p, %p, %p, %Ld, %p, %lu)\n", nf, node, cookie, pos, + buffer, *length)); + status_t error = volume->Read(node, cookie, pos, buffer, *length, + length); + PRINT(("userlandfs_read() done: (%lx, %lu)\n", error, *length)); + return error; +} + +// userlandfs_write +static status_t +userlandfs_write(fs_volume fs, fs_vnode node, fs_cookie cookie, off_t pos, + const void *buffer, size_t *length) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_write(%p, %p, %p, %Ld, %p, %lu)\n", fs, node, cookie, + pos, buffer, *length)); + status_t error = volume->Write(node, cookie, pos, buffer, *length, length); + PRINT(("userlandfs_write() done: (%lx, %lu)\n", error, *length)); + return error; +} + + +// #pragma mark - directories + + +// userlandfs_create_dir +static status_t +userlandfs_create_dir(fs_volume fs, fs_vnode parent, const char *name, + int perms, vnode_id *newDir) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_create_dir(%p, %p, `%s', %d, %p)\n", fs, parent, name, + perms, newDir)); + status_t error = volume->CreateDir(parent, name, perms, newDir); + PRINT(("userlandfs_create_dir() done: (%lx, %lld)\n", error, *newDir)); + return error; +} + +// userlandfs_remove_dir +static status_t +userlandfs_remove_dir(fs_volume fs, fs_vnode parent, const char *name) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_remove_dir(%p, %p, `%s')\n", fs, parent, name)); + status_t error = volume->RemoveDir(parent, name); + PRINT(("userlandfs_remove_dir() done: (%lx)\n", error)); + return error; +} + +// userlandfs_open_dir +static status_t +userlandfs_open_dir(fs_volume fs, fs_vnode node, fs_cookie *cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_open_dir(%p, %p)\n", fs, node)); + status_t error = volume->OpenDir(node, cookie); + PRINT(("userlandfs_open_dir() done: (%lx, %p)\n", error, *cookie)); + return error; +} + +// userlandfs_close_dir +static status_t +userlandfs_close_dir(fs_volume fs, fs_vnode node, fs_cookie cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_close_dir(%p, %p, %p)\n", fs, node, cookie)); + status_t error = volume->CloseDir(node, cookie); + PRINT(("userlandfs_close_dir() done: %lx\n", error)); + return error; +} + +// userlandfs_free_dir_cookie +static status_t +userlandfs_free_dir_cookie(fs_volume fs, fs_vnode node, fs_cookie cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_free_dir_cookie(%p, %p, %p)\n", fs, node, cookie)); + status_t error = volume->FreeDirCookie(node, cookie); + PRINT(("userlandfs_free_dir_cookie() done: %lx \n", error)); + return error; +} + +// userlandfs_read_dir +static status_t +userlandfs_read_dir(fs_volume fs, fs_vnode node, fs_cookie cookie, + struct dirent *buffer, size_t bufferSize, uint32 *count) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_read_dir(%p, %p, %p, %p, %lu, %lu)\n", fs, node, cookie, + buffer, bufferSize, *count)); + status_t error = volume->ReadDir(node, cookie, buffer, bufferSize, *count, + count); + PRINT(("userlandfs_read_dir() done: (%lx, %lu)\n", error, *count)); + #if DEBUG + dirent* entry = buffer; + for (int32 i = 0; i < *count; i++) { + // R5's kernel vsprintf() doesn't seem to know `%.s', so + // we need to work around. + char name[B_FILE_NAME_LENGTH]; + int nameLen = strnlen(entry->d_name, B_FILE_NAME_LENGTH - 1); + strncpy(name, entry->d_name, nameLen); + name[nameLen] = '\0'; + PRINT((" entry: d_dev: %ld, d_pdev: %ld, d_ino: %Ld, d_pino: %Ld, " + "d_reclen: %hu, d_name: `%s'\n", + entry->d_dev, entry->d_pdev, entry->d_ino, entry->d_pino, + entry->d_reclen, name)); + entry = (dirent*)((char*)entry + entry->d_reclen); + } + #endif + return error; +} + +// userlandfs_rewind_dir +static status_t +userlandfs_rewind_dir(fs_volume fs, fs_vnode node, fs_cookie cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_rewind_dir(%p, %p, %p)\n", fs, node, cookie)); + status_t error = volume->RewindDir(node, cookie); + PRINT(("userlandfs_rewind_dir() done: %lx\n", error)); + return error; +} + + +// #pragma mark - attribute directories + + +// userlandfs_open_attr_dir +static status_t +userlandfs_open_attr_dir(fs_volume fs, fs_vnode node, fs_cookie *cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_open_attr_dir(%p, %p)\n", fs, node)); + status_t error = volume->OpenAttrDir(node, cookie); + PRINT(("userlandfs_open_attr_dir() done: (%lx, %p)\n", error, *cookie)); + return error; +} + +// userlandfs_close_attr_dir +static status_t +userlandfs_close_attr_dir(fs_volume fs, fs_vnode node, fs_cookie cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_close_attr_dir(%p, %p, %p)\n", fs, node, cookie)); + status_t error = volume->CloseAttrDir(node, cookie); + PRINT(("userlandfs_close_attr_dir() done: (%lx)\n", error)); + return error; +} + +// userlandfs_free_attr_dir_cookie +static status_t +userlandfs_free_attr_dir_cookie(fs_volume fs, fs_vnode node, fs_cookie cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_free_attr_dir_cookie(%p, %p, %p)\n", fs, node, cookie)); + status_t error = volume->FreeAttrDirCookie(node, cookie); + PRINT(("userlandfs_free_attr_dir_cookie() done: (%lx)\n", error)); + return error; +} + +// userlandfs_read_attr_dir +static status_t +userlandfs_read_attr_dir(fs_volume fs, fs_vnode node, fs_cookie cookie, + struct dirent *buffer, size_t bufferSize, uint32 *count) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_read_attr_dir(%p, %p, %p, %p, %lu, %lu)\n", fs, node, + cookie, buffer, bufferSize, *count)); + status_t error = volume->ReadAttrDir(node, cookie, buffer, bufferSize, + *count, count); + PRINT(("userlandfs_read_attr_dir() done: (%lx, %lu)\n", error, *count)); + return error; +} + +// userlandfs_rewind_attr_dir +static status_t +userlandfs_rewind_attr_dir(fs_volume fs, fs_vnode node, fs_cookie cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_rewind_attr_dir(%p, %p, %p)\n", fs, node, cookie)); + status_t error = volume->RewindAttrDir(node, cookie); + PRINT(("userlandfs_rewind_attr_dir() done: (%lx)\n", error)); + return error; +} + + +// #pragma mark - attributes + + +// TODO: create_attr() +// TODO: open_attr() +// TODO: close_attr() +// TODO: free_attr_cookie() + +// userlandfs_read_attr +static status_t +userlandfs_read_attr(fs_volume fs, fs_vnode node, fs_cookie cookie, + off_t pos, void *buffer, size_t *length) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_read_attr(%p, %p, %p, %lld, %p, %lu)\n", fs, node, + cookie, pos, buffer, *length)); + status_t error = volume->ReadAttr(node, cookie, pos, buffer, *length, + length); + PRINT(("userlandfs_read_attr() done: (%lx, %lu)\n", error, *length)); + return error; +} + +// userlandfs_write_attr +static status_t +userlandfs_write_attr(fs_volume fs, fs_vnode node, fs_cookie cookie, + off_t pos, const void *buffer, size_t *length) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_write_attr(%p, %p, %p, %lld, %p, %lu)\n", fs, node, + cookie, pos, buffer, *length)); + status_t error = volume->WriteAttr(node, cookie, pos, buffer, *length, + length); + PRINT(("userlandfs_write_attr() done: (%lx, %lu)\n", error, *length)); + return error; +} + +// userlandfs_read_attr_stat +static status_t +userlandfs_read_attr_stat(fs_volume fs, fs_vnode node, fs_cookie cookie, + struct stat *st) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_read_attr_stat(%p, %p, %p', %p)\n", fs, node, cookie, + st)); + status_t error = volume->ReadAttrStat(node, cookie, st); + PRINT(("userlandfs_read_attr_stat() done: (%lx)\n", error)); + return error; +} + +// TODO: userlandfs_write_attr_stat + +// userlandfs_rename_attr +static status_t +userlandfs_rename_attr(fs_volume fs, fs_vnode fromNode, const char *fromName, + fs_vnode toNode, const char *toName) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_rename_attr(%p, %p, `%s', %p, `%s')\n", fs, fromNode, + fromName, toNode, toName)); + status_t error = volume->RenameAttr(fromNode, fromName, toNode, toName); + PRINT(("userlandfs_rename_attr() done: (%lx)\n", error)); + return error; +} + +// userlandfs_remove_attr +static status_t +userlandfs_remove_attr(fs_volume fs, fs_vnode node, const char *name) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_remove_attr(%p, %p, `%s')\n", fs, node, name)); + status_t error = volume->RemoveAttr(node, name); + PRINT(("userlandfs_remove_attr() done: (%lx)\n", error)); + return error; +} + + +// #pragma mark - indices + + +// userlandfs_open_index_dir +static status_t +userlandfs_open_index_dir(fs_volume fs, fs_cookie *cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_open_index_dir(%p, %p)\n", fs, cookie)); + status_t error = volume->OpenIndexDir(cookie); + PRINT(("userlandfs_open_index_dir() done: (%lx, %p)\n", error, *cookie)); + return error; +} + +// userlandfs_close_index_dir +static status_t +userlandfs_close_index_dir(fs_volume fs, fs_cookie cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_close_index_dir(%p, %p)\n", fs, cookie)); + status_t error = volume->CloseIndexDir(cookie); + PRINT(("userlandfs_close_index_dir() done: (%lx)\n", error)); + return error; +} + +// userlandfs_free_index_dir_cookie +static status_t +userlandfs_free_index_dir_cookie(fs_volume fs, fs_cookie cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_free_index_dir_cookie(%p, %p)\n", fs, cookie)); + status_t error = volume->FreeIndexDirCookie(cookie); + PRINT(("userlandfs_free_index_dir_cookie() done: (%lx)\n", error)); + return error; +} + +// userlandfs_read_index_dir +static status_t +userlandfs_read_index_dir(fs_volume fs, fs_cookie cookie, + struct dirent *buffer, size_t bufferSize, uint32 *count) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_read_index_dir(%p, %p, %p, %lu, %lu)\n", fs, cookie, + buffer, bufferSize, *count)); + status_t error = volume->ReadIndexDir(cookie, buffer, bufferSize, + *count, count); + PRINT(("userlandfs_read_index_dir() done: (%lx, %lu)\n", error, *count)); + return error; +} + +// userlandfs_rewind_index_dir +static status_t +userlandfs_rewind_index_dir(fs_volume fs, fs_cookie cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_rewind_index_dir(%p, %p)\n", fs, cookie)); + status_t error = volume->RewindIndexDir(cookie); + PRINT(("userlandfs_rewind_index_dir() done: (%lx)\n", error)); + return error; +} + +// userlandfs_create_index +static status_t +userlandfs_create_index(fs_volume fs, const char *name, uint32 type, + uint32 flags) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_create_index(%p, `%s', 0x%lx, 0x%lx)\n", fs, name, type, + flags)); + status_t error = volume->CreateIndex(name, type, flags); + PRINT(("userlandfs_create_index() done: (%lx)\n", error)); + return error; +} + +// userlandfs_remove_index +static status_t +userlandfs_remove_index(fs_volume fs, const char *name) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_remove_index(%p, `%s')\n", fs, name)); + status_t error = volume->RemoveIndex(name); + PRINT(("userlandfs_remove_index() done: (%lx)\n", error)); + return error; +} + +// userlandfs_read_index_stat +static status_t +userlandfs_read_index_stat(fs_volume fs, const char *name, struct stat *st) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_read_index_stat(%p, `%s', %p)\n", s, name, st)); + status_t error = volume->ReadIndexStat(name, st); + PRINT(("userlandfs_read_index_stat() done: (%lx)\n", error)); + return error; +} + + +// #pragma mark - queries + + +// userlandfs_open_query +static status_t +userlandfs_open_query(fs_volume fs, const char *queryString, uint32 flags, + port_id port, uint32 token, fs_cookie *cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_open_query(%p, `%s', %lu, %ld, %lu, %p)\n", fs, + queryString, flags, port, token, cookie)); + status_t error = volume->OpenQuery(queryString, flags, port, token, cookie); + PRINT(("userlandfs_open_query() done: (%lx, %p)\n", error, *cookie)); + return error; +} + +// userlandfs_close_query +static status_t +userlandfs_close_query(fs_volume fs, fs_cookie cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_close_query(%p, %p)\n", fs, cookie)); + status_t error = volume->CloseQuery(cookie); + PRINT(("userlandfs_close_query() done: (%lx)\n", error)); + return error; +} + +// userlandfs_free_query_cookie +static status_t +userlandfs_free_query_cookie(fs_volume fs, fs_cookie cookie) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_free_query_cookie(%p, %p)\n", fs, cookie)); + status_t error = volume->FreeQueryCookie(cookie); + PRINT(("userlandfs_free_query_cookie() done: (%lx)\n", error)); + return error; +} + +// userlandfs_read_query +static status_t +userlandfs_read_query(fs_volume fs, fs_cookie cookie, + struct dirent *buffer, size_t bufferSize, uint32 *count) +{ + Volume* volume = (Volume*)fs; + PRINT(("userlandfs_read_query(%p, %p, %p, %lu, %lu)\n", fs, cookie, + buffer, bufferSize, *count)); + status_t error = volume->ReadQuery(cookie, buffer, bufferSize, *count, + count); + PRINT(("userlandfs_read_query() done: (%lx, %ld)\n", error, *count)); + #if DEBUG + if (*count > 0) { + // R5's kernel vsprintf() doesn't seem to know `%.s', so + // we need to work around. + char name[B_FILE_NAME_LENGTH]; + int nameLen = strnlen(buffer->d_name, B_FILE_NAME_LENGTH - 1); + strncpy(name, buffer->d_name, nameLen); + name[nameLen] = '\0'; + PRINT((" entry: d_dev: %ld, d_pdev: %ld, d_ino: %Ld, d_pino: %Ld, " + "d_reclen: %hu, d_name: `%s'\n", + buffer->d_dev, buffer->d_pdev, buffer->d_ino, buffer->d_pino, + buffer->d_reclen, name)); + } + #endif + return error; +} + +// TODO: userlandfs_rewind_query() + + // userlandfs_initialize -/*static -int +/* +static status_t userlandfs_initialize(const char *deviceName, void *parameters, size_t len) { @@ -149,784 +903,6 @@ userlandfs_initialize(const char *deviceName, void *parameters, return error; }*/ -// userlandfs_sync -static -int -userlandfs_sync(void *ns) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_sync(%p)\n", ns)); - status_t error = volume->Sync(); - PRINT(("userlandfs_sync() done: %lx \n", error)); - return error; -} - -// userlandfs_read_fs_stat -static -int -userlandfs_read_fs_stat(void *ns, struct fs_info *info) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_read_fs_stat(%p, %p)\n", ns, info)); - status_t error = volume->ReadFSStat(info); - PRINT(("userlandfs_read_fs_stat() done: %lx \n", error)); - return error; -} - -// userlandfs_write_fs_stat -static -int -userlandfs_write_fs_stat(void *ns, struct fs_info *info, long mask) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_write_fs_stat(%p, %p, %ld)\n", ns, info, mask)); - status_t error = volume->WriteFSStat(info, mask); - PRINT(("userlandfs_write_fs_stat() done: %lx \n", error)); - return error; -} - -// #pragma mark - -// #pragma mark ----- vnodes ----- - -// userlandfs_read_vnode -static -int -userlandfs_read_vnode(void *ns, vnode_id vnid, char reenter, void **node) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_read_vnode(%p, %Ld, %d, %p)\n", ns, vnid, reenter, - node)); - status_t error = volume->ReadVNode(vnid, reenter, node); - PRINT(("userlandfs_read_vnode() done: (%lx, %p)\n", error, *node)); - return error; -} - -// userlandfs_write_vnode -static -int -userlandfs_write_vnode(void *ns, void *node, char reenter) -{ - Volume* volume = (Volume*)ns; -// DANGER: If dbg_printf() is used, this thread will enter another FS and -// even perform a write operation. The is dangerous here, since this hook -// may be called out of the other FSs, since, for instance a put_vnode() -// called from another FS may cause the VFS layer to free vnodes and thus -// invoke this hook. -// PRINT(("userlandfs_write_vnode(%p, %p, %d)\n", ns, node, reenter)); - status_t error = volume->WriteVNode(node, reenter); -// PRINT(("userlandfs_write_vnode() done: %lx\n", error)); - return error; -} - -// userlandfs_remove_vnode -static -int -userlandfs_remove_vnode(void *ns, void *node, char reenter) -{ - Volume* volume = (Volume*)ns; -// DANGER: See userlandfs_write_vnode(). -// PRINT(("userlandfs_remove_vnode(%p, %p, %d)\n", ns, node, reenter)); - status_t error = volume->RemoveVNode(node, reenter); -// PRINT(("userlandfs_remove_vnode() done: %lx\n", error)); - return error; -} - -// #pragma mark - -// #pragma mark ----- nodes ----- - -// userlandfs_fsync -static -int -userlandfs_fsync(void *ns, void *node) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_fsync(%p, %p)\n", ns, node)); - status_t error = volume->FSync(node); - PRINT(("userlandfs_fsync() done: %lx\n", error)); - return error; -} - -// userlandfs_read_stat -static -int -userlandfs_read_stat(void *ns, void *node, struct stat *st) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_read_stat(%p, %p, %p)\n", ns, node, st)); - status_t error = volume->ReadStat(node, st); - PRINT(("userlandfs_read_stat() done: %lx\n", error)); - return error; -} - -// userlandfs_write_stat -static -int -userlandfs_write_stat(void *ns, void *node, struct stat *st, long mask) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_write_stat(%p, %p, %p, %ld)\n", ns, node, st, mask)); - status_t error = volume->WriteStat(node, st, mask); - PRINT(("userlandfs_write_stat() done: %lx\n", error)); - return error; -} - -// userlandfs_access -static -int -userlandfs_access(void *ns, void *node, int mode) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_access(%p, %p, %d)\n", ns, node, mode)); - status_t error = volume->Access(node, mode); - PRINT(("userlandfs_access() done: %lx\n", error)); - return error; -} - -// #pragma mark - -// #pragma mark ----- files ----- - -// userlandfs_create -static -int -userlandfs_create(void *ns, void *dir, const char *name, int openMode, int mode, - vnode_id *vnid, void **cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_create(%p, %p, `%s', %d, %d, %p, %p)\n", ns, dir, - name, openMode, mode, vnid, cookie)); - status_t error = volume->Create(dir, name, openMode, mode, vnid, cookie); - PRINT(("userlandfs_create() done: (%lx, %Ld, %p)\n", error, *vnid, - *cookie)); - return error; -} - -// userlandfs_open -static -int -userlandfs_open(void *ns, void *node, int openMode, void **cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_open(%p, %p, %d)\n", ns, node, openMode)); - status_t error = volume->Open(node, openMode, cookie); - PRINT(("userlandfs_open() done: (%lx, %p)\n", error, *cookie)); - return error; -} - -// userlandfs_close -static -int -userlandfs_close(void *ns, void *node, void *cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_close(%p, %p, %p)\n", ns, node, cookie)); - status_t error = volume->Close(node, cookie); - PRINT(("userlandfs_close() done: %lx\n", error)); - return error; -} - -// userlandfs_free_cookie -static -int -userlandfs_free_cookie(void *ns, void *node, void *cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_free_cookie(%p, %p, %p)\n", ns, node, cookie)); - status_t error = volume->FreeCookie(node, cookie); - PRINT(("userlandfs_free_cookie() done: %lx\n", error)); - return error; -} - -// userlandfs_read -static -int -userlandfs_read(void *ns, void *node, void *cookie, off_t pos, void *buffer, - size_t *bufferSize) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_read(%p, %p, %p, %Ld, %p, %lu)\n", ns, node, cookie, pos, - buffer, *bufferSize)); - status_t error = volume->Read(node, cookie, pos, buffer, *bufferSize, - bufferSize); - PRINT(("userlandfs_read() done: (%lx, %lu)\n", error, *bufferSize)); - return error; -} - -// userlandfs_write -static -int -userlandfs_write(void *ns, void *node, void *cookie, off_t pos, - const void *buffer, size_t *bufferSize) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_write(%p, %p, %p, %Ld, %p, %lu)\n", ns, node, cookie, pos, - buffer, *bufferSize)); - status_t error = volume->Write(node, cookie, pos, buffer, *bufferSize, - bufferSize); - PRINT(("userlandfs_write() done: (%lx, %lu)\n", error, *bufferSize)); - return error; -} - -// userlandfs_ioctl -static -int -userlandfs_ioctl(void *ns, void *node, void *cookie, int cmd, void *buffer, - size_t bufferSize) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_ioctl(%p, %p, %p, %d, %p, %lu)\n", ns, node, cookie, cmd, - buffer, bufferSize)); - status_t error = volume->IOCtl(node, cookie, cmd, buffer, bufferSize); - PRINT(("userlandfs_ioctl() done: (%lx)\n", error)); - return error; -} - -// userlandfs_setflags -static -int -userlandfs_setflags(void *ns, void *node, void *cookie, int flags) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_setflags(%p, %p, %p, %d)\n", ns, node, cookie, flags)); - status_t error = volume->SetFlags(node, cookie, flags); - PRINT(("userlandfs_setflags() done: (%lx)\n", error)); - return error; -} - -// userlandfs_select -static -int -userlandfs_select(void *ns, void *node, void *cookie, uint8 event, uint32 ref, - selectsync *sync) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_select(%p, %p, %p, %hhd, %lu, %p)\n", ns, node, cookie, - event, ref, sync)); - status_t error = volume->Select(node, cookie, event, ref, sync); - PRINT(("userlandfs_select() done: (%lx)\n", error)); - return error; -} - -// userlandfs_deselect -static -int -userlandfs_deselect(void *ns, void *node, void *cookie, uint8 event, - selectsync *sync) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_deselect(%p, %p, %p, %hhd, %p)\n", ns, node, cookie, - event, sync)); - status_t error = volume->Deselect(node, cookie, event, sync); - PRINT(("userlandfs_deselect() done: (%lx)\n", error)); - return error; -} - -// #pragma mark - -// #pragma mark ----- hard links / symlinks ----- - -// userlandfs_link -static -int -userlandfs_link(void *ns, void *dir, const char *name, void *node) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_link(%p, %p, `%s', %p)\n", ns, dir, name, node)); - status_t error = volume->Link(dir, name, node); - PRINT(("userlandfs_link() done: (%lx)\n", error)); - return error; -} - -// userlandfs_unlink -static -int -userlandfs_unlink(void *ns, void *dir, const char *name) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_unlink(%p, %p, `%s')\n", ns, dir, name)); - status_t error = volume->Unlink(dir, name); - PRINT(("userlandfs_unlink() done: (%lx)\n", error)); - return error; -} - -// userlandfs_symlink -static -int -userlandfs_symlink(void *ns, void *dir, const char *name, const char *path) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_symlink(%p, %p, `%s', `%s')\n", ns, dir, name, path)); - status_t error = volume->Symlink(dir, name, path); - PRINT(("userlandfs_symlink() done: (%lx)\n", error)); - return error; -} - -// userlandfs_read_link -static -int -userlandfs_read_link(void *ns, void *node, char *buffer, size_t *bufferSize) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_read_link(%p, %p, %p, %lu)\n", ns, node, buffer, - *bufferSize)); - status_t error = volume->ReadLink(node, buffer, *bufferSize, bufferSize); - PRINT(("userlandfs_read_link() done: (%lx, %lu)\n", error, *bufferSize)); - return error; -} - -// userlandfs_rename -static -int -userlandfs_rename(void *ns, void *oldDir, const char *oldName, void *newDir, - const char *newName) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_rename(%p, %p, `%s', %p, `%s')\n", ns, oldDir, oldName, - newDir, newName)); - status_t error = volume->Rename(oldDir, oldName, newDir, newName); - PRINT(("userlandfs_rename() done: (%lx)\n", error)); - return error; -} - -// #pragma mark - -// #pragma mark ----- directories ----- - -// userlandfs_mkdir -static -int -userlandfs_mkdir(void *ns, void *dir, const char *name, int mode) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_mkdir(%p, %p, `%s', %d)\n", ns, dir, name, mode)); - status_t error = volume->MkDir(dir, name, mode); - PRINT(("userlandfs_mkdir() done: (%lx)\n", error)); - return error; -} - -// userlandfs_rmdir -static -int -userlandfs_rmdir(void *ns, void *dir, const char *name) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_rmdir(%p, %p, `%s')\n", ns, dir, name)); - status_t error = volume->RmDir(dir, name); - PRINT(("userlandfs_rmdir() done: (%lx)\n", error)); - return error; -} - -// userlandfs_open_dir -static -int -userlandfs_open_dir(void *ns, void *node, void **cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_open_dir(%p, %p)\n", ns, node)); - status_t error = volume->OpenDir(node, cookie); - PRINT(("userlandfs_open_dir() done: (%lx, %p)\n", error, *cookie)); - return error; -} - -// userlandfs_close_dir -static -int -userlandfs_close_dir(void *ns, void *node, void *cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_close_dir(%p, %p, %p)\n", ns, node, cookie)); - status_t error = volume->CloseDir(node, cookie); - PRINT(("userlandfs_close_dir() done: %lx\n", error)); - return error; -} - -// userlandfs_free_dir_cookie -static -int -userlandfs_free_dir_cookie(void *ns, void *node, void *cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_free_dir_cookie(%p, %p, %p)\n", ns, node, cookie)); - status_t error = volume->FreeDirCookie(node, cookie); - PRINT(("userlandfs_free_dir_cookie() done: %lx \n", error)); - return error; -} - -// userlandfs_read_dir -static -int -userlandfs_read_dir(void *ns, void *node, void *cookie, long *count, - struct dirent *buffer, size_t bufferSize) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_read_dir(%p, %p, %p, %ld, %p, %lu)\n", ns, node, cookie, - *count, buffer, bufferSize)); - status_t error = volume->ReadDir(node, cookie, buffer, bufferSize, *count, - count); - PRINT(("userlandfs_read_dir() done: (%lx, %ld)\n", error, *count)); - #if DEBUG - dirent* entry = buffer; - for (int32 i = 0; i < *count; i++) { - // R5's kernel vsprintf() doesn't seem to know `%.s', so - // we need to work around. - char name[B_FILE_NAME_LENGTH]; - int nameLen = strnlen(entry->d_name, B_FILE_NAME_LENGTH - 1); - strncpy(name, entry->d_name, nameLen); - name[nameLen] = '\0'; - PRINT((" entry: d_dev: %ld, d_pdev: %ld, d_ino: %Ld, d_pino: %Ld, " - "d_reclen: %hu, d_name: `%s'\n", - entry->d_dev, entry->d_pdev, entry->d_ino, entry->d_pino, - entry->d_reclen, name)); - entry = (dirent*)((char*)entry + entry->d_reclen); - } - #endif - return error; -} - -// userlandfs_rewind_dir -static -int -userlandfs_rewind_dir(void *ns, void *node, void *cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_rewind_dir(%p, %p, %p)\n", ns, node, cookie)); - status_t error = volume->RewindDir(node, cookie); - PRINT(("userlandfs_rewind_dir() done: %lx\n", error)); - return error; -} - -// userlandfs_walk -static -int -userlandfs_walk(void *ns, void *dir, const char *entryName, - char **resolvedPath, vnode_id *vnid) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_walk(%p, %p, `%s', %p, %p)\n", ns, dir, - entryName, resolvedPath, vnid)); - status_t error = volume->Walk(dir, entryName, resolvedPath, vnid); - PRINT(("userlandfs_walk() done: (%lx, `%s', %Ld)\n", error, - (resolvedPath ? *resolvedPath : NULL), *vnid)); - return error; -} - -// #pragma mark - -// #pragma mark ----- attributes ----- - -// userlandfs_open_attrdir -static -int -userlandfs_open_attrdir(void *ns, void *node, void **cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_open_attrdir(%p, %p)\n", ns, node)); - status_t error = volume->OpenAttrDir(node, cookie); - PRINT(("userlandfs_open_attrdir() done: (%lx, %p)\n", error, *cookie)); - return error; -} - -// userlandfs_close_attrdir -static -int -userlandfs_close_attrdir(void *ns, void *node, void *cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_close_attrdir(%p, %p, %p)\n", ns, node, cookie)); - status_t error = volume->CloseAttrDir(node, cookie); - PRINT(("userlandfs_close_attrdir() done: (%lx)\n", error)); - return error; -} - -// userlandfs_free_attrdir_cookie -static -int -userlandfs_free_attrdir_cookie(void *ns, void *node, void *cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_free_attrdir_cookie(%p, %p, %p)\n", ns, node, cookie)); - status_t error = volume->FreeAttrDirCookie(node, cookie); - PRINT(("userlandfs_free_attrdir_cookie() done: (%lx)\n", error)); - return error; -} - -// userlandfs_read_attrdir -static -int -userlandfs_read_attrdir(void *ns, void *node, void *cookie, long *count, - struct dirent *buffer, size_t bufferSize) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_read_attrdir(%p, %p, %p, %ld, %p, %lu)\n", ns, node, - cookie, *count, buffer, bufferSize)); - status_t error = volume->ReadAttrDir(node, cookie, buffer, bufferSize, - *count, count); - PRINT(("userlandfs_read_attrdir() done: (%lx, %ld)\n", error, *count)); - return error; -} - -// userlandfs_rewind_attrdir -static -int -userlandfs_rewind_attrdir(void *ns, void *node, void *cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_rewind_attrdir(%p, %p, %p)\n", ns, node, cookie)); - status_t error = volume->RewindAttrDir(node, cookie); - PRINT(("userlandfs_rewind_attrdir() done: (%lx)\n", error)); - return error; -} - -// userlandfs_read_attr -static -int -userlandfs_read_attr(void *ns, void *node, const char *name, int type, - void *buffer, size_t *bufferSize, off_t pos) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_read_attr(%p, %p, `%s', %d, %p, %lu, %Ld)\n", ns, node, - name, type, buffer, *bufferSize, pos)); - status_t error = volume->ReadAttr(node, name, type, pos, buffer, - *bufferSize, bufferSize); - PRINT(("userlandfs_read_attr() done: (%lx, %ld)\n", error, *bufferSize)); - return error; -} - -// userlandfs_write_attr -static -int -userlandfs_write_attr(void *ns, void *node, const char *name, int type, - const void *buffer, size_t *bufferSize, off_t pos) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_write_attr(%p, %p, `%s', %d, %p, %lu, %Ld)\n", ns, node, - name, type, buffer, *bufferSize, pos)); - status_t error = volume->WriteAttr(node, name, type, pos, buffer, - *bufferSize, bufferSize); - PRINT(("userlandfs_write_attr() done: (%lx, %ld)\n", error, *bufferSize)); - return error; -} - -// userlandfs_remove_attr -static -int -userlandfs_remove_attr(void *ns, void *node, const char *name) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_remove_attr(%p, %p, `%s')\n", ns, node, name)); - status_t error = volume->RemoveAttr(node, name); - PRINT(("userlandfs_remove_attr() done: (%lx)\n", error)); - return error; -} - -// userlandfs_rename_attr -static -int -userlandfs_rename_attr(void *ns, void *node, const char *oldName, - const char *newName) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_rename_attr(%p, %p, `%s', `%s')\n", ns, node, oldName, - newName)); - status_t error = volume->RenameAttr(node, oldName, newName); - PRINT(("userlandfs_rename_attr() done: (%lx)\n", error)); - return error; -} - -// userlandfs_stat_attr -static -int -userlandfs_stat_attr(void *ns, void *node, const char *name, - struct attr_info *attrInfo) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_stat_attr(%p, %p, `%s', %p)\n", ns, node, name, - attrInfo)); - status_t error = volume->StatAttr(node, name, attrInfo); - PRINT(("userlandfs_stat_attr() done: (%lx)\n", error)); - return error; -} - -// #pragma mark - -// #pragma mark ----- indices ----- - -// userlandfs_open_indexdir -static -int -userlandfs_open_indexdir(void *ns, void **cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_open_indexdir(%p, %p)\n", ns, cookie)); - status_t error = volume->OpenIndexDir(cookie); - PRINT(("userlandfs_open_indexdir() done: (%lx, %p)\n", error, *cookie)); - return error; -} - -// userlandfs_close_indexdir -static -int -userlandfs_close_indexdir(void *ns, void *cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_close_indexdir(%p, %p)\n", ns, cookie)); - status_t error = volume->CloseIndexDir(cookie); - PRINT(("userlandfs_close_indexdir() done: (%lx)\n", error)); - return error; -} - -// userlandfs_free_indexdir_cookie -static -int -userlandfs_free_indexdir_cookie(void *ns, void *node, void *cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_free_indexdir_cookie(%p, %p)\n", ns, cookie)); - status_t error = volume->FreeIndexDirCookie(cookie); - PRINT(("userlandfs_free_indexdir_cookie() done: (%lx)\n", error)); - return error; -} - -// userlandfs_read_indexdir -static -int -userlandfs_read_indexdir(void *ns, void *cookie, long *count, - struct dirent *buffer, size_t bufferSize) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_read_indexdir(%p, %p, %ld, %p, %lu)\n", ns, cookie, - *count, buffer, bufferSize)); - status_t error = volume->ReadIndexDir(cookie, buffer, bufferSize, - *count, count); - PRINT(("userlandfs_read_indexdir() done: (%lx, %ld)\n", error, *count)); - return error; -} - -// userlandfs_rewind_indexdir -static -int -userlandfs_rewind_indexdir(void *ns, void *cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_rewind_indexdir(%p, %p)\n", ns, cookie)); - status_t error = volume->RewindIndexDir(cookie); - PRINT(("userlandfs_rewind_indexdir() done: (%lx)\n", error)); - return error; -} - -// userlandfs_create_index -static -int -userlandfs_create_index(void *ns, const char *name, int type, int flags) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_create_index(%p, `%s', %d, %d)\n", ns, name, type, - flags)); - status_t error = volume->CreateIndex(name, type, flags); - PRINT(("userlandfs_create_index() done: (%lx)\n", error)); - return error; -} - -// userlandfs_remove_index -static -int -userlandfs_remove_index(void *ns, const char *name) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_remove_index(%p, `%s')\n", ns, name)); - status_t error = volume->RemoveIndex(name); - PRINT(("userlandfs_remove_index() done: (%lx)\n", error)); - return error; -} - -// userlandfs_rename_index -static -int -userlandfs_rename_index(void *ns, const char *oldName, const char *newName) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_rename_index(%p, `%s', `%s')\n", ns, oldName, newName)); - status_t error = volume->RenameIndex(oldName, newName); - PRINT(("userlandfs_rename_index() done: (%lx)\n", error)); - return error; -} - -// userlandfs_stat_index -static -int -userlandfs_stat_index(void *ns, const char *name, struct index_info *indexInfo) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_stat_index(%p, `%s', %p)\n", ns, name, indexInfo)); - status_t error = volume->StatIndex(name, indexInfo); - PRINT(("userlandfs_stat_index() done: (%lx)\n", error)); - return error; -} - -// #pragma mark - -// #pragma mark ----- queries ----- - -// userlandfs_open_query -static -int -userlandfs_open_query(void *ns, const char *queryString, ulong flags, - port_id port, long token, void **cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_open_query(%p, `%s', %lu, %ld, %ld, %p)\n", ns, - queryString, flags, port, token, cookie)); - status_t error = volume->OpenQuery(queryString, flags, port, token, cookie); - PRINT(("userlandfs_open_query() done: (%lx, %p)\n", error, *cookie)); - return error; -} - -// userlandfs_close_query -static -int -userlandfs_close_query(void *ns, void *cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_close_query(%p, %p)\n", ns, cookie)); - status_t error = volume->CloseQuery(cookie); - PRINT(("userlandfs_close_query() done: (%lx)\n", error)); - return error; -} - -// userlandfs_free_query_cookie -static -int -userlandfs_free_query_cookie(void *ns, void *node, void *cookie) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_free_query_cookie(%p, %p)\n", ns, cookie)); - status_t error = volume->FreeQueryCookie(cookie); - PRINT(("userlandfs_free_query_cookie() done: (%lx)\n", error)); - return error; -} - -// userlandfs_read_query -static -int -userlandfs_read_query(void *ns, void *cookie, long *count, - struct dirent *buffer, size_t bufferSize) -{ - Volume* volume = (Volume*)ns; - PRINT(("userlandfs_read_query(%p, %p, %ld, %p, %lu)\n", ns, cookie, - *count, buffer, bufferSize)); - status_t error = volume->ReadQuery(cookie, buffer, bufferSize, - *count, count); - PRINT(("userlandfs_read_query() done: (%lx, %ld)\n", error, *count)); - #if DEBUG - if (*count > 0) { - // R5's kernel vsprintf() doesn't seem to know `%.s', so - // we need to work around. - char name[B_FILE_NAME_LENGTH]; - int nameLen = strnlen(buffer->d_name, B_FILE_NAME_LENGTH - 1); - strncpy(name, buffer->d_name, nameLen); - name[nameLen] = '\0'; - PRINT((" entry: d_dev: %ld, d_pdev: %ld, d_ino: %Ld, d_pino: %Ld, " - "d_reclen: %hu, d_name: `%s'\n", - buffer->d_dev, buffer->d_pdev, buffer->d_ino, buffer->d_pino, - buffer->d_reclen, name)); - } - #endif - return error; -} // #pragma mark ----- module ----- @@ -937,19 +913,22 @@ userlandfs_std_ops(int32 op, ...) { switch (op) { case B_MODULE_INIT: + { init_debugging(); // make sure there is a UserlandFS we can work with UserlandFS* userlandFS = NULL; - error = UserlandFS::RegisterUserlandFS(&userlandFS); + status_t error = UserlandFS::InitUserlandFS(&userlandFS); if (error != B_OK) { exit_debugging(); return error; } return B_OK; + } case B_MODULE_UNINIT: + UserlandFS::UninitUserlandFS(); exit_debugging(); return B_OK; @@ -976,31 +955,31 @@ static file_system_module_info sUserlandFSModuleInfo = { &userlandfs_mount, &userlandfs_unmount, - &userlandfs_read_fs_stat, - &userlandfs_write_fs_stat, + &userlandfs_read_fs_info, + &userlandfs_write_fs_info, &userlandfs_sync, /* vnode operations */ &userlandfs_lookup, - &userlandfs_get_vnode_name, - &userlandfs_read_vnode, - &userlandfs_release_vnode, + NULL, // &userlandfs_get_vnode_name, + &userlandfs_get_vnode, + &userlandfs_put_vnode, &userlandfs_remove_vnode, /* VM file access */ - &userlandfs_can_page, - &userlandfs_read_pages, - &userlandfs_write_pages, + NULL, // &userlandfs_can_page, + NULL, // &userlandfs_read_pages, + NULL, // &userlandfs_write_pages, - &userlandfs_get_file_map, + NULL, // &userlandfs_get_file_map, &userlandfs_ioctl, &userlandfs_set_flags, - NULL, // &userlandfs_select - NULL, // &userlandfs_deselect + &userlandfs_select, + &userlandfs_deselect, &userlandfs_fsync, - &userlandfs_read_link, + &userlandfs_read_symlink, NULL, // write link &userlandfs_create_symlink, @@ -1037,15 +1016,15 @@ static file_system_module_info sUserlandFSModuleInfo = { &userlandfs_rewind_attr_dir, /* attribute operations */ - &userlandfs_create_attr, - &userlandfs_open_attr, - &userlandfs_close_attr, - &userlandfs_free_attr_cookie, + NULL, // &userlandfs_create_attr, + NULL, // &userlandfs_open_attr, + NULL, // &userlandfs_close_attr, + NULL, // &userlandfs_free_attr_cookie, &userlandfs_read_attr, &userlandfs_write_attr, &userlandfs_read_attr_stat, - &userlandfs_write_attr_stat, + NULL, // &userlandfs_write_attr_stat, &userlandfs_rename_attr, &userlandfs_remove_attr, @@ -1058,14 +1037,14 @@ static file_system_module_info sUserlandFSModuleInfo = { &userlandfs_create_index, &userlandfs_remove_index, - &userlandfs_stat_index, + &userlandfs_read_index_stat, /* query operations */ &userlandfs_open_query, &userlandfs_close_query, &userlandfs_free_query_cookie, &userlandfs_read_query, - &userlandfs_rewind_query, + NULL, // &userlandfs_rewind_query, }; module_info *modules[] = { diff --git a/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp b/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp index 119e8fd065..a1f1d10ba8 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp @@ -44,14 +44,14 @@ MountVolumeRequest::GetAddressInfos(AddressInfo* infos, int32* count) return B_OK; } -// InitializeVolumeRequest -status_t -InitializeVolumeRequest::GetAddressInfos(AddressInfo* infos, int32* count) -{ - ADD_STRING(device); - ADD_STRING(parameters); - return B_OK; -} +//// InitializeVolumeRequest +//status_t +//InitializeVolumeRequest::GetAddressInfos(AddressInfo* infos, int32* count) +//{ +// ADD_STRING(device); +// ADD_STRING(parameters); +// return B_OK; +//} // CreateRequest status_t @@ -109,18 +109,18 @@ UnlinkRequest::GetAddressInfos(AddressInfo* infos, int32* count) return B_OK; } -// SymlinkRequest +// CreateSymlinkRequest status_t -SymlinkRequest::GetAddressInfos(AddressInfo* infos, int32* count) +CreateSymlinkRequest::GetAddressInfos(AddressInfo* infos, int32* count) { ADD_NON_NULL_STRING(name); ADD_NON_NULL_STRING(target); return B_OK; } -// ReadLinkReply +// ReadSymlinkReply status_t -ReadLinkReply::GetAddressInfos(AddressInfo* infos, int32* count) +ReadSymlinkReply::GetAddressInfos(AddressInfo* infos, int32* count) { ADD_STRING(buffer); return B_OK; @@ -135,17 +135,17 @@ RenameRequest::GetAddressInfos(AddressInfo* infos, int32* count) return B_OK; } -// MkDirRequest +// CreateDirRequest status_t -MkDirRequest::GetAddressInfos(AddressInfo* infos, int32* count) +CreateDirRequest::GetAddressInfos(AddressInfo* infos, int32* count) { ADD_NON_NULL_STRING(name); return B_OK; } -// RmDirRequest +// RemoveDirRequest status_t -RmDirRequest::GetAddressInfos(AddressInfo* infos, int32* count) +RemoveDirRequest::GetAddressInfos(AddressInfo* infos, int32* count) { ADD_NON_NULL_STRING(name); return B_OK; @@ -159,22 +159,14 @@ ReadDirReply::GetAddressInfos(AddressInfo* infos, int32* count) return B_OK; } -// WalkRequest +// LookupRequest status_t -WalkRequest::GetAddressInfos(AddressInfo* infos, int32* count) +LookupRequest::GetAddressInfos(AddressInfo* infos, int32* count) { ADD_NON_NULL_STRING(entryName); return B_OK; } -// WalkReply -status_t -WalkReply::GetAddressInfos(AddressInfo* infos, int32* count) -{ - ADD_STRING(resolvedPath); - return B_OK; -} - // ReadAttrDirReply status_t ReadAttrDirReply::GetAddressInfos(AddressInfo* infos, int32* count) @@ -183,14 +175,6 @@ ReadAttrDirReply::GetAddressInfos(AddressInfo* infos, int32* count) return B_OK; } -// ReadAttrRequest -status_t -ReadAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count) -{ - ADD_NON_NULL_STRING(name); - return B_OK; -} - // ReadAttrReply status_t ReadAttrReply::GetAddressInfos(AddressInfo* infos, int32* count) @@ -203,7 +187,6 @@ ReadAttrReply::GetAddressInfos(AddressInfo* infos, int32* count) status_t WriteAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count) { - ADD_NON_NULL_STRING(name); ADD_ADDRESS(buffer); return B_OK; } @@ -225,14 +208,6 @@ RenameAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count) return B_OK; } -// StatAttrRequest -status_t -StatAttrRequest::GetAddressInfos(AddressInfo* infos, int32* count) -{ - ADD_NON_NULL_STRING(name); - return B_OK; -} - // ReadIndexDirReply status_t ReadIndexDirReply::GetAddressInfos(AddressInfo* infos, int32* count) @@ -257,18 +232,9 @@ RemoveIndexRequest::GetAddressInfos(AddressInfo* infos, int32* count) return B_OK; } -// RenameIndexRequest +// ReadIndexStatRequest status_t -RenameIndexRequest::GetAddressInfos(AddressInfo* infos, int32* count) -{ - ADD_NON_NULL_STRING(oldName); - ADD_NON_NULL_STRING(newName); - return B_OK; -} - -// StatIndexRequest -status_t -StatIndexRequest::GetAddressInfos(AddressInfo* infos, int32* count) +ReadIndexStatRequest::GetAddressInfos(AddressInfo* infos, int32* count) { ADD_NON_NULL_STRING(name); return B_OK; @@ -499,37 +465,57 @@ UserlandFSUtil::is_kernel_request(uint32 type) // FS case MOUNT_VOLUME_REQUEST: case UNMOUNT_VOLUME_REQUEST: - case INITIALIZE_VOLUME_REQUEST: +// case INITIALIZE_VOLUME_REQUEST: case SYNC_VOLUME_REQUEST: - case READ_FS_STAT_REQUEST: - case WRITE_FS_STAT_REQUEST: + case READ_FS_INFO_REQUEST: + case WRITE_FS_INFO_REQUEST: return true; case MOUNT_VOLUME_REPLY: case UNMOUNT_VOLUME_REPLY: - case INITIALIZE_VOLUME_REPLY: +// case INITIALIZE_VOLUME_REPLY: case SYNC_VOLUME_REPLY: - case READ_FS_STAT_REPLY: - case WRITE_FS_STAT_REPLY: + case READ_FS_INFO_REPLY: + case WRITE_FS_INFO_REPLY: return false; // vnodes + case LOOKUP_REQUEST: case READ_VNODE_REQUEST: case WRITE_VNODE_REQUEST: case FS_REMOVE_VNODE_REQUEST: return true; + case LOOKUP_REPLY: case READ_VNODE_REPLY: case WRITE_VNODE_REPLY: case FS_REMOVE_VNODE_REPLY: return false; // nodes + case IOCTL_REQUEST: + case SET_FLAGS_REQUEST: + case SELECT_REQUEST: + case DESELECT_REQUEST: case FSYNC_REQUEST: + case READ_SYMLINK_REQUEST: + case CREATE_SYMLINK_REQUEST: + case LINK_REQUEST: + case UNLINK_REQUEST: + case RENAME_REQUEST: + case ACCESS_REQUEST: case READ_STAT_REQUEST: case WRITE_STAT_REQUEST: - case ACCESS_REQUEST: return true; + case IOCTL_REPLY: + case SET_FLAGS_REPLY: + case SELECT_REPLY: + case DESELECT_REPLY: case FSYNC_REPLY: + case READ_SYMLINK_REPLY: + case CREATE_SYMLINK_REPLY: + case LINK_REPLY: + case UNLINK_REPLY: + case RENAME_REPLY: + case ACCESS_REPLY: case READ_STAT_REPLY: case WRITE_STAT_REPLY: - case ACCESS_REPLY: return false; // files case CREATE_REQUEST: @@ -538,10 +524,6 @@ UserlandFSUtil::is_kernel_request(uint32 type) case FREE_COOKIE_REQUEST: case READ_REQUEST: case WRITE_REQUEST: - case IOCTL_REQUEST: - case SET_FLAGS_REQUEST: - case SELECT_REQUEST: - case DESELECT_REQUEST: return true; case CREATE_REPLY: case OPEN_REPLY: @@ -549,65 +531,49 @@ UserlandFSUtil::is_kernel_request(uint32 type) case FREE_COOKIE_REPLY: case READ_REPLY: case WRITE_REPLY: - case IOCTL_REPLY: - case SET_FLAGS_REPLY: - case SELECT_REPLY: - case DESELECT_REPLY: - return false; - // hard links / symlinks - case LINK_REQUEST: - case UNLINK_REQUEST: - case SYMLINK_REQUEST: - case READ_LINK_REQUEST: - case RENAME_REQUEST: - return true; - case LINK_REPLY: - case UNLINK_REPLY: - case SYMLINK_REPLY: - case READ_LINK_REPLY: - case RENAME_REPLY: return false; // directories - case MKDIR_REQUEST: - case RMDIR_REQUEST: + case CREATE_DIR_REQUEST: + case REMOVE_DIR_REQUEST: case OPEN_DIR_REQUEST: case CLOSE_DIR_REQUEST: case FREE_DIR_COOKIE_REQUEST: case READ_DIR_REQUEST: case REWIND_DIR_REQUEST: - case WALK_REQUEST: return true; - case MKDIR_REPLY: - case RMDIR_REPLY: + case CREATE_DIR_REPLY: + case REMOVE_DIR_REPLY: case OPEN_DIR_REPLY: case CLOSE_DIR_REPLY: case FREE_DIR_COOKIE_REPLY: case READ_DIR_REPLY: case REWIND_DIR_REPLY: - case WALK_REPLY: return false; - // attributes + // attribute directories case OPEN_ATTR_DIR_REQUEST: case CLOSE_ATTR_DIR_REQUEST: case FREE_ATTR_DIR_COOKIE_REQUEST: case READ_ATTR_DIR_REQUEST: case REWIND_ATTR_DIR_REQUEST: - case READ_ATTR_REQUEST: - case WRITE_ATTR_REQUEST: - case REMOVE_ATTR_REQUEST: - case RENAME_ATTR_REQUEST: - case STAT_ATTR_REQUEST: return true; case OPEN_ATTR_DIR_REPLY: case CLOSE_ATTR_DIR_REPLY: case FREE_ATTR_DIR_COOKIE_REPLY: case READ_ATTR_DIR_REPLY: case REWIND_ATTR_DIR_REPLY: + return false; + // attributes + case READ_ATTR_REQUEST: + case WRITE_ATTR_REQUEST: + case READ_ATTR_STAT_REQUEST: + case RENAME_ATTR_REQUEST: + case REMOVE_ATTR_REQUEST: + return true; case READ_ATTR_REPLY: case WRITE_ATTR_REPLY: - case REMOVE_ATTR_REPLY: + case READ_ATTR_STAT_REPLY: case RENAME_ATTR_REPLY: - case STAT_ATTR_REPLY: + case REMOVE_ATTR_REPLY: return false; // indices case OPEN_INDEX_DIR_REQUEST: @@ -617,8 +583,7 @@ UserlandFSUtil::is_kernel_request(uint32 type) case REWIND_INDEX_DIR_REQUEST: case CREATE_INDEX_REQUEST: case REMOVE_INDEX_REQUEST: - case RENAME_INDEX_REQUEST: - case STAT_INDEX_REQUEST: + case READ_INDEX_STAT_REQUEST: return true; case OPEN_INDEX_DIR_REPLY: case CLOSE_INDEX_DIR_REPLY: @@ -627,8 +592,7 @@ UserlandFSUtil::is_kernel_request(uint32 type) case REWIND_INDEX_DIR_REPLY: case CREATE_INDEX_REPLY: case REMOVE_INDEX_REPLY: - case RENAME_INDEX_REPLY: - case STAT_INDEX_REPLY: + case READ_INDEX_STAT_REPLY: return false; // queries case OPEN_QUERY_REQUEST: @@ -691,37 +655,57 @@ UserlandFSUtil::is_userland_request(uint32 type) // FS case MOUNT_VOLUME_REQUEST: case UNMOUNT_VOLUME_REQUEST: - case INITIALIZE_VOLUME_REQUEST: +// case INITIALIZE_VOLUME_REQUEST: case SYNC_VOLUME_REQUEST: - case READ_FS_STAT_REQUEST: - case WRITE_FS_STAT_REQUEST: + case READ_FS_INFO_REQUEST: + case WRITE_FS_INFO_REQUEST: return false; case MOUNT_VOLUME_REPLY: case UNMOUNT_VOLUME_REPLY: - case INITIALIZE_VOLUME_REPLY: +// case INITIALIZE_VOLUME_REPLY: case SYNC_VOLUME_REPLY: - case READ_FS_STAT_REPLY: - case WRITE_FS_STAT_REPLY: + case READ_FS_INFO_REPLY: + case WRITE_FS_INFO_REPLY: return true; // vnodes + case LOOKUP_REQUEST: case READ_VNODE_REQUEST: case WRITE_VNODE_REQUEST: case FS_REMOVE_VNODE_REQUEST: return false; + case LOOKUP_REPLY: case READ_VNODE_REPLY: case WRITE_VNODE_REPLY: case FS_REMOVE_VNODE_REPLY: return true; // nodes + case IOCTL_REQUEST: + case SET_FLAGS_REQUEST: + case SELECT_REQUEST: + case DESELECT_REQUEST: case FSYNC_REQUEST: + case READ_SYMLINK_REQUEST: + case CREATE_SYMLINK_REQUEST: + case LINK_REQUEST: + case UNLINK_REQUEST: + case RENAME_REQUEST: + case ACCESS_REQUEST: case READ_STAT_REQUEST: case WRITE_STAT_REQUEST: - case ACCESS_REQUEST: return false; + case IOCTL_REPLY: + case SET_FLAGS_REPLY: + case SELECT_REPLY: + case DESELECT_REPLY: case FSYNC_REPLY: + case READ_SYMLINK_REPLY: + case CREATE_SYMLINK_REPLY: + case LINK_REPLY: + case UNLINK_REPLY: + case RENAME_REPLY: + case ACCESS_REPLY: case READ_STAT_REPLY: case WRITE_STAT_REPLY: - case ACCESS_REPLY: return true; // files case CREATE_REQUEST: @@ -730,10 +714,6 @@ UserlandFSUtil::is_userland_request(uint32 type) case FREE_COOKIE_REQUEST: case READ_REQUEST: case WRITE_REQUEST: - case IOCTL_REQUEST: - case SET_FLAGS_REQUEST: - case SELECT_REQUEST: - case DESELECT_REQUEST: return false; case CREATE_REPLY: case OPEN_REPLY: @@ -741,65 +721,49 @@ UserlandFSUtil::is_userland_request(uint32 type) case FREE_COOKIE_REPLY: case READ_REPLY: case WRITE_REPLY: - case IOCTL_REPLY: - case SET_FLAGS_REPLY: - case SELECT_REPLY: - case DESELECT_REPLY: - return true; - // hard links / symlinks - case LINK_REQUEST: - case UNLINK_REQUEST: - case SYMLINK_REQUEST: - case READ_LINK_REQUEST: - case RENAME_REQUEST: - return false; - case LINK_REPLY: - case UNLINK_REPLY: - case SYMLINK_REPLY: - case READ_LINK_REPLY: - case RENAME_REPLY: return true; // directories - case MKDIR_REQUEST: - case RMDIR_REQUEST: + case CREATE_DIR_REQUEST: + case REMOVE_DIR_REQUEST: case OPEN_DIR_REQUEST: case CLOSE_DIR_REQUEST: case FREE_DIR_COOKIE_REQUEST: case READ_DIR_REQUEST: case REWIND_DIR_REQUEST: - case WALK_REQUEST: return false; - case MKDIR_REPLY: - case RMDIR_REPLY: + case CREATE_DIR_REPLY: + case REMOVE_DIR_REPLY: case OPEN_DIR_REPLY: case CLOSE_DIR_REPLY: case FREE_DIR_COOKIE_REPLY: case READ_DIR_REPLY: case REWIND_DIR_REPLY: - case WALK_REPLY: return true; - // attributes + // attribute directories case OPEN_ATTR_DIR_REQUEST: case CLOSE_ATTR_DIR_REQUEST: case FREE_ATTR_DIR_COOKIE_REQUEST: case READ_ATTR_DIR_REQUEST: case REWIND_ATTR_DIR_REQUEST: - case READ_ATTR_REQUEST: - case WRITE_ATTR_REQUEST: - case REMOVE_ATTR_REQUEST: - case RENAME_ATTR_REQUEST: - case STAT_ATTR_REQUEST: return false; case OPEN_ATTR_DIR_REPLY: case CLOSE_ATTR_DIR_REPLY: case FREE_ATTR_DIR_COOKIE_REPLY: case READ_ATTR_DIR_REPLY: case REWIND_ATTR_DIR_REPLY: + return true; + // attributes + case READ_ATTR_REQUEST: + case WRITE_ATTR_REQUEST: + case RENAME_ATTR_REQUEST: + case READ_ATTR_STAT_REQUEST: + case REMOVE_ATTR_REQUEST: + return false; case READ_ATTR_REPLY: case WRITE_ATTR_REPLY: - case REMOVE_ATTR_REPLY: + case READ_ATTR_STAT_REPLY: case RENAME_ATTR_REPLY: - case STAT_ATTR_REPLY: + case REMOVE_ATTR_REPLY: return true; // indices case OPEN_INDEX_DIR_REQUEST: @@ -809,8 +773,7 @@ UserlandFSUtil::is_userland_request(uint32 type) case REWIND_INDEX_DIR_REQUEST: case CREATE_INDEX_REQUEST: case REMOVE_INDEX_REQUEST: - case RENAME_INDEX_REQUEST: - case STAT_INDEX_REQUEST: + case READ_INDEX_STAT_REQUEST: return false; case OPEN_INDEX_DIR_REPLY: case CLOSE_INDEX_DIR_REPLY: @@ -819,8 +782,7 @@ UserlandFSUtil::is_userland_request(uint32 type) case REWIND_INDEX_DIR_REPLY: case CREATE_INDEX_REPLY: case REMOVE_INDEX_REPLY: - case RENAME_INDEX_REPLY: - case STAT_INDEX_REPLY: + case READ_INDEX_STAT_REPLY: return true; // queries case OPEN_QUERY_REQUEST: