* Reorganized the FS interface a little:
- Moved most file_system_module_info hooks into separate structures. Those that operate on mounted volumes to fs_volume_ops, those operating on a vnode to fs_vnode_ops. - Got rid of the fs_volume, fs_cookie, fs_vnode typedefs. We use void* again. - Instead of a void* volume and node cookie hooks are passed a fs_volume and fs_vnode structure pointer, which contain the cookie and an ops pointer (fs_volume a few more things). - The VFS {new,publish,get,...}_vnode() functions take a fs_volume* instead of the volume ID. So does vfs_get_fs_node_from_path(). - Added type and flags arguments to publish_vnode() and the get_vnode() hook and removed the type argument from lookup() hook. Added vnode::type using formerly unused bits to store the node type. Simplified a few things in the VFS due to the now always available node type. - Added fs_volume_ops::{create,delete}_sub_vnode() and fs_vnode_ops::get_super_vnode() hooks. They are used to support file system layers, e.g. allowing to extend an FS not supporting BeOS attribute with attribute support. Needs some more work in the VFS. - Added fs_vnode_ops::create_special_node() hook for creating special nodes (e.g. FIFOs). * Adjusted the built-in file systems and BFS according to the interface changes. Removed all other FSs from the image for the time being. We'll see whether further API changes are necessary before porting them. * Adjusted the bfs_shell accordingly. * Implemented create_special_node() in rootfs to support special nodes. * Added support for FIFOs: - Added syscall _kern_create_fifo() (used by mkfifo()), which creates a special node (type S_IFIFO) in the respective file system. - When a special node is published the VFS creates a respective sub node. Currently only FIFOs are supported. - Added a little support for FIFO subnodes by using functionality from the pipefs. - Added mkfifo to the image. It can create FIFOs in the rootfs, but the FIFOs aren't really usable ATM, since they still work like pipes, i.e. readers and writers need to have them open at the same time. * Some smaller changes in the VFS: - Made the *_CALL macros nicer to use (vargs). - Refactored FS entry lookup into new function lookup_dir_entry(). - create_vnode() no longer just calls the FS create() hook. First it looks up the entry and uses open_vnode(), if it already exists. This is necessary for two reasons: 1) The FS might not support create() while still allowing to open() entries. 2) When the FS has other layers on to of it (or the respective node) it might not be responsible for opening the node. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24816 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5d7ee5e84a
commit
7ffafac8d7
@ -35,7 +35,7 @@ BEOS_BIN = "[" addattr alert arp base64 basename bc beep bootman bzip2 cal cat
|
||||
ideinfo idestatus ifconfig <bin>install installsound iroster isvolume join
|
||||
keymap kill less lessecho lesskey link listarea listattr listdev listimage
|
||||
listport listres listsem ln locate logger login logname ls lsindex m4 make
|
||||
makebootable md5sum merge mimeset mkdos mkdir mkindex modifiers mount
|
||||
makebootable md5sum merge mimeset mkdos mkdir mkfifo mkindex modifiers mount
|
||||
mount_nfs mountvolume mv nc netstat nl nohup od open paste patch pathchk pc
|
||||
ping play playfile playsound playwav pr prio printenv printf ps ptx pwd
|
||||
query quit readlink release renice rescan rlog rm rmattr rmindex rmdir roster route
|
||||
@ -134,7 +134,8 @@ BEOS_ADD_ONS_DRIVERS_NET = $(X86_ONLY)3com etherpci $(X86_ONLY)ipro1000
|
||||
BEOS_ADD_ONS_BUS_MANAGERS = pci $(X86_ONLY)ps2 $(X86_ONLY)isa ide scsi
|
||||
config_manager agp_gart usb firewire
|
||||
;
|
||||
BEOS_ADD_ONS_FILE_SYSTEMS = bfs cdda fat googlefs iso9660 nfs $(GPL_ONLY)ntfs ;
|
||||
BEOS_ADD_ONS_FILE_SYSTEMS = bfs ;
|
||||
#cdda fat googlefs iso9660 nfs $(GPL_ONLY)ntfs ;
|
||||
|
||||
|
||||
# modules
|
||||
|
@ -21,11 +21,6 @@ struct stat;
|
||||
struct fs_info;
|
||||
struct select_sync;
|
||||
|
||||
/* the file system's private data structures */
|
||||
typedef void *fs_volume;
|
||||
typedef void *fs_cookie;
|
||||
typedef void *fs_vnode;
|
||||
|
||||
/* additional flags passed to write_stat() (see NodeMonitor.h for the others) */
|
||||
// NOTE: Changing the constants here or in NodeMonitor.h will break
|
||||
// src/kits/storage/LibBeAdapter.cpp:_kern_write_stat().
|
||||
@ -42,10 +37,199 @@ struct file_io_vec {
|
||||
|
||||
#define B_CURRENT_FS_API_VERSION "/v1"
|
||||
|
||||
// flags for publish_vnode() and fs_volume_ops::get_vnode()
|
||||
#define B_VNODE_PUBLISH_REMOVED 0x01
|
||||
#define B_VNODE_DONT_CREATE_SPECIAL_SUB_NODE 0x02
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct fs_volume fs_volume;
|
||||
typedef struct fs_volume_ops fs_volume_ops;
|
||||
typedef struct fs_vnode fs_vnode;
|
||||
typedef struct fs_vnode_ops fs_vnode_ops;
|
||||
|
||||
|
||||
struct fs_volume {
|
||||
dev_t id;
|
||||
int32 layer;
|
||||
void* private_volume;
|
||||
fs_volume_ops* ops;
|
||||
fs_volume* sub_volume;
|
||||
fs_volume* super_volume;
|
||||
};
|
||||
|
||||
struct fs_vnode {
|
||||
void* private_node;
|
||||
fs_vnode_ops* ops;
|
||||
};
|
||||
|
||||
struct fs_volume_ops {
|
||||
status_t (*unmount)(fs_volume *volume);
|
||||
|
||||
status_t (*read_fs_info)(fs_volume *volume, struct fs_info *info);
|
||||
status_t (*write_fs_info)(fs_volume *volume, const struct fs_info *info,
|
||||
uint32 mask);
|
||||
status_t (*sync)(fs_volume *volume);
|
||||
|
||||
status_t (*get_vnode)(fs_volume *volume, ino_t id, fs_vnode *vnode,
|
||||
int *_type, uint32 *_flags, bool reenter);
|
||||
|
||||
/* index directory & index operations */
|
||||
status_t (*open_index_dir)(fs_volume *volume, void **cookie);
|
||||
status_t (*close_index_dir)(fs_volume *volume, void *cookie);
|
||||
status_t (*free_index_dir_cookie)(fs_volume *volume, void *cookie);
|
||||
status_t (*read_index_dir)(fs_volume *volume, void *cookie,
|
||||
struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
status_t (*rewind_index_dir)(fs_volume *volume, void *cookie);
|
||||
|
||||
status_t (*create_index)(fs_volume *volume, const char *name, uint32 type,
|
||||
uint32 flags);
|
||||
status_t (*remove_index)(fs_volume *volume, const char *name);
|
||||
status_t (*read_index_stat)(fs_volume *volume, const char *name,
|
||||
struct stat *stat);
|
||||
|
||||
/* query operations */
|
||||
status_t (*open_query)(fs_volume *volume, const char *query, uint32 flags,
|
||||
port_id port, uint32 token, void **_cookie);
|
||||
status_t (*close_query)(fs_volume *volume, void *cookie);
|
||||
status_t (*free_query_cookie)(fs_volume *volume, void *cookie);
|
||||
status_t (*read_query)(fs_volume *volume, void *cookie,
|
||||
struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
status_t (*rewind_query)(fs_volume *volume, void *cookie);
|
||||
|
||||
/* support for FS layers */
|
||||
status_t (*create_sub_vnode)(fs_volume *volume, ino_t id, fs_vnode *vnode);
|
||||
status_t (*delete_sub_vnode)(fs_volume *volume, fs_vnode *vnode);
|
||||
};
|
||||
|
||||
struct fs_vnode_ops {
|
||||
/* vnode operations */
|
||||
status_t (*lookup)(fs_volume *volume, fs_vnode *dir, const char *name,
|
||||
ino_t *_id);
|
||||
status_t (*get_vnode_name)(fs_volume *volume, fs_vnode *vnode, char *buffer,
|
||||
size_t bufferSize);
|
||||
|
||||
status_t (*put_vnode)(fs_volume *volume, fs_vnode *vnode, bool reenter);
|
||||
status_t (*remove_vnode)(fs_volume *volume, fs_vnode *vnode, bool reenter);
|
||||
|
||||
/* VM file access */
|
||||
bool (*can_page)(fs_volume *volume, fs_vnode *vnode, void *cookie);
|
||||
status_t (*read_pages)(fs_volume *volume, fs_vnode *vnode, void *cookie,
|
||||
off_t pos, const iovec *vecs, size_t count, size_t *_numBytes,
|
||||
bool reenter);
|
||||
status_t (*write_pages)(fs_volume *volume, fs_vnode *vnode,
|
||||
void *cookie, off_t pos, const iovec *vecs, size_t count,
|
||||
size_t *_numBytes, bool reenter);
|
||||
|
||||
/* cache file access */
|
||||
status_t (*get_file_map)(fs_volume *volume, fs_vnode *vnode, off_t offset,
|
||||
size_t size, struct file_io_vec *vecs, size_t *_count);
|
||||
|
||||
/* common operations */
|
||||
status_t (*ioctl)(fs_volume *volume, fs_vnode *vnode, void *cookie,
|
||||
ulong op, void *buffer, size_t length);
|
||||
status_t (*set_flags)(fs_volume *volume, fs_vnode *vnode, void *cookie,
|
||||
int flags);
|
||||
status_t (*select)(fs_volume *volume, fs_vnode *vnode, void *cookie,
|
||||
uint8 event, uint32 ref, selectsync *sync);
|
||||
status_t (*deselect)(fs_volume *volume, fs_vnode *vnode, void *cookie,
|
||||
uint8 event, selectsync *sync);
|
||||
status_t (*fsync)(fs_volume *volume, fs_vnode *vnode);
|
||||
|
||||
status_t (*read_symlink)(fs_volume *volume, fs_vnode *link, char *buffer,
|
||||
size_t *_bufferSize);
|
||||
status_t (*create_symlink)(fs_volume *volume, fs_vnode *dir,
|
||||
const char *name, const char *path, int mode);
|
||||
|
||||
status_t (*link)(fs_volume *volume, fs_vnode *dir, const char *name,
|
||||
fs_vnode *vnode);
|
||||
status_t (*unlink)(fs_volume *volume, fs_vnode *dir, const char *name);
|
||||
status_t (*rename)(fs_volume *volume, fs_vnode *fromDir,
|
||||
const char *fromName, fs_vnode *toDir, const char *toName);
|
||||
|
||||
status_t (*access)(fs_volume *volume, fs_vnode *vnode, int mode);
|
||||
status_t (*read_stat)(fs_volume *volume, fs_vnode *vnode,
|
||||
struct stat *stat);
|
||||
status_t (*write_stat)(fs_volume *volume, fs_vnode *vnode,
|
||||
const struct stat *stat, uint32 statMask);
|
||||
|
||||
/* file operations */
|
||||
status_t (*create)(fs_volume *volume, fs_vnode *dir, const char *name,
|
||||
int openMode, int perms, void **_cookie,
|
||||
ino_t *_newVnodeID);
|
||||
status_t (*open)(fs_volume *volume, fs_vnode *vnode, int openMode,
|
||||
void **_cookie);
|
||||
status_t (*close)(fs_volume *volume, fs_vnode *vnode, void *cookie);
|
||||
status_t (*free_cookie)(fs_volume *volume, fs_vnode *vnode,
|
||||
void *cookie);
|
||||
status_t (*read)(fs_volume *volume, fs_vnode *vnode, void *cookie,
|
||||
off_t pos, void *buffer, size_t *length);
|
||||
status_t (*write)(fs_volume *volume, fs_vnode *vnode, void *cookie,
|
||||
off_t pos, const void *buffer, size_t *length);
|
||||
|
||||
/* directory operations */
|
||||
status_t (*create_dir)(fs_volume *volume, fs_vnode *parent,
|
||||
const char *name, int perms, ino_t *_newVnodeID);
|
||||
status_t (*remove_dir)(fs_volume *volume, fs_vnode *parent,
|
||||
const char *name);
|
||||
status_t (*open_dir)(fs_volume *volume, fs_vnode *vnode,
|
||||
void **_cookie);
|
||||
status_t (*close_dir)(fs_volume *volume, fs_vnode *vnode, void *cookie);
|
||||
status_t (*free_dir_cookie)(fs_volume *volume, fs_vnode *vnode,
|
||||
void *cookie);
|
||||
status_t (*read_dir)(fs_volume *volume, fs_vnode *vnode, void *cookie,
|
||||
struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
status_t (*rewind_dir)(fs_volume *volume, fs_vnode *vnode,
|
||||
void *cookie);
|
||||
|
||||
/* attribute directory operations */
|
||||
status_t (*open_attr_dir)(fs_volume *volume, fs_vnode *vnode,
|
||||
void **_cookie);
|
||||
status_t (*close_attr_dir)(fs_volume *volume, fs_vnode *vnode,
|
||||
void *cookie);
|
||||
status_t (*free_attr_dir_cookie)(fs_volume *volume, fs_vnode *vnode,
|
||||
void *cookie);
|
||||
status_t (*read_attr_dir)(fs_volume *volume, fs_vnode *vnode,
|
||||
void *cookie, struct dirent *buffer, size_t bufferSize,
|
||||
uint32 *_num);
|
||||
status_t (*rewind_attr_dir)(fs_volume *volume, fs_vnode *vnode,
|
||||
void *cookie);
|
||||
|
||||
/* attribute operations */
|
||||
status_t (*create_attr)(fs_volume *volume, fs_vnode *vnode,
|
||||
const char *name, uint32 type, int openMode,
|
||||
void **_cookie);
|
||||
status_t (*open_attr)(fs_volume *volume, fs_vnode *vnode, const char *name,
|
||||
int openMode, void **_cookie);
|
||||
status_t (*close_attr)(fs_volume *volume, fs_vnode *vnode,
|
||||
void *cookie);
|
||||
status_t (*free_attr_cookie)(fs_volume *volume, fs_vnode *vnode,
|
||||
void *cookie);
|
||||
status_t (*read_attr)(fs_volume *volume, fs_vnode *vnode, void *cookie,
|
||||
off_t pos, void *buffer, size_t *length);
|
||||
status_t (*write_attr)(fs_volume *volume, fs_vnode *vnode, void *cookie,
|
||||
off_t pos, const void *buffer, size_t *length);
|
||||
|
||||
status_t (*read_attr_stat)(fs_volume *volume, fs_vnode *vnode,
|
||||
void *cookie, struct stat *stat);
|
||||
status_t (*write_attr_stat)(fs_volume *volume, fs_vnode *vnode,
|
||||
void *cookie, const struct stat *stat, int statMask);
|
||||
status_t (*rename_attr)(fs_volume *volume, fs_vnode *fromVnode,
|
||||
const char *fromName, fs_vnode *toVnode, const char *toName);
|
||||
status_t (*remove_attr)(fs_volume *volume, fs_vnode *vnode,
|
||||
const char *name);
|
||||
|
||||
/* support for node and FS layers */
|
||||
status_t (*create_special_node)(fs_volume *volume, fs_vnode *dir,
|
||||
const char *name, fs_vnode *subVnode, mode_t mode, uint32 flags,
|
||||
fs_vnode *_superVnode, ino_t *_nodeID);
|
||||
status_t (*get_super_vnode)(fs_volume *volume, fs_vnode *vnode,
|
||||
fs_volume *superVolume, fs_vnode *superVnode);
|
||||
};
|
||||
|
||||
typedef struct file_system_module_info {
|
||||
struct module_info info;
|
||||
const char* pretty_name;
|
||||
@ -61,142 +245,8 @@ typedef struct file_system_module_info {
|
||||
void (*free_partition_content_cookie)(partition_data *partition);
|
||||
|
||||
/* general operations */
|
||||
status_t (*mount)(dev_t id, const char *device, uint32 flags,
|
||||
const char *args, fs_volume *_fs, ino_t *_rootVnodeID);
|
||||
status_t (*unmount)(fs_volume fs);
|
||||
|
||||
status_t (*read_fs_info)(fs_volume fs, struct fs_info *info);
|
||||
status_t (*write_fs_info)(fs_volume fs, const struct fs_info *info,
|
||||
uint32 mask);
|
||||
status_t (*sync)(fs_volume fs);
|
||||
|
||||
/* vnode operations */
|
||||
status_t (*lookup)(fs_volume fs, fs_vnode dir, const char *name,
|
||||
ino_t *_id, int *_type);
|
||||
status_t (*get_vnode_name)(fs_volume fs, fs_vnode vnode, char *buffer,
|
||||
size_t bufferSize);
|
||||
|
||||
status_t (*get_vnode)(fs_volume fs, ino_t id, fs_vnode *_vnode,
|
||||
bool reenter);
|
||||
status_t (*put_vnode)(fs_volume fs, fs_vnode vnode, bool reenter);
|
||||
status_t (*remove_vnode)(fs_volume fs, fs_vnode vnode, bool reenter);
|
||||
|
||||
/* VM file access */
|
||||
bool (*can_page)(fs_volume fs, fs_vnode vnode, fs_cookie cookie);
|
||||
status_t (*read_pages)(fs_volume fs, fs_vnode vnode, fs_cookie cookie,
|
||||
off_t pos, const iovec *vecs, size_t count, size_t *_numBytes,
|
||||
bool reenter);
|
||||
status_t (*write_pages)(fs_volume fs, fs_vnode vnode, fs_cookie cookie,
|
||||
off_t pos, const iovec *vecs, size_t count, size_t *_numBytes,
|
||||
bool reenter);
|
||||
|
||||
/* cache file access */
|
||||
status_t (*get_file_map)(fs_volume fs, fs_vnode vnode, off_t offset,
|
||||
size_t size, struct file_io_vec *vecs, size_t *_count);
|
||||
|
||||
/* common operations */
|
||||
status_t (*ioctl)(fs_volume fs, fs_vnode vnode, fs_cookie cookie, ulong op,
|
||||
void *buffer, size_t length);
|
||||
status_t (*set_flags)(fs_volume fs, fs_vnode vnode, fs_cookie cookie,
|
||||
int flags);
|
||||
status_t (*select)(fs_volume fs, fs_vnode vnode, fs_cookie cookie,
|
||||
uint8 event, uint32 ref, selectsync *sync);
|
||||
status_t (*deselect)(fs_volume fs, fs_vnode vnode, fs_cookie cookie,
|
||||
uint8 event, selectsync *sync);
|
||||
status_t (*fsync)(fs_volume fs, fs_vnode vnode);
|
||||
|
||||
status_t (*read_symlink)(fs_volume fs, fs_vnode link, char *buffer,
|
||||
size_t *_bufferSize);
|
||||
status_t (*create_symlink)(fs_volume fs, fs_vnode dir, const char *name,
|
||||
const char *path, int mode);
|
||||
|
||||
status_t (*link)(fs_volume fs, fs_vnode dir, const char *name,
|
||||
fs_vnode vnode);
|
||||
status_t (*unlink)(fs_volume fs, fs_vnode dir, const char *name);
|
||||
status_t (*rename)(fs_volume fs, fs_vnode fromDir, const char *fromName,
|
||||
fs_vnode toDir, const char *toName);
|
||||
|
||||
status_t (*access)(fs_volume fs, fs_vnode vnode, int mode);
|
||||
status_t (*read_stat)(fs_volume fs, fs_vnode vnode, struct stat *stat);
|
||||
status_t (*write_stat)(fs_volume fs, fs_vnode vnode,
|
||||
const struct stat *stat, uint32 statMask);
|
||||
|
||||
/* file operations */
|
||||
status_t (*create)(fs_volume fs, fs_vnode dir, const char *name,
|
||||
int openMode, int perms, fs_cookie *_cookie,
|
||||
ino_t *_newVnodeID);
|
||||
status_t (*open)(fs_volume fs, fs_vnode vnode, int openMode,
|
||||
fs_cookie *_cookie);
|
||||
status_t (*close)(fs_volume fs, fs_vnode vnode, fs_cookie cookie);
|
||||
status_t (*free_cookie)(fs_volume fs, fs_vnode vnode, fs_cookie cookie);
|
||||
status_t (*read)(fs_volume fs, fs_vnode vnode, fs_cookie cookie, off_t pos,
|
||||
void *buffer, size_t *length);
|
||||
status_t (*write)(fs_volume fs, fs_vnode vnode, fs_cookie cookie, off_t pos,
|
||||
const void *buffer, size_t *length);
|
||||
|
||||
/* directory operations */
|
||||
status_t (*create_dir)(fs_volume fs, fs_vnode parent, const char *name,
|
||||
int perms, ino_t *_newVnodeID);
|
||||
status_t (*remove_dir)(fs_volume fs, fs_vnode parent, const char *name);
|
||||
status_t (*open_dir)(fs_volume fs, fs_vnode vnode, fs_cookie *_cookie);
|
||||
status_t (*close_dir)(fs_volume fs, fs_vnode vnode, fs_cookie cookie);
|
||||
status_t (*free_dir_cookie)(fs_volume fs, fs_vnode vnode, fs_cookie cookie);
|
||||
status_t (*read_dir)(fs_volume fs, fs_vnode vnode, fs_cookie cookie,
|
||||
struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
status_t (*rewind_dir)(fs_volume fs, fs_vnode vnode, fs_cookie cookie);
|
||||
|
||||
/* attribute directory operations */
|
||||
status_t (*open_attr_dir)(fs_volume fs, fs_vnode vnode, fs_cookie *_cookie);
|
||||
status_t (*close_attr_dir)(fs_volume fs, fs_vnode vnode, fs_cookie cookie);
|
||||
status_t (*free_attr_dir_cookie)(fs_volume fs, fs_vnode vnode,
|
||||
fs_cookie cookie);
|
||||
status_t (*read_attr_dir)(fs_volume fs, fs_vnode vnode, fs_cookie cookie,
|
||||
struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
status_t (*rewind_attr_dir)(fs_volume fs, fs_vnode vnode, fs_cookie cookie);
|
||||
|
||||
/* attribute operations */
|
||||
status_t (*create_attr)(fs_volume fs, fs_vnode vnode, const char *name,
|
||||
uint32 type, int openMode, fs_cookie *_cookie);
|
||||
status_t (*open_attr)(fs_volume fs, fs_vnode vnode, const char *name,
|
||||
int openMode, fs_cookie *_cookie);
|
||||
status_t (*close_attr)(fs_volume fs, fs_vnode vnode, fs_cookie cookie);
|
||||
status_t (*free_attr_cookie)(fs_volume fs, fs_vnode vnode,
|
||||
fs_cookie cookie);
|
||||
status_t (*read_attr)(fs_volume fs, fs_vnode vnode, fs_cookie cookie,
|
||||
off_t pos, void *buffer, size_t *length);
|
||||
status_t (*write_attr)(fs_volume fs, fs_vnode vnode, fs_cookie cookie,
|
||||
off_t pos, const void *buffer, size_t *length);
|
||||
|
||||
status_t (*read_attr_stat)(fs_volume fs, fs_vnode vnode, fs_cookie cookie,
|
||||
struct stat *stat);
|
||||
status_t (*write_attr_stat)(fs_volume fs, fs_vnode vnode, fs_cookie cookie,
|
||||
const struct stat *stat, int statMask);
|
||||
status_t (*rename_attr)(fs_volume fs, fs_vnode fromVnode,
|
||||
const char *fromName, fs_vnode toVnode, const char *toName);
|
||||
status_t (*remove_attr)(fs_volume fs, fs_vnode vnode, const char *name);
|
||||
|
||||
/* index directory & index operations */
|
||||
status_t (*open_index_dir)(fs_volume fs, fs_cookie *cookie);
|
||||
status_t (*close_index_dir)(fs_volume fs, fs_cookie cookie);
|
||||
status_t (*free_index_dir_cookie)(fs_volume fs, fs_cookie cookie);
|
||||
status_t (*read_index_dir)(fs_volume fs, fs_cookie cookie,
|
||||
struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
status_t (*rewind_index_dir)(fs_volume fs, fs_cookie cookie);
|
||||
|
||||
status_t (*create_index)(fs_volume fs, const char *name, uint32 type,
|
||||
uint32 flags);
|
||||
status_t (*remove_index)(fs_volume fs, const char *name);
|
||||
status_t (*read_index_stat)(fs_volume fs, const char *name,
|
||||
struct stat *stat);
|
||||
|
||||
/* query operations */
|
||||
status_t (*open_query)(fs_volume fs, const char *query, uint32 flags,
|
||||
port_id port, uint32 token, fs_cookie *_cookie);
|
||||
status_t (*close_query)(fs_volume fs, fs_cookie cookie);
|
||||
status_t (*free_query_cookie)(fs_volume fs, fs_cookie cookie);
|
||||
status_t (*read_query)(fs_volume fs, fs_cookie cookie,
|
||||
struct dirent *buffer, size_t bufferSize, uint32 *_num);
|
||||
status_t (*rewind_query)(fs_volume fs, fs_cookie cookie);
|
||||
status_t (*mount)(fs_volume *volume, const char *device, uint32 flags,
|
||||
const char *args, ino_t *_rootVnodeID);
|
||||
|
||||
/* capability querying (the device is read locked) */
|
||||
uint32 (*get_supported_operations)(partition_data* partition, uint32 mask);
|
||||
@ -233,17 +283,19 @@ typedef struct file_system_module_info {
|
||||
|
||||
|
||||
/* file system add-ons only prototypes */
|
||||
extern status_t new_vnode(dev_t mountID, ino_t vnodeID,
|
||||
fs_vnode privateNode);
|
||||
extern status_t publish_vnode(dev_t mountID, ino_t vnodeID,
|
||||
fs_vnode privateNode);
|
||||
extern status_t get_vnode(dev_t mountID, ino_t vnodeID,
|
||||
fs_vnode *_privateNode);
|
||||
extern status_t put_vnode(dev_t mountID, ino_t vnodeID);
|
||||
extern status_t remove_vnode(dev_t mountID, ino_t vnodeID);
|
||||
extern status_t unremove_vnode(dev_t mountID, ino_t vnodeID);
|
||||
extern status_t get_vnode_removed(dev_t mountID, ino_t vnodeID,
|
||||
bool* removed);
|
||||
extern status_t new_vnode(fs_volume *volume, ino_t vnodeID, void *privateNode,
|
||||
fs_vnode_ops *ops);
|
||||
extern status_t publish_vnode(fs_volume *volume, ino_t vnodeID,
|
||||
void *privateNode, fs_vnode_ops *ops, int type,
|
||||
uint32 flags);
|
||||
extern status_t get_vnode(fs_volume *volume, ino_t vnodeID,
|
||||
void **_privateNode);
|
||||
extern status_t put_vnode(fs_volume *volume, ino_t vnodeID);
|
||||
extern status_t remove_vnode(fs_volume *volume, ino_t vnodeID);
|
||||
extern status_t unremove_vnode(fs_volume *volume, ino_t vnodeID);
|
||||
extern status_t get_vnode_removed(fs_volume *volume, ino_t vnodeID,
|
||||
bool *removed);
|
||||
|
||||
extern status_t read_pages(int fd, off_t pos, const struct iovec *vecs,
|
||||
size_t count, size_t *_numBytes, bool fsReenter);
|
||||
extern status_t write_pages(int fd, off_t pos, const struct iovec *vecs,
|
||||
@ -257,10 +309,6 @@ extern status_t write_file_io_vec_pages(int fd,
|
||||
const struct iovec *vecs, size_t vecCount,
|
||||
uint32 *_vecIndex, size_t *_vecOffset, size_t *_bytes);
|
||||
|
||||
// Deprecated! Will disappear soon!
|
||||
extern status_t notify_listener(int op, dev_t device, ino_t parentNode,
|
||||
ino_t toParentNode, ino_t node, const char *name);
|
||||
|
||||
extern status_t notify_entry_created(dev_t device, ino_t directory,
|
||||
const char *name, ino_t node);
|
||||
extern status_t notify_entry_removed(dev_t device, ino_t directory,
|
||||
|
@ -870,11 +870,6 @@
|
||||
#define mount_id fssh_mount_id
|
||||
#define vnode_id fssh_vnode_id
|
||||
|
||||
/* the file system's private data structures */
|
||||
#define fs_volume fssh_fs_volume
|
||||
#define fs_cookie fssh_fs_cookie
|
||||
#define fs_vnode fssh_fs_vnode
|
||||
|
||||
/* additional flags passed to write_stat() */
|
||||
#define B_STAT_SIZE_INSECURE FSSH_B_STAT_SIZE_INSECURE
|
||||
|
||||
@ -885,6 +880,14 @@
|
||||
|
||||
#define B_CURRENT_FS_API_VERSION FSSH_B_CURRENT_FS_API_VERSION
|
||||
|
||||
// flags for publish_vnode() and fs_volume_ops::get_vnode()
|
||||
#define B_VNODE_PUBLISH_REMOVED FSSH_B_VNODE_PUBLISH_REMOVED
|
||||
#define B_VNODE_DONT_CREATE_SPECIAL_SUB_NODE FSSH_B_VNODE_DONT_CREATE_SPECIAL_SUB_NODE
|
||||
|
||||
#define fs_volume fssh_fs_volume
|
||||
#define fs_volume_ops fssh_fs_volume_ops
|
||||
#define fs_vnode fssh_fs_vnode
|
||||
#define fs_vnode_ops fssh_fs_vnode_ops
|
||||
#define file_system_module_info fssh_file_system_module_info
|
||||
|
||||
|
||||
|
@ -24,9 +24,7 @@ typedef fssh_dev_t fssh_mount_id;
|
||||
typedef fssh_ino_t fssh_vnode_id;
|
||||
|
||||
/* the file system's private data structures */
|
||||
typedef void *fssh_fs_volume;
|
||||
typedef void *fssh_fs_cookie;
|
||||
typedef void *fssh_fs_vnode;
|
||||
|
||||
/* additional flags passed to write_stat() */
|
||||
#define FSSH_B_STAT_SIZE_INSECURE 0x2000
|
||||
@ -41,10 +39,232 @@ struct fssh_file_io_vec {
|
||||
|
||||
#define FSSH_B_CURRENT_FS_API_VERSION "/v1"
|
||||
|
||||
// flags for publish_vnode() and fs_volume_ops::get_vnode()
|
||||
#define FSSH_B_VNODE_PUBLISH_REMOVED 0x01
|
||||
#define FSSH_B_VNODE_DONT_CREATE_SPECIAL_SUB_NODE 0x02
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct fssh_fs_volume fssh_fs_volume;
|
||||
typedef struct fssh_fs_volume_ops fssh_fs_volume_ops;
|
||||
typedef struct fssh_fs_vnode fssh_fs_vnode;
|
||||
typedef struct fssh_fs_vnode_ops fssh_fs_vnode_ops;
|
||||
|
||||
|
||||
struct fssh_fs_volume {
|
||||
fssh_dev_t id;
|
||||
int32_t layer;
|
||||
void* private_volume;
|
||||
fssh_fs_volume_ops* ops;
|
||||
fssh_fs_volume* sub_volume;
|
||||
fssh_fs_volume* super_volume;
|
||||
};
|
||||
|
||||
struct fssh_fs_vnode {
|
||||
void* private_node;
|
||||
fssh_fs_vnode_ops* ops;
|
||||
};
|
||||
|
||||
struct fssh_fs_volume_ops {
|
||||
fssh_status_t (*unmount)(fssh_fs_volume *volume);
|
||||
|
||||
fssh_status_t (*read_fs_info)(fssh_fs_volume *volume,
|
||||
struct fssh_fs_info *info);
|
||||
fssh_status_t (*write_fs_info)(fssh_fs_volume *volume,
|
||||
const struct fssh_fs_info *info, uint32_t mask);
|
||||
fssh_status_t (*sync)(fssh_fs_volume *volume);
|
||||
|
||||
fssh_status_t (*get_vnode)(fssh_fs_volume *volume, fssh_vnode_id id,
|
||||
fssh_fs_vnode *_vnode, int *_type, uint32_t *_flags,
|
||||
bool reenter);
|
||||
|
||||
/* index directory & index operations */
|
||||
fssh_status_t (*open_index_dir)(fssh_fs_volume *volume,
|
||||
fssh_fs_cookie *cookie);
|
||||
fssh_status_t (*close_index_dir)(fssh_fs_volume *volume,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*free_index_dir_cookie)(fssh_fs_volume *volume,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read_index_dir)(fssh_fs_volume *volume,
|
||||
fssh_fs_cookie cookie, struct fssh_dirent *buffer,
|
||||
fssh_size_t bufferSize, uint32_t *_num);
|
||||
fssh_status_t (*rewind_index_dir)(fssh_fs_volume *volume,
|
||||
fssh_fs_cookie cookie);
|
||||
|
||||
fssh_status_t (*create_index)(fssh_fs_volume *volume, const char *name,
|
||||
uint32_t type, uint32_t flags);
|
||||
fssh_status_t (*remove_index)(fssh_fs_volume *volume, const char *name);
|
||||
fssh_status_t (*read_index_stat)(fssh_fs_volume *volume, const char *name,
|
||||
struct fssh_stat *stat);
|
||||
|
||||
/* query operations */
|
||||
fssh_status_t (*open_query)(fssh_fs_volume *volume, const char *query,
|
||||
uint32_t flags, fssh_port_id port, uint32_t token,
|
||||
fssh_fs_cookie *_cookie);
|
||||
fssh_status_t (*close_query)(fssh_fs_volume *volume, fssh_fs_cookie cookie);
|
||||
fssh_status_t (*free_query_cookie)(fssh_fs_volume *volume,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read_query)(fssh_fs_volume *volume, fssh_fs_cookie cookie,
|
||||
struct fssh_dirent *buffer, fssh_size_t bufferSize,
|
||||
uint32_t *_num);
|
||||
fssh_status_t (*rewind_query)(fssh_fs_volume *volume,
|
||||
fssh_fs_cookie cookie);
|
||||
|
||||
/* support for FS layers */
|
||||
fssh_status_t (*create_sub_vnode)(fssh_fs_volume *volume, fssh_ino_t id,
|
||||
fssh_fs_vnode *vnode);
|
||||
fssh_status_t (*delete_sub_vnode)(fssh_fs_volume *volume,
|
||||
fssh_fs_vnode *vnode);
|
||||
};
|
||||
|
||||
struct fssh_fs_vnode_ops {
|
||||
/* vnode operations */
|
||||
fssh_status_t (*lookup)(fssh_fs_volume *volume, fssh_fs_vnode *dir,
|
||||
const char *name, fssh_vnode_id *_id);
|
||||
fssh_status_t (*get_vnode_name)(fssh_fs_volume *volume,
|
||||
fssh_fs_vnode *vnode, char *buffer, fssh_size_t bufferSize);
|
||||
|
||||
fssh_status_t (*put_vnode)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
bool reenter);
|
||||
fssh_status_t (*remove_vnode)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
bool reenter);
|
||||
|
||||
/* VM file access */
|
||||
bool (*can_page)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read_pages)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie, fssh_off_t pos, const fssh_iovec *vecs,
|
||||
fssh_size_t count, fssh_size_t *_numBytes, bool reenter);
|
||||
fssh_status_t (*write_pages)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie, fssh_off_t pos, const fssh_iovec *vecs,
|
||||
fssh_size_t count, fssh_size_t *_numBytes, bool reenter);
|
||||
|
||||
/* cache file access */
|
||||
fssh_status_t (*get_file_map)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_off_t offset, fssh_size_t size,
|
||||
struct fssh_file_io_vec *vecs, fssh_size_t *_count);
|
||||
|
||||
/* common operations */
|
||||
fssh_status_t (*ioctl)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie, fssh_ulong op, void *buffer,
|
||||
fssh_size_t length);
|
||||
fssh_status_t (*set_flags)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie, int flags);
|
||||
fssh_status_t (*select)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie, uint8_t event, uint32_t ref,
|
||||
fssh_selectsync *sync);
|
||||
fssh_status_t (*deselect)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie, uint8_t event, fssh_selectsync *sync);
|
||||
fssh_status_t (*fsync)(fssh_fs_volume *volume, fssh_fs_vnode *vnode);
|
||||
|
||||
fssh_status_t (*read_symlink)(fssh_fs_volume *volume, fssh_fs_vnode *link,
|
||||
char *buffer, fssh_size_t *_bufferSize);
|
||||
fssh_status_t (*create_symlink)(fssh_fs_volume *volume, fssh_fs_vnode *dir,
|
||||
const char *name, const char *path, int mode);
|
||||
|
||||
fssh_status_t (*link)(fssh_fs_volume *volume, fssh_fs_vnode *dir,
|
||||
const char *name, fssh_fs_vnode *vnode);
|
||||
fssh_status_t (*unlink)(fssh_fs_volume *volume, fssh_fs_vnode *dir,
|
||||
const char *name);
|
||||
fssh_status_t (*rename)(fssh_fs_volume *volume, fssh_fs_vnode *fromDir,
|
||||
const char *fromName, fssh_fs_vnode *toDir, const char *toName);
|
||||
|
||||
fssh_status_t (*access)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
int mode);
|
||||
fssh_status_t (*read_stat)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
struct fssh_stat *stat);
|
||||
fssh_status_t (*write_stat)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
const struct fssh_stat *stat, uint32_t statMask);
|
||||
|
||||
/* file operations */
|
||||
fssh_status_t (*create)(fssh_fs_volume *volume, fssh_fs_vnode *dir,
|
||||
const char *name, int openMode, int perms,
|
||||
fssh_fs_cookie *_cookie, fssh_vnode_id *_newVnodeID);
|
||||
fssh_status_t (*open)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
int openMode, fssh_fs_cookie *_cookie);
|
||||
fssh_status_t (*close)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*free_cookie)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie, fssh_off_t pos, void *buffer,
|
||||
fssh_size_t *length);
|
||||
fssh_status_t (*write)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie, fssh_off_t pos, const void *buffer,
|
||||
fssh_size_t *length);
|
||||
|
||||
/* directory operations */
|
||||
fssh_status_t (*create_dir)(fssh_fs_volume *volume, fssh_fs_vnode *parent,
|
||||
const char *name, int perms, fssh_vnode_id *_newVnodeID);
|
||||
fssh_status_t (*remove_dir)(fssh_fs_volume *volume, fssh_fs_vnode *parent,
|
||||
const char *name);
|
||||
fssh_status_t (*open_dir)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie *_cookie);
|
||||
fssh_status_t (*close_dir)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*free_dir_cookie)(fssh_fs_volume *volume,
|
||||
fssh_fs_vnode *vnode, fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read_dir)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie, struct fssh_dirent *buffer,
|
||||
fssh_size_t bufferSize, uint32_t *_num);
|
||||
fssh_status_t (*rewind_dir)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
|
||||
/* attribute directory operations */
|
||||
fssh_status_t (*open_attr_dir)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie *_cookie);
|
||||
fssh_status_t (*close_attr_dir)(fssh_fs_volume *volume,
|
||||
fssh_fs_vnode *vnode, fssh_fs_cookie cookie);
|
||||
fssh_status_t (*free_attr_dir_cookie)(fssh_fs_volume *volume,
|
||||
fssh_fs_vnode *vnode, fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read_attr_dir)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie, struct fssh_dirent *buffer,
|
||||
fssh_size_t bufferSize, uint32_t *_num);
|
||||
fssh_status_t (*rewind_attr_dir)(fssh_fs_volume *volume,
|
||||
fssh_fs_vnode *vnode, fssh_fs_cookie cookie);
|
||||
|
||||
/* attribute operations */
|
||||
fssh_status_t (*create_attr)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
const char *name, uint32_t type, int openMode,
|
||||
fssh_fs_cookie *_cookie);
|
||||
fssh_status_t (*open_attr)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
const char *name, int openMode, fssh_fs_cookie *_cookie);
|
||||
fssh_status_t (*close_attr)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*free_attr_cookie)(fssh_fs_volume *volume,
|
||||
fssh_fs_vnode *vnode, fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read_attr)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie, fssh_off_t pos, void *buffer,
|
||||
fssh_size_t *length);
|
||||
fssh_status_t (*write_attr)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
fssh_fs_cookie cookie, fssh_off_t pos, const void *buffer,
|
||||
fssh_size_t *length);
|
||||
|
||||
fssh_status_t (*read_attr_stat)(fssh_fs_volume *volume,
|
||||
fssh_fs_vnode *vnode, fssh_fs_cookie cookie,
|
||||
struct fssh_stat *stat);
|
||||
fssh_status_t (*write_attr_stat)(fssh_fs_volume *volume,
|
||||
fssh_fs_vnode *vnode, fssh_fs_cookie cookie,
|
||||
const struct fssh_stat *stat, int statMask);
|
||||
fssh_status_t (*rename_attr)(fssh_fs_volume *volume,
|
||||
fssh_fs_vnode *fromVnode, const char *fromName,
|
||||
fssh_fs_vnode *toVnode, const char *toName);
|
||||
fssh_status_t (*remove_attr)(fssh_fs_volume *volume, fssh_fs_vnode *vnode,
|
||||
const char *name);
|
||||
|
||||
/* support for vnode and FS layers */
|
||||
fssh_status_t (*create_special_node)(fssh_fs_volume *volume,
|
||||
fssh_fs_vnode *dir, const char *name, fssh_fs_vnode *subVnode,
|
||||
fssh_mode_t mode, uint32_t flags, fssh_fs_vnode *_superVnode,
|
||||
fssh_ino_t *_nodeID);
|
||||
fssh_status_t (*get_super_vnode)(fssh_fs_volume *volume,
|
||||
fssh_fs_vnode *vnode, fssh_fs_volume *superVolume,
|
||||
fssh_fs_vnode *superVnode);
|
||||
};
|
||||
|
||||
typedef struct fssh_file_system_module_info {
|
||||
struct fssh_module_info info;
|
||||
const char* pretty_name;
|
||||
@ -60,177 +280,8 @@ typedef struct fssh_file_system_module_info {
|
||||
void (*free_partition_content_cookie)(fssh_partition_data *partition);
|
||||
|
||||
/* general operations */
|
||||
fssh_status_t (*mount)(fssh_mount_id id, const char *device, uint32_t flags,
|
||||
const char *args, fssh_fs_volume *_fs,
|
||||
fssh_vnode_id *_rootVnodeID);
|
||||
fssh_status_t (*unmount)(fssh_fs_volume fs);
|
||||
|
||||
fssh_status_t (*read_fs_info)(fssh_fs_volume fs, struct fssh_fs_info *info);
|
||||
fssh_status_t (*write_fs_info)(fssh_fs_volume fs,
|
||||
const struct fssh_fs_info *info, uint32_t mask);
|
||||
fssh_status_t (*sync)(fssh_fs_volume fs);
|
||||
|
||||
/* vnode operations */
|
||||
fssh_status_t (*lookup)(fssh_fs_volume fs, fssh_fs_vnode dir,
|
||||
const char *name, fssh_vnode_id *_id, int *_type);
|
||||
fssh_status_t (*get_vnode_name)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
char *buffer, fssh_size_t bufferSize);
|
||||
|
||||
fssh_status_t (*get_vnode)(fssh_fs_volume fs, fssh_vnode_id id,
|
||||
fssh_fs_vnode *_vnode, bool reenter);
|
||||
fssh_status_t (*put_vnode)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
bool reenter);
|
||||
fssh_status_t (*remove_vnode)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
bool reenter);
|
||||
|
||||
/* VM file access */
|
||||
bool (*can_page)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read_pages)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, fssh_off_t pos, const fssh_iovec *vecs,
|
||||
fssh_size_t count, fssh_size_t *_numBytes, bool reenter);
|
||||
fssh_status_t (*write_pages)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, fssh_off_t pos, const fssh_iovec *vecs,
|
||||
fssh_size_t count, fssh_size_t *_numBytes, bool reenter);
|
||||
|
||||
/* cache file access */
|
||||
fssh_status_t (*get_file_map)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_off_t offset, fssh_size_t size,
|
||||
struct fssh_file_io_vec *vecs, fssh_size_t *_count);
|
||||
|
||||
/* common operations */
|
||||
fssh_status_t (*ioctl)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, fssh_ulong op, void *buffer,
|
||||
fssh_size_t length);
|
||||
fssh_status_t (*set_flags)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, int flags);
|
||||
fssh_status_t (*select)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, uint8_t event, uint32_t ref,
|
||||
fssh_selectsync *sync);
|
||||
fssh_status_t (*deselect)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, uint8_t event, fssh_selectsync *sync);
|
||||
fssh_status_t (*fsync)(fssh_fs_volume fs, fssh_fs_vnode vnode);
|
||||
|
||||
fssh_status_t (*read_symlink)(fssh_fs_volume fs, fssh_fs_vnode link,
|
||||
char *buffer, fssh_size_t *_bufferSize);
|
||||
fssh_status_t (*create_symlink)(fssh_fs_volume fs, fssh_fs_vnode dir,
|
||||
const char *name, const char *path, int mode);
|
||||
|
||||
fssh_status_t (*link)(fssh_fs_volume fs, fssh_fs_vnode dir,
|
||||
const char *name, fssh_fs_vnode vnode);
|
||||
fssh_status_t (*unlink)(fssh_fs_volume fs, fssh_fs_vnode dir,
|
||||
const char *name);
|
||||
fssh_status_t (*rename)(fssh_fs_volume fs, fssh_fs_vnode fromDir,
|
||||
const char *fromName, fssh_fs_vnode toDir, const char *toName);
|
||||
|
||||
fssh_status_t (*access)(fssh_fs_volume fs, fssh_fs_vnode vnode, int mode);
|
||||
fssh_status_t (*read_stat)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
struct fssh_stat *stat);
|
||||
fssh_status_t (*write_stat)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
const struct fssh_stat *stat, uint32_t statMask);
|
||||
|
||||
/* file operations */
|
||||
fssh_status_t (*create)(fssh_fs_volume fs, fssh_fs_vnode dir,
|
||||
const char *name, int openMode, int perms,
|
||||
fssh_fs_cookie *_cookie, fssh_vnode_id *_newVnodeID);
|
||||
fssh_status_t (*open)(fssh_fs_volume fs, fssh_fs_vnode vnode, int openMode,
|
||||
fssh_fs_cookie *_cookie);
|
||||
fssh_status_t (*close)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*free_cookie)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, fssh_off_t pos, void *buffer,
|
||||
fssh_size_t *length);
|
||||
fssh_status_t (*write)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, fssh_off_t pos, const void *buffer,
|
||||
fssh_size_t *length);
|
||||
|
||||
/* directory operations */
|
||||
fssh_status_t (*create_dir)(fssh_fs_volume fs, fssh_fs_vnode parent,
|
||||
const char *name, int perms, fssh_vnode_id *_newVnodeID);
|
||||
fssh_status_t (*remove_dir)(fssh_fs_volume fs, fssh_fs_vnode parent,
|
||||
const char *name);
|
||||
fssh_status_t (*open_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie *_cookie);
|
||||
fssh_status_t (*close_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*free_dir_cookie)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, struct fssh_dirent *buffer,
|
||||
fssh_size_t bufferSize, uint32_t *_num);
|
||||
fssh_status_t (*rewind_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
|
||||
/* attribute directory operations */
|
||||
fssh_status_t (*open_attr_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie *_cookie);
|
||||
fssh_status_t (*close_attr_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*free_attr_dir_cookie)(fssh_fs_volume fs,
|
||||
fssh_fs_vnode vnode, fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read_attr_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, struct fssh_dirent *buffer,
|
||||
fssh_size_t bufferSize, uint32_t *_num);
|
||||
fssh_status_t (*rewind_attr_dir)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
|
||||
/* attribute operations */
|
||||
fssh_status_t (*create_attr)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
const char *name, uint32_t type, int openMode,
|
||||
fssh_fs_cookie *_cookie);
|
||||
fssh_status_t (*open_attr)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
const char *name, int openMode, fssh_fs_cookie *_cookie);
|
||||
fssh_status_t (*close_attr)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*free_attr_cookie)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read_attr)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, fssh_off_t pos, void *buffer,
|
||||
fssh_size_t *length);
|
||||
fssh_status_t (*write_attr)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, fssh_off_t pos, const void *buffer,
|
||||
fssh_size_t *length);
|
||||
|
||||
fssh_status_t (*read_attr_stat)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, struct fssh_stat *stat);
|
||||
fssh_status_t (*write_attr_stat)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
fssh_fs_cookie cookie, const struct fssh_stat *stat,
|
||||
int statMask);
|
||||
fssh_status_t (*rename_attr)(fssh_fs_volume fs, fssh_fs_vnode fromVnode,
|
||||
const char *fromName, fssh_fs_vnode toVnode,
|
||||
const char *toName);
|
||||
fssh_status_t (*remove_attr)(fssh_fs_volume fs, fssh_fs_vnode vnode,
|
||||
const char *name);
|
||||
|
||||
/* index directory & index operations */
|
||||
fssh_status_t (*open_index_dir)(fssh_fs_volume fs, fssh_fs_cookie *cookie);
|
||||
fssh_status_t (*close_index_dir)(fssh_fs_volume fs, fssh_fs_cookie cookie);
|
||||
fssh_status_t (*free_index_dir_cookie)(fssh_fs_volume fs,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read_index_dir)(fssh_fs_volume fs, fssh_fs_cookie cookie,
|
||||
struct fssh_dirent *buffer, fssh_size_t bufferSize,
|
||||
uint32_t *_num);
|
||||
fssh_status_t (*rewind_index_dir)(fssh_fs_volume fs, fssh_fs_cookie cookie);
|
||||
|
||||
fssh_status_t (*create_index)(fssh_fs_volume fs, const char *name,
|
||||
uint32_t type, uint32_t flags);
|
||||
fssh_status_t (*remove_index)(fssh_fs_volume fs, const char *name);
|
||||
fssh_status_t (*read_index_stat)(fssh_fs_volume fs, const char *name,
|
||||
struct fssh_stat *stat);
|
||||
|
||||
/* query operations */
|
||||
fssh_status_t (*open_query)(fssh_fs_volume fs, const char *query,
|
||||
uint32_t flags, fssh_port_id port, uint32_t token,
|
||||
fssh_fs_cookie *_cookie);
|
||||
fssh_status_t (*close_query)(fssh_fs_volume fs, fssh_fs_cookie cookie);
|
||||
fssh_status_t (*free_query_cookie)(fssh_fs_volume fs,
|
||||
fssh_fs_cookie cookie);
|
||||
fssh_status_t (*read_query)(fssh_fs_volume fs, fssh_fs_cookie cookie,
|
||||
struct fssh_dirent *buffer, fssh_size_t bufferSize,
|
||||
uint32_t *_num);
|
||||
fssh_status_t (*rewind_query)(fssh_fs_volume fs, fssh_fs_cookie cookie);
|
||||
fssh_status_t (*mount)(fssh_fs_volume *volume, const char *device,
|
||||
uint32_t flags, const char *args, fssh_vnode_id *_rootVnodeID);
|
||||
|
||||
/* capability querying (the device is read locked) */
|
||||
uint32_t (*get_supported_operations)(fssh_partition_data* partition,
|
||||
@ -269,20 +320,23 @@ typedef struct fssh_file_system_module_info {
|
||||
|
||||
|
||||
/* file system add-ons only prototypes */
|
||||
extern fssh_status_t fssh_new_vnode(fssh_mount_id mountID,
|
||||
fssh_vnode_id vnodeID, fssh_fs_vnode privateNode);
|
||||
extern fssh_status_t fssh_publish_vnode(fssh_mount_id mountID,
|
||||
fssh_vnode_id vnodeID, fssh_fs_vnode privateNode);
|
||||
extern fssh_status_t fssh_get_vnode(fssh_mount_id mountID,
|
||||
fssh_vnode_id vnodeID, fssh_fs_vnode *_privateNode);
|
||||
extern fssh_status_t fssh_put_vnode(fssh_mount_id mountID,
|
||||
extern fssh_status_t fssh_new_vnode(fssh_fs_volume *volume,
|
||||
fssh_vnode_id vnodeID, void *privateNode,
|
||||
fssh_fs_vnode_ops *ops);
|
||||
extern fssh_status_t fssh_publish_vnode(fssh_fs_volume *volume,
|
||||
fssh_vnode_id vnodeID, void *privateNode,
|
||||
fssh_fs_vnode_ops *ops, int type, uint32_t flags);
|
||||
extern fssh_status_t fssh_get_vnode(fssh_fs_volume *volume,
|
||||
fssh_vnode_id vnodeID, void **_privateNode);
|
||||
extern fssh_status_t fssh_put_vnode(fssh_fs_volume *volume,
|
||||
fssh_vnode_id vnodeID);
|
||||
extern fssh_status_t fssh_remove_vnode(fssh_mount_id mountID,
|
||||
extern fssh_status_t fssh_remove_vnode(fssh_fs_volume *volume,
|
||||
fssh_vnode_id vnodeID);
|
||||
extern fssh_status_t fssh_unremove_vnode(fssh_mount_id mountID,
|
||||
extern fssh_status_t fssh_unremove_vnode(fssh_fs_volume *volume,
|
||||
fssh_vnode_id vnodeID);
|
||||
extern fssh_status_t fssh_get_vnode_removed(fssh_mount_id mountID,
|
||||
extern fssh_status_t fssh_get_vnode_removed(fssh_fs_volume *volume,
|
||||
fssh_vnode_id vnodeID, bool* removed);
|
||||
|
||||
extern fssh_status_t fssh_read_pages(int fd, fssh_off_t pos,
|
||||
const struct fssh_iovec *vecs, fssh_size_t count,
|
||||
fssh_size_t *_numBytes, bool fsReenter);
|
||||
|
@ -178,6 +178,7 @@ extern status_t _kern_create_link(const char *path, const char *toPath);
|
||||
extern status_t _kern_unlink(int fd, const char *path);
|
||||
extern status_t _kern_rename(int oldDir, const char *oldpath, int newDir,
|
||||
const char *newpath);
|
||||
extern status_t _kern_create_fifo(const char *path, mode_t perms);
|
||||
extern status_t _kern_access(const char *path, int mode);
|
||||
extern ssize_t _kern_select(int numfds, struct fd_set *readSet,
|
||||
struct fd_set *writeSet, struct fd_set *errorSet,
|
||||
|
@ -104,7 +104,7 @@ status_t vfs_get_vnode_cache(struct vnode *vnode, struct vm_cache **_cache,
|
||||
bool allocate);
|
||||
status_t vfs_get_file_map(struct vnode *vnode, off_t offset, size_t size,
|
||||
struct file_io_vec *vecs, size_t *_count);
|
||||
status_t vfs_get_fs_node_from_path(dev_t mountID, const char *path,
|
||||
status_t vfs_get_fs_node_from_path(fs_volume *volume, const char *path,
|
||||
bool kernel, void **_node);
|
||||
status_t vfs_stat_vnode(struct vnode *vnode, struct stat *stat);
|
||||
status_t vfs_stat_entry_ref(dev_t device, ino_t inode, struct stat *stat);
|
||||
@ -171,6 +171,7 @@ status_t _user_create_link(const char *path, const char *toPath);
|
||||
status_t _user_unlink(int fd, const char *path);
|
||||
status_t _user_rename(int oldFD, const char *oldpath, int newFD,
|
||||
const char *newpath);
|
||||
status_t _user_create_fifo(const char *path, mode_t perms);
|
||||
status_t _user_access(const char *path, int mode);
|
||||
ssize_t _user_select(int numfds, fd_set *readSet, fd_set *writeSet, fd_set *errorSet,
|
||||
bigtime_t timeout, const sigset_t *sigMask);
|
||||
|
@ -954,7 +954,7 @@ BlockAllocator::StopChecking(check_control *control)
|
||||
cookie->iterator = NULL;
|
||||
|
||||
// the current directory inode is still locked in memory
|
||||
put_vnode(fVolume->ID(), fVolume->ToVnode(cookie->current));
|
||||
put_vnode(fVolume->FSVolume(), fVolume->ToVnode(cookie->current));
|
||||
}
|
||||
|
||||
// if CheckNextNode() could completely work through, we can
|
||||
@ -1089,7 +1089,7 @@ BlockAllocator::CheckNextNode(check_control *control)
|
||||
cookie->iterator = NULL;
|
||||
|
||||
// unlock the directory's inode from memory
|
||||
put_vnode(fVolume->ID(), fVolume->ToVnode(cookie->current));
|
||||
put_vnode(fVolume->FSVolume(), fVolume->ToVnode(cookie->current));
|
||||
|
||||
continue;
|
||||
} else if (status == B_OK) {
|
||||
|
@ -34,7 +34,7 @@ Index::~Index()
|
||||
return;
|
||||
|
||||
if (fVolume->ID() >= 0)
|
||||
put_vnode(fVolume->ID(), fNode->ID());
|
||||
put_vnode(fVolume->FSVolume(), fNode->ID());
|
||||
}
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ Index::Unset()
|
||||
return;
|
||||
|
||||
if (fVolume->ID() >= 0)
|
||||
put_vnode(fVolume->ID(), fNode->ID());
|
||||
put_vnode(fVolume->FSVolume(), fNode->ID());
|
||||
fNode = NULL;
|
||||
fName = NULL;
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ InodeAllocator::~InodeAllocator()
|
||||
fInode->Node().flags &= ~HOST_ENDIAN_TO_BFS_INT32(INODE_IN_USE);
|
||||
// this unblocks any pending bfs_read_vnode() calls
|
||||
fInode->Free(*fTransaction);
|
||||
remove_vnode(volume->ID(), fInode->ID());
|
||||
remove_vnode(volume->FSVolume(), fInode->ID());
|
||||
} else
|
||||
volume->Free(*fTransaction, fRun);
|
||||
}
|
||||
@ -199,7 +199,8 @@ InodeAllocator::New(block_run *parentRun, mode_t mode, block_run &run,
|
||||
RETURN_ERROR(B_NO_MEMORY);
|
||||
|
||||
if (volume->ID() >= 0) {
|
||||
status = new_vnode(volume->ID(), fInode->ID(), fInode);
|
||||
status = new_vnode(volume->FSVolume(), fInode->ID(), fInode,
|
||||
&gBFSVnodeOps);
|
||||
if (status < B_OK) {
|
||||
delete fInode;
|
||||
fInode = NULL;
|
||||
@ -247,8 +248,10 @@ InodeAllocator::Keep()
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!fInode->IsSymLink() && volume->ID() >= 0)
|
||||
status = publish_vnode(volume->ID(), fInode->ID(), fInode);
|
||||
if (!fInode->IsSymLink() && volume->ID() >= 0) {
|
||||
status = publish_vnode(volume->FSVolume(), fInode->ID(), fInode,
|
||||
&gBFSVnodeOps, fInode->Mode(), 0);
|
||||
}
|
||||
|
||||
if (status == B_OK) {
|
||||
cache_add_transaction_listener(volume->BlockCache(), fTransaction->ID(),
|
||||
@ -933,14 +936,14 @@ Inode::_RemoveAttribute(Transaction &transaction, const char *name,
|
||||
|
||||
if (attributes->IsEmpty()) {
|
||||
// remove attribute directory (don't fail if that can't be done)
|
||||
if (remove_vnode(fVolume->ID(), attributes->ID()) == B_OK) {
|
||||
if (remove_vnode(fVolume->FSVolume(), attributes->ID()) == B_OK) {
|
||||
// update the inode, so that no one will ever doubt it's deleted :-)
|
||||
attributes->Node().flags |= HOST_ENDIAN_TO_BFS_INT32(INODE_DELETED);
|
||||
if (attributes->WriteBack(transaction) == B_OK) {
|
||||
Attributes().SetTo(0, 0, 0);
|
||||
WriteBack(transaction);
|
||||
} else
|
||||
unremove_vnode(fVolume->ID(), attributes->ID());
|
||||
unremove_vnode(fVolume->FSVolume(), attributes->ID());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1188,7 +1191,7 @@ Inode::ReleaseAttribute(Inode *attribute)
|
||||
if (attribute == NULL)
|
||||
return;
|
||||
|
||||
put_vnode(fVolume->ID(), attribute->ID());
|
||||
put_vnode(fVolume->FSVolume(), attribute->ID());
|
||||
}
|
||||
|
||||
|
||||
@ -2240,12 +2243,12 @@ Inode::Remove(Transaction &transaction, const char *name, ino_t *_id,
|
||||
}
|
||||
|
||||
// remove_vnode() allows the inode to be accessed until the last put_vnode()
|
||||
status = remove_vnode(fVolume->ID(), id);
|
||||
status = remove_vnode(fVolume->FSVolume(), id);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
if (tree->Remove(transaction, name, id) < B_OK) {
|
||||
unremove_vnode(fVolume->ID(), id);
|
||||
unremove_vnode(fVolume->FSVolume(), id);
|
||||
RETURN_ERROR(B_ERROR);
|
||||
}
|
||||
|
||||
@ -2494,7 +2497,7 @@ Inode::Create(Transaction &transaction, Inode *parent, const char *name,
|
||||
|
||||
// if either _id or _inode is passed, we will keep the inode locked
|
||||
if (_id == NULL && _inode == NULL)
|
||||
put_vnode(volume->ID(), inode->ID());
|
||||
put_vnode(volume->FSVolume(), inode->ID());
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -2518,7 +2521,7 @@ AttributeIterator::AttributeIterator(Inode *inode)
|
||||
AttributeIterator::~AttributeIterator()
|
||||
{
|
||||
if (fAttributes)
|
||||
put_vnode(fAttributes->GetVolume()->ID(), fAttributes->ID());
|
||||
put_vnode(fAttributes->GetVolume()->FSVolume(), fAttributes->ID());
|
||||
|
||||
delete fIterator;
|
||||
fInode->_RemoveIterator(this);
|
||||
@ -2591,7 +2594,7 @@ AttributeIterator::GetNext(char *name, size_t *_length, uint32 *_type,
|
||||
|
||||
// if you haven't yet access to the attributes directory, get it
|
||||
if (fAttributes == NULL) {
|
||||
if (get_vnode(volume->ID(), volume->ToVnode(fInode->Attributes()),
|
||||
if (get_vnode(volume->FSVolume(), volume->ToVnode(fInode->Attributes()),
|
||||
(void **)&fAttributes) != B_OK) {
|
||||
FATAL(("get_vnode() failed in AttributeIterator::GetNext(ino_t"
|
||||
" = %Ld,name = \"%s\")\n",fInode->ID(),name));
|
||||
|
@ -276,13 +276,13 @@ class Vnode {
|
||||
status_t Get(Inode **_inode)
|
||||
{
|
||||
// should we check inode against NULL here? it should not be necessary
|
||||
return get_vnode(fVolume->ID(), fID, (void **)_inode);
|
||||
return get_vnode(fVolume->FSVolume(), fID, (void **)_inode);
|
||||
}
|
||||
|
||||
void Put()
|
||||
{
|
||||
if (fVolume)
|
||||
put_vnode(fVolume->ID(), fID);
|
||||
put_vnode(fVolume->FSVolume(), fID);
|
||||
fVolume = NULL;
|
||||
}
|
||||
|
||||
|
@ -272,9 +272,9 @@ disk_super_block::Initialize(const char *diskName, off_t numBlocks,
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
Volume::Volume(dev_t id)
|
||||
Volume::Volume(fs_volume *volume)
|
||||
:
|
||||
fID(id),
|
||||
fVolume(volume),
|
||||
fBlockAllocator(this),
|
||||
fLock("bfs volume"),
|
||||
fRootNode(NULL),
|
||||
@ -388,7 +388,8 @@ Volume::Mount(const char *deviceName, uint32 flags)
|
||||
|
||||
fRootNode = new Inode(this, ToVnode(Root()));
|
||||
if (fRootNode && fRootNode->InitCheck() == B_OK) {
|
||||
status = publish_vnode(fID, ToVnode(Root()), (void *)fRootNode);
|
||||
status = publish_vnode(fVolume, ToVnode(Root()), (void *)fRootNode,
|
||||
&gBFSVnodeOps, fRootNode->Mode(), 0);
|
||||
if (status == B_OK) {
|
||||
// try to get indices root dir
|
||||
|
||||
@ -429,7 +430,7 @@ status_t
|
||||
Volume::Unmount()
|
||||
{
|
||||
// Unlike in BeOS, we need to put the reference to our root node ourselves
|
||||
put_vnode(fID, ToVnode(Root()));
|
||||
put_vnode(fVolume, ToVnode(Root()));
|
||||
|
||||
// This will also flush the log & all blocks to disk
|
||||
delete fJournal;
|
||||
|
@ -26,7 +26,7 @@ enum volume_initialize_flags {
|
||||
|
||||
class Volume {
|
||||
public:
|
||||
Volume(dev_t id);
|
||||
Volume(fs_volume *volume);
|
||||
~Volume();
|
||||
|
||||
status_t Mount(const char *device, uint32 flags);
|
||||
@ -48,7 +48,8 @@ class Volume {
|
||||
vint32 &LogEnd() { return fLogEnd; }
|
||||
int Device() const { return fDevice; }
|
||||
|
||||
dev_t ID() const { return fID; }
|
||||
dev_t ID() const { return fVolume ? fVolume->id : -1; }
|
||||
fs_volume *FSVolume() const { return fVolume; }
|
||||
const char *Name() const { return fSuperBlock.name; }
|
||||
|
||||
off_t NumBlocks() const { return fSuperBlock.NumBlocks(); }
|
||||
@ -107,7 +108,7 @@ class Volume {
|
||||
static status_t Identify(int fd, disk_super_block *superBlock);
|
||||
|
||||
protected:
|
||||
dev_t fID;
|
||||
fs_volume *fVolume;
|
||||
int fDevice;
|
||||
disk_super_block fSuperBlock;
|
||||
|
||||
|
@ -21,6 +21,11 @@ namespace BFS {
|
||||
// ToDo: temporary fix! (missing but public ioctls)
|
||||
#define IOCTL_FILE_UNCACHED_IO 10000
|
||||
|
||||
#ifndef _BOOT_MODE
|
||||
extern fs_volume_ops gBFSVolumeOps;
|
||||
extern fs_vnode_ops gBFSVnodeOps;
|
||||
#endif
|
||||
|
||||
struct block_run {
|
||||
int32 allocation_group;
|
||||
uint16 start;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -99,6 +99,7 @@ struct devfs_vnode {
|
||||
|
||||
struct devfs {
|
||||
dev_t id;
|
||||
fs_volume *volume;
|
||||
recursive_lock lock;
|
||||
int32 next_vnode_id;
|
||||
hash_table *vnode_hash;
|
||||
@ -158,6 +159,12 @@ class DriverWatcher : public NotificationListener {
|
||||
const KMessage* event);
|
||||
};
|
||||
|
||||
// extern and in a private namespace only to make forward declaration possible
|
||||
namespace {
|
||||
extern fs_volume_ops kVolumeOps;
|
||||
extern fs_vnode_ops kVnodeOps;
|
||||
}
|
||||
|
||||
|
||||
static status_t get_node_for_path(struct devfs *fs, const char *path,
|
||||
struct devfs_vnode **_node);
|
||||
@ -467,12 +474,12 @@ unpublish_driver(driver_entry *driver)
|
||||
if (S_ISCHR(vnode->stream.type)
|
||||
&& vnode->stream.u.dev.driver == driver) {
|
||||
void *dummy;
|
||||
get_vnode(sDeviceFileSystem->id, vnode->id, &dummy);
|
||||
get_vnode(sDeviceFileSystem->volume, vnode->id, &dummy);
|
||||
// We need to get/put the node, so that it is
|
||||
// actually removed
|
||||
|
||||
unpublish_node(sDeviceFileSystem, vnode, S_IFCHR);
|
||||
put_vnode(sDeviceFileSystem->id, vnode->id);
|
||||
put_vnode(sDeviceFileSystem->volume, vnode->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -818,9 +825,10 @@ devfs_delete_vnode(struct devfs *fs, struct devfs_vnode *vnode,
|
||||
|
||||
if (S_ISCHR(vnode->stream.type)) {
|
||||
// for partitions, we have to release the raw device
|
||||
if (vnode->stream.u.dev.partition)
|
||||
put_vnode(fs->id, vnode->stream.u.dev.partition->raw_device->id);
|
||||
else
|
||||
if (vnode->stream.u.dev.partition) {
|
||||
put_vnode(fs->volume,
|
||||
vnode->stream.u.dev.partition->raw_device->id);
|
||||
} else
|
||||
delete vnode->stream.u.dev.scheduler;
|
||||
|
||||
// remove API conversion from old to new drivers
|
||||
@ -973,7 +981,7 @@ add_partition(struct devfs *fs, struct devfs_vnode *device,
|
||||
|
||||
// increase reference count of raw device -
|
||||
// the partition device really needs it
|
||||
status = get_vnode(fs->id, device->id, (fs_vnode *)&partition->raw_device);
|
||||
status = get_vnode(fs->volume, device->id, (void**)&partition->raw_device);
|
||||
if (status < B_OK)
|
||||
goto err1;
|
||||
|
||||
@ -999,7 +1007,7 @@ add_partition(struct devfs *fs, struct devfs_vnode *device,
|
||||
return B_OK;
|
||||
|
||||
err2:
|
||||
put_vnode(fs->id, device->id);
|
||||
put_vnode(fs->volume, device->id);
|
||||
err1:
|
||||
free(partition);
|
||||
return status;
|
||||
@ -1063,7 +1071,7 @@ static status_t
|
||||
get_node_for_path(struct devfs *fs, const char *path,
|
||||
struct devfs_vnode **_node)
|
||||
{
|
||||
return vfs_get_fs_node_from_path(fs->id, path, true, (void **)_node);
|
||||
return vfs_get_fs_node_from_path(fs->volume, path, true, (void **)_node);
|
||||
}
|
||||
|
||||
|
||||
@ -1079,7 +1087,7 @@ unpublish_node(struct devfs *fs, devfs_vnode *node, mode_t type)
|
||||
if (status < B_OK)
|
||||
goto out;
|
||||
|
||||
status = remove_vnode(fs->id, node->id);
|
||||
status = remove_vnode(fs->volume, node->id);
|
||||
|
||||
if (status == B_OK && S_ISCHR(node->stream.type)
|
||||
&& node->stream.u.dev.driver != NULL) {
|
||||
@ -1102,7 +1110,7 @@ unpublish_node(struct devfs *fs, const char *path, mode_t type)
|
||||
|
||||
status = unpublish_node(fs, node, type);
|
||||
|
||||
put_vnode(fs->id, node->id);
|
||||
put_vnode(fs->volume, node->id);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -1484,8 +1492,8 @@ dump_driver(int argc, char **argv)
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_mount(dev_t id, const char *devfs, uint32 flags, const char *args,
|
||||
fs_volume *_fs, ino_t *root_vnid)
|
||||
devfs_mount(fs_volume *volume, const char *devfs, uint32 flags,
|
||||
const char *args, ino_t *root_vnid)
|
||||
{
|
||||
struct devfs_vnode *vnode;
|
||||
struct devfs *fs;
|
||||
@ -1505,7 +1513,10 @@ devfs_mount(dev_t id, const char *devfs, uint32 flags, const char *args,
|
||||
goto err;
|
||||
}
|
||||
|
||||
fs->id = id;
|
||||
volume->private_volume = fs;
|
||||
volume->ops = &kVolumeOps;
|
||||
fs->volume = volume;
|
||||
fs->id = volume->id;
|
||||
fs->next_vnode_id = 0;
|
||||
|
||||
err = recursive_lock_init(&fs->lock, "devfs lock");
|
||||
@ -1550,10 +1561,9 @@ devfs_mount(dev_t id, const char *devfs, uint32 flags, const char *args,
|
||||
fs->root_vnode = vnode;
|
||||
|
||||
hash_insert(fs->vnode_hash, vnode);
|
||||
publish_vnode(id, vnode->id, vnode);
|
||||
publish_vnode(volume, vnode->id, vnode, &kVnodeOps, vnode->stream.type, 0);
|
||||
|
||||
*root_vnid = vnode->id;
|
||||
*_fs = fs;
|
||||
sDeviceFileSystem = fs;
|
||||
return B_OK;
|
||||
|
||||
@ -1571,9 +1581,9 @@ err:
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_unmount(fs_volume _fs)
|
||||
devfs_unmount(fs_volume *_volume)
|
||||
{
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
struct devfs_vnode *vnode;
|
||||
struct hash_iterator i;
|
||||
|
||||
@ -1592,7 +1602,7 @@ devfs_unmount(fs_volume _fs)
|
||||
}
|
||||
|
||||
// release the reference to the root
|
||||
put_vnode(fs->id, fs->root_vnode->id);
|
||||
put_vnode(fs->volume, fs->root_vnode->id);
|
||||
|
||||
// delete all of the vnodes
|
||||
hash_open(fs->vnode_hash, &i);
|
||||
@ -1612,7 +1622,7 @@ devfs_unmount(fs_volume _fs)
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_sync(fs_volume fs)
|
||||
devfs_sync(fs_volume *_volume)
|
||||
{
|
||||
TRACE(("devfs_sync: entry\n"));
|
||||
|
||||
@ -1621,11 +1631,10 @@ devfs_sync(fs_volume fs)
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_lookup(fs_volume _fs, fs_vnode _dir, const char *name, ino_t *_id,
|
||||
int *_type)
|
||||
devfs_lookup(fs_volume *_volume, fs_vnode *_dir, const char *name, ino_t *_id)
|
||||
{
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs_vnode *dir = (struct devfs_vnode *)_dir;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
struct devfs_vnode *dir = (struct devfs_vnode *)_dir->private_node;
|
||||
struct devfs_vnode *vnode, *vdummy;
|
||||
status_t status;
|
||||
|
||||
@ -1647,21 +1656,21 @@ devfs_lookup(fs_volume _fs, fs_vnode _dir, const char *name, ino_t *_id,
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
status = get_vnode(fs->id, vnode->id, (fs_vnode *)&vdummy);
|
||||
status = get_vnode(fs->volume, vnode->id, (void**)&vdummy);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
*_id = vnode->id;
|
||||
*_type = vnode->stream.type;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_get_vnode_name(fs_volume _fs, fs_vnode _vnode, char *buffer, size_t bufferSize)
|
||||
devfs_get_vnode_name(fs_volume *_volume, fs_vnode *_vnode, char *buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
|
||||
TRACE(("devfs_get_vnode_name: vnode = %p\n", vnode));
|
||||
|
||||
@ -1671,9 +1680,10 @@ devfs_get_vnode_name(fs_volume _fs, fs_vnode _vnode, char *buffer, size_t buffer
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_get_vnode(fs_volume _fs, ino_t id, fs_vnode *_vnode, bool reenter)
|
||||
devfs_get_vnode(fs_volume *_volume, ino_t id, fs_vnode *_vnode, int *_type,
|
||||
uint32 *_flags, bool reenter)
|
||||
{
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
|
||||
TRACE(("devfs_get_vnode: asking for vnode id = %Ld, vnode = %p, r %d\n", id, _vnode, reenter));
|
||||
|
||||
@ -1685,16 +1695,19 @@ devfs_get_vnode(fs_volume _fs, ino_t id, fs_vnode *_vnode, bool reenter)
|
||||
|
||||
TRACE(("devfs_get_vnode: looked it up at %p\n", *_vnode));
|
||||
|
||||
*_vnode = vnode;
|
||||
_vnode->private_node = vnode;
|
||||
_vnode->ops = &kVnodeOps;
|
||||
*_type = vnode->stream.type;
|
||||
*_flags = 0;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_put_vnode(fs_volume _fs, fs_vnode _v, bool reenter)
|
||||
devfs_put_vnode(fs_volume *_volume, fs_vnode *_v, bool reenter)
|
||||
{
|
||||
#ifdef TRACE_DEVFS
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_v;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_v->private_node;
|
||||
|
||||
TRACE(("devfs_put_vnode: entry on vnode %p, id = %Ld, reenter %d\n",
|
||||
vnode, vnode->id, reenter));
|
||||
@ -1705,10 +1718,10 @@ devfs_put_vnode(fs_volume _fs, fs_vnode _v, bool reenter)
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_remove_vnode(fs_volume _fs, fs_vnode _v, bool reenter)
|
||||
devfs_remove_vnode(fs_volume *_volume, fs_vnode *_v, bool reenter)
|
||||
{
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_v;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_v->private_node;
|
||||
|
||||
TRACE(("devfs_removevnode: remove %p (%Ld), reenter %d\n", vnode, vnode->id, reenter));
|
||||
|
||||
@ -1726,11 +1739,11 @@ devfs_remove_vnode(fs_volume _fs, fs_vnode _v, bool reenter)
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_create(fs_volume _fs, fs_vnode _dir, const char *name, int openMode, int perms,
|
||||
fs_cookie *_cookie, ino_t *_newVnodeID)
|
||||
devfs_create(fs_volume *_volume, fs_vnode *_dir, const char *name, int openMode,
|
||||
int perms, void **_cookie, ino_t *_newVnodeID)
|
||||
{
|
||||
struct devfs_vnode *dir = (struct devfs_vnode *)_dir;
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs_vnode *dir = (struct devfs_vnode *)_dir->private_node;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
struct devfs_cookie *cookie;
|
||||
struct devfs_vnode *vnode, *vdummy;
|
||||
status_t status = B_OK;
|
||||
@ -1749,7 +1762,7 @@ devfs_create(fs_volume _fs, fs_vnode _dir, const char *name, int openMode, int p
|
||||
if (openMode & O_EXCL)
|
||||
return B_FILE_EXISTS;
|
||||
|
||||
status = get_vnode(fs->id, vnode->id, (fs_vnode *)&vdummy);
|
||||
status = get_vnode(fs->volume, vnode->id, (void**)&vdummy);
|
||||
if (status < B_OK)
|
||||
goto err1;
|
||||
|
||||
@ -1783,17 +1796,18 @@ devfs_create(fs_volume _fs, fs_vnode _dir, const char *name, int openMode, int p
|
||||
err3:
|
||||
free(cookie);
|
||||
err2:
|
||||
put_vnode(fs->id, vnode->id);
|
||||
put_vnode(fs->volume, vnode->id);
|
||||
err1:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_open(fs_volume _fs, fs_vnode _vnode, int openMode, fs_cookie *_cookie)
|
||||
devfs_open(fs_volume *_volume, fs_vnode *_vnode, int openMode,
|
||||
void **_cookie)
|
||||
{
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
struct devfs_cookie *cookie;
|
||||
status_t status = B_OK;
|
||||
|
||||
@ -1846,9 +1860,9 @@ devfs_open(fs_volume _fs, fs_vnode _vnode, int openMode, fs_cookie *_cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_close(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
|
||||
devfs_close(fs_volume *_volume, fs_vnode *_vnode, void *_cookie)
|
||||
{
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie;
|
||||
|
||||
TRACE(("devfs_close: entry vnode %p, cookie %p\n", vnode, cookie));
|
||||
@ -1863,11 +1877,11 @@ devfs_close(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_free_cookie(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
|
||||
devfs_free_cookie(fs_volume *_volume, fs_vnode *_vnode, void *_cookie)
|
||||
{
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie;
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
|
||||
TRACE(("devfs_freecookie: entry vnode %p, cookie %p\n", vnode, cookie));
|
||||
|
||||
@ -1887,16 +1901,17 @@ devfs_free_cookie(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_fsync(fs_volume _fs, fs_vnode _v)
|
||||
devfs_fsync(fs_volume *_volume, fs_vnode *_v)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_read_link(fs_volume _fs, fs_vnode _link, char *buffer, size_t *_bufferSize)
|
||||
devfs_read_link(fs_volume *_volume, fs_vnode *_link, char *buffer,
|
||||
size_t *_bufferSize)
|
||||
{
|
||||
struct devfs_vnode *link = (struct devfs_vnode *)_link;
|
||||
struct devfs_vnode *link = (struct devfs_vnode *)_link->private_node;
|
||||
size_t bufferSize = *_bufferSize;
|
||||
|
||||
if (!S_ISLNK(link->stream.type))
|
||||
@ -1911,10 +1926,10 @@ devfs_read_link(fs_volume _fs, fs_vnode _link, char *buffer, size_t *_bufferSize
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_read(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, off_t pos,
|
||||
devfs_read(fs_volume *_volume, fs_vnode *_vnode, void *_cookie, off_t pos,
|
||||
void *buffer, size_t *_length)
|
||||
{
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie;
|
||||
|
||||
//TRACE(("devfs_read: vnode %p, cookie %p, pos %Ld, len %p\n",
|
||||
@ -1953,10 +1968,10 @@ devfs_read(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, off_t pos,
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_write(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, off_t pos,
|
||||
devfs_write(fs_volume *_volume, fs_vnode *_vnode, void *_cookie, off_t pos,
|
||||
const void *buffer, size_t *_length)
|
||||
{
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie;
|
||||
|
||||
//TRACE(("devfs_write: vnode %p, cookie %p, pos %Ld, len %p\n",
|
||||
@ -1993,11 +2008,11 @@ devfs_write(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, off_t pos,
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_create_dir(fs_volume _fs, fs_vnode _dir, const char *name,
|
||||
devfs_create_dir(fs_volume *_volume, fs_vnode *_dir, const char *name,
|
||||
int perms, ino_t *_newVnodeID)
|
||||
{
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs_vnode *dir = (struct devfs_vnode *)_dir;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
struct devfs_vnode *dir = (struct devfs_vnode *)_dir->private_node;
|
||||
|
||||
struct devfs_vnode *vnode = devfs_find_in_dir(dir, name);
|
||||
if (vnode != NULL) {
|
||||
@ -2023,10 +2038,10 @@ devfs_create_dir(fs_volume _fs, fs_vnode _dir, const char *name,
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_open_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie *_cookie)
|
||||
devfs_open_dir(fs_volume *_volume, fs_vnode *_vnode, void **_cookie)
|
||||
{
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_dir_cookie *cookie;
|
||||
|
||||
TRACE(("devfs_open_dir: vnode %p\n", vnode));
|
||||
@ -2055,11 +2070,11 @@ devfs_open_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie *_cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_free_dir_cookie(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
|
||||
devfs_free_dir_cookie(fs_volume *_volume, fs_vnode *_vnode, void *_cookie)
|
||||
{
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_dir_cookie *cookie = (devfs_dir_cookie *)_cookie;
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
|
||||
TRACE(("devfs_free_dir_cookie: entry vnode %p, cookie %p\n", vnode, cookie));
|
||||
|
||||
@ -2072,12 +2087,12 @@ devfs_free_dir_cookie(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_read_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie,
|
||||
devfs_read_dir(fs_volume *_volume, fs_vnode *_vnode, void *_cookie,
|
||||
struct dirent *dirent, size_t bufferSize, uint32 *_num)
|
||||
{
|
||||
struct devfs_vnode *vnode = (devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_dir_cookie *cookie = (devfs_dir_cookie *)_cookie;
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
status_t status = B_OK;
|
||||
struct devfs_vnode *childNode = NULL;
|
||||
const char *name = NULL;
|
||||
@ -2139,11 +2154,11 @@ devfs_read_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie,
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_rewind_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
|
||||
devfs_rewind_dir(fs_volume *_volume, fs_vnode *_vnode, void *_cookie)
|
||||
{
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_dir_cookie *cookie = (devfs_dir_cookie *)_cookie;
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
|
||||
TRACE(("devfs_rewind_dir: vnode %p, cookie %p\n", _vnode, _cookie));
|
||||
|
||||
@ -2163,11 +2178,11 @@ devfs_rewind_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
|
||||
specific functionality, like partitions.
|
||||
*/
|
||||
static status_t
|
||||
devfs_ioctl(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, ulong op,
|
||||
devfs_ioctl(fs_volume *_volume, fs_vnode *_vnode, void *_cookie, ulong op,
|
||||
void *buffer, size_t length)
|
||||
{
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie;
|
||||
|
||||
TRACE(("devfs_ioctl: vnode %p, cookie %p, op %ld, buf %p, len %ld\n",
|
||||
@ -2268,9 +2283,10 @@ devfs_ioctl(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, ulong op,
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_set_flags(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, int flags)
|
||||
devfs_set_flags(fs_volume *_volume, fs_vnode *_vnode, void *_cookie,
|
||||
int flags)
|
||||
{
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie;
|
||||
|
||||
// we need to pass the O_NONBLOCK flag to the underlying device
|
||||
@ -2284,10 +2300,10 @@ devfs_set_flags(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, int flags)
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_select(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, uint8 event,
|
||||
uint32 ref, selectsync *sync)
|
||||
devfs_select(fs_volume *_volume, fs_vnode *_vnode, void *_cookie,
|
||||
uint8 event, uint32 ref, selectsync *sync)
|
||||
{
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie;
|
||||
|
||||
if (!S_ISCHR(vnode->stream.type))
|
||||
@ -2303,10 +2319,10 @@ devfs_select(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, uint8 event,
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_deselect(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, uint8 event,
|
||||
selectsync *sync)
|
||||
devfs_deselect(fs_volume *_volume, fs_vnode *_vnode, void *_cookie,
|
||||
uint8 event, selectsync *sync)
|
||||
{
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie;
|
||||
|
||||
if (!S_ISCHR(vnode->stream.type))
|
||||
@ -2322,9 +2338,9 @@ devfs_deselect(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, uint8 event,
|
||||
|
||||
|
||||
static bool
|
||||
devfs_can_page(fs_volume _fs, fs_vnode _vnode, fs_cookie cookie)
|
||||
devfs_can_page(fs_volume *_volume, fs_vnode *_vnode, void *cookie)
|
||||
{
|
||||
struct devfs_vnode *vnode = (devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (devfs_vnode *)_vnode->private_node;
|
||||
|
||||
//TRACE(("devfs_canpage: vnode %p\n", vnode));
|
||||
|
||||
@ -2339,10 +2355,10 @@ devfs_can_page(fs_volume _fs, fs_vnode _vnode, fs_cookie cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_read_pages(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, off_t pos,
|
||||
const iovec *vecs, size_t count, size_t *_numBytes, bool reenter)
|
||||
devfs_read_pages(fs_volume *_volume, fs_vnode *_vnode, void *_cookie,
|
||||
off_t pos, const iovec *vecs, size_t count, size_t *_numBytes, bool reenter)
|
||||
{
|
||||
struct devfs_vnode *vnode = (devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie;
|
||||
|
||||
//TRACE(("devfs_read_pages: vnode %p, vecs %p, count = %lu, pos = %Ld, size = %lu\n", vnode, vecs, count, pos, *_numBytes));
|
||||
@ -2398,10 +2414,10 @@ devfs_read_pages(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, off_t pos,
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_write_pages(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, off_t pos,
|
||||
const iovec *vecs, size_t count, size_t *_numBytes, bool reenter)
|
||||
devfs_write_pages(fs_volume *_volume, fs_vnode *_vnode, void *_cookie,
|
||||
off_t pos, const iovec *vecs, size_t count, size_t *_numBytes, bool reenter)
|
||||
{
|
||||
struct devfs_vnode *vnode = (devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (devfs_vnode *)_vnode->private_node;
|
||||
struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie;
|
||||
|
||||
//TRACE(("devfs_write_pages: vnode %p, vecs %p, count = %lu, pos = %Ld, size = %lu\n", vnode, vecs, count, pos, *_numBytes));
|
||||
@ -2457,9 +2473,9 @@ devfs_write_pages(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, off_t pos,
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_read_stat(fs_volume _fs, fs_vnode _vnode, struct stat *stat)
|
||||
devfs_read_stat(fs_volume *_volume, fs_vnode *_vnode, struct stat *stat)
|
||||
{
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
|
||||
TRACE(("devfs_read_stat: vnode %p (%Ld), stat %p\n", vnode, vnode->id,
|
||||
stat));
|
||||
@ -2506,11 +2522,11 @@ devfs_read_stat(fs_volume _fs, fs_vnode _vnode, struct stat *stat)
|
||||
|
||||
|
||||
static status_t
|
||||
devfs_write_stat(fs_volume _fs, fs_vnode _vnode, const struct stat *stat,
|
||||
devfs_write_stat(fs_volume *_volume, fs_vnode *_vnode, const struct stat *stat,
|
||||
uint32 statMask)
|
||||
{
|
||||
struct devfs *fs = (struct devfs *)_fs;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode;
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode->private_node;
|
||||
|
||||
TRACE(("devfs_write_stat: vnode %p (0x%Lx), stat %p\n", vnode, vnode->id,
|
||||
stat));
|
||||
@ -2562,32 +2578,23 @@ devfs_std_ops(int32 op, ...)
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
file_system_module_info gDeviceFileSystem = {
|
||||
{
|
||||
"file_systems/devfs" B_CURRENT_FS_API_VERSION,
|
||||
0,
|
||||
devfs_std_ops,
|
||||
},
|
||||
|
||||
"Device File System",
|
||||
0, // DDM flags
|
||||
|
||||
NULL, // identify_partition()
|
||||
NULL, // scan_partition()
|
||||
NULL, // free_identify_partition_cookie()
|
||||
NULL, // free_partition_content_cookie()
|
||||
|
||||
&devfs_mount,
|
||||
fs_volume_ops kVolumeOps = {
|
||||
&devfs_unmount,
|
||||
NULL,
|
||||
NULL,
|
||||
&devfs_sync,
|
||||
&devfs_get_vnode,
|
||||
|
||||
// the other operations are not supported (attributes, indices, queries)
|
||||
NULL,
|
||||
};
|
||||
|
||||
fs_vnode_ops kVnodeOps = {
|
||||
&devfs_lookup,
|
||||
&devfs_get_vnode_name,
|
||||
|
||||
&devfs_get_vnode,
|
||||
&devfs_put_vnode,
|
||||
&devfs_remove_vnode,
|
||||
|
||||
@ -2632,10 +2639,30 @@ file_system_module_info gDeviceFileSystem = {
|
||||
&devfs_read_dir,
|
||||
&devfs_rewind_dir,
|
||||
|
||||
// the other operations are not supported (attributes, indices, queries)
|
||||
// attributes operations are not supported
|
||||
NULL,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
file_system_module_info gDeviceFileSystem = {
|
||||
{
|
||||
"file_systems/devfs" B_CURRENT_FS_API_VERSION,
|
||||
0,
|
||||
devfs_std_ops,
|
||||
},
|
||||
|
||||
"Device File System",
|
||||
0, // DDM flags
|
||||
|
||||
NULL, // identify_partition()
|
||||
NULL, // scan_partition()
|
||||
NULL, // free_identify_partition_cookie()
|
||||
NULL, // free_partition_content_cookie()
|
||||
|
||||
&devfs_mount,
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - device node
|
||||
// temporary hack to get it to work with the current device manager
|
||||
@ -2945,7 +2972,7 @@ devfs_publish_partition(const char *path, const partition_info *info)
|
||||
|
||||
status = add_partition(sDeviceFileSystem, device, lastPath + 1, *info);
|
||||
|
||||
put_vnode(sDeviceFileSystem->id, device->id);
|
||||
put_vnode(sDeviceFileSystem->volume, device->id);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -2963,7 +2990,7 @@ devfs_unpublish_device(const char *path, bool disconnect)
|
||||
if (status == B_OK && disconnect)
|
||||
vfs_disconnect_vnode(sDeviceFileSystem->id, node->id);
|
||||
|
||||
put_vnode(sDeviceFileSystem->id, node->id);
|
||||
put_vnode(sDeviceFileSystem->volume, node->id);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
14
src/system/kernel/fs/fifo.h
Normal file
14
src/system/kernel/fs/fifo.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _VFS_FIFO_H
|
||||
#define _VFS_FIFO_H
|
||||
|
||||
#include <fs_interface.h>
|
||||
|
||||
|
||||
status_t create_fifo_vnode(fs_volume* superVolume, fs_vnode* vnode);
|
||||
|
||||
|
||||
#endif // _VFS_FIFO_H
|
@ -10,6 +10,8 @@
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <NodeMonitor.h>
|
||||
#include <Select.h>
|
||||
@ -26,6 +28,8 @@
|
||||
#include <vfs.h>
|
||||
#include <vm.h>
|
||||
|
||||
#include "fifo.h"
|
||||
|
||||
|
||||
//#define TRACE_PIPEFS
|
||||
#ifdef TRACE_PIPEFS
|
||||
@ -111,11 +115,12 @@ typedef DoublyLinkedList<WriteRequest> WriteRequestList;
|
||||
|
||||
class Volume {
|
||||
public:
|
||||
Volume(dev_t id);
|
||||
Volume(fs_volume *volume);
|
||||
~Volume();
|
||||
|
||||
status_t InitCheck();
|
||||
dev_t ID() const { return fID; }
|
||||
fs_volume *FSVolume() const { return fVolume; }
|
||||
dev_t ID() const { return fVolume->id; }
|
||||
Inode &RootNode() const { return *fRootNode; }
|
||||
|
||||
void Lock();
|
||||
@ -144,7 +149,7 @@ class Volume {
|
||||
status_t _InsertNode(Inode *inode);
|
||||
|
||||
mutex fLock;
|
||||
dev_t fID;
|
||||
fs_volume *fVolume;
|
||||
Inode *fRootNode;
|
||||
ino_t fNextNodeID;
|
||||
hash_table *fNodeHash;
|
||||
@ -158,7 +163,7 @@ class Volume {
|
||||
|
||||
class Inode {
|
||||
public:
|
||||
Inode(Volume *volume, Inode *parent, const char *name, int32 type);
|
||||
Inode(ino_t, Inode *parent, const char *name, int32 type);
|
||||
~Inode();
|
||||
|
||||
status_t InitCheck();
|
||||
@ -266,6 +271,10 @@ struct file_cookie {
|
||||
int open_mode;
|
||||
};
|
||||
|
||||
// extern only to make forward declaration possible
|
||||
extern fs_volume_ops kVolumeOps;
|
||||
extern fs_vnode_ops kVnodeOps;
|
||||
|
||||
|
||||
//---------------------
|
||||
|
||||
@ -327,9 +336,9 @@ RingBuffer::Writable() const
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
Volume::Volume(dev_t id)
|
||||
Volume::Volume(fs_volume *volume)
|
||||
:
|
||||
fID(id),
|
||||
fVolume(volume),
|
||||
fRootNode(NULL),
|
||||
fNextNodeID(0),
|
||||
fNodeHash(NULL),
|
||||
@ -361,7 +370,7 @@ Volume::~Volume()
|
||||
{
|
||||
// put_vnode on the root to release the ref to it
|
||||
if (fRootNode)
|
||||
put_vnode(ID(), fRootNode->ID());
|
||||
put_vnode(FSVolume(), fRootNode->ID());
|
||||
|
||||
if (fNameHash != NULL)
|
||||
hash_uninit(fNameHash);
|
||||
@ -412,7 +421,7 @@ Volume::Unlock()
|
||||
Inode *
|
||||
Volume::CreateNode(Inode *parent, const char *name, int32 type)
|
||||
{
|
||||
Inode *inode = new Inode(this, parent, name, type);
|
||||
Inode *inode = new(std::nothrow) Inode(GetNextNodeID(), parent, name, type);
|
||||
if (inode == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -426,7 +435,8 @@ Volume::CreateNode(Inode *parent, const char *name, int32 type)
|
||||
|
||||
hash_insert(fNodeHash, inode);
|
||||
hash_insert(fNameHash, inode);
|
||||
publish_vnode(ID(), inode->ID(), inode);
|
||||
publish_vnode(FSVolume(), inode->ID(), inode, &kVnodeOps, inode->Type(),
|
||||
S_ISFIFO(type) ? B_VNODE_DONT_CREATE_SPECIAL_SUB_NODE : 0);
|
||||
|
||||
if (fRootNode != NULL)
|
||||
fRootNode->SetModificationTime(time(NULL));
|
||||
@ -544,7 +554,7 @@ status_t
|
||||
Volume::RemoveNode(Inode *inode)
|
||||
{
|
||||
// schedule this vnode to be removed when it's ref goes to zero
|
||||
status_t status = remove_vnode(ID(), inode->ID());
|
||||
status_t status = remove_vnode(FSVolume(), inode->ID());
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
@ -580,10 +590,12 @@ Volume::RemoveNode(Inode *directory, const char *name)
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
Inode::Inode(Volume *volume, Inode *parent, const char *name, int32 type)
|
||||
Inode::Inode(ino_t id, Inode *parent, const char *name, int32 type)
|
||||
:
|
||||
fNext(NULL),
|
||||
fHashNext(NULL),
|
||||
fID(id),
|
||||
fType(type),
|
||||
fReadRequests(),
|
||||
fWriteRequests(),
|
||||
fReaderCount(0),
|
||||
@ -595,9 +607,6 @@ Inode::Inode(Volume *volume, Inode *parent, const char *name, int32 type)
|
||||
if (fName == NULL)
|
||||
return;
|
||||
|
||||
fID = volume->GetNextNodeID();
|
||||
fType = type;
|
||||
|
||||
if (S_ISFIFO(type)) {
|
||||
fWriteCondition.Publish(this, "pipe");
|
||||
benaphore_init(&fRequestLock, "pipe request");
|
||||
@ -1037,12 +1046,12 @@ Inode::Deselect(uint8 event, selectsync *sync, int openMode)
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_mount(dev_t id, const char *device, uint32 flags, const char *args,
|
||||
fs_volume *_volume, ino_t *_rootVnodeID)
|
||||
pipefs_mount(fs_volume *_volume, const char *device, uint32 flags,
|
||||
const char *args, ino_t *_rootVnodeID)
|
||||
{
|
||||
TRACE(("pipefs_mount: entry\n"));
|
||||
|
||||
Volume *volume = new Volume(id);
|
||||
Volume *volume = new Volume(_volume);
|
||||
if (volume == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -1053,16 +1062,17 @@ pipefs_mount(dev_t id, const char *device, uint32 flags, const char *args,
|
||||
}
|
||||
|
||||
*_rootVnodeID = volume->RootNode().ID();
|
||||
*_volume = volume;
|
||||
_volume->ops = &kVolumeOps;
|
||||
_volume->private_volume = volume;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_unmount(fs_volume _volume)
|
||||
pipefs_unmount(fs_volume *_volume)
|
||||
{
|
||||
struct Volume *volume = (struct Volume *)_volume;
|
||||
struct Volume *volume = (struct Volume *)_volume->private_volume;
|
||||
|
||||
TRACE(("pipefs_unmount: entry fs = %p\n", _volume));
|
||||
delete volume;
|
||||
@ -1072,7 +1082,7 @@ pipefs_unmount(fs_volume _volume)
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_sync(fs_volume fs)
|
||||
pipefs_sync(fs_volume *_volume)
|
||||
{
|
||||
TRACE(("pipefs_sync: entry\n"));
|
||||
|
||||
@ -1081,15 +1091,15 @@ pipefs_sync(fs_volume fs)
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_lookup(fs_volume _volume, fs_vnode _dir, const char *name,
|
||||
ino_t *_id, int *_type)
|
||||
pipefs_lookup(fs_volume *_volume, fs_vnode *_dir, const char *name,
|
||||
ino_t *_id)
|
||||
{
|
||||
Volume *volume = (Volume *)_volume;
|
||||
Volume *volume = (Volume *)_volume->private_volume;
|
||||
status_t status;
|
||||
|
||||
TRACE(("pipefs_lookup: entry dir %p, name '%s'\n", _dir, name));
|
||||
|
||||
Inode *directory = (Inode *)_dir;
|
||||
Inode *directory = (Inode *)_dir->private_node;
|
||||
if (!S_ISDIR(directory->Type()))
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
@ -1103,12 +1113,11 @@ pipefs_lookup(fs_volume _volume, fs_vnode _dir, const char *name,
|
||||
}
|
||||
|
||||
Inode *dummy;
|
||||
status = get_vnode(volume->ID(), inode->ID(), (fs_vnode *)&dummy);
|
||||
status = get_vnode(volume->FSVolume(), inode->ID(), (void**)&dummy);
|
||||
if (status < B_OK)
|
||||
goto err;
|
||||
|
||||
*_id = inode->ID();
|
||||
*_type = inode->Type();
|
||||
|
||||
err:
|
||||
volume->Unlock();
|
||||
@ -1118,10 +1127,10 @@ err:
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_get_vnode_name(fs_volume _volume, fs_vnode _node, char *buffer,
|
||||
pipefs_get_vnode_name(fs_volume *_volume, fs_vnode *_node, char *buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
Inode *inode = (Inode *)_node;
|
||||
Inode *inode = (Inode *)_node->private_node;
|
||||
|
||||
TRACE(("pipefs_get_vnode_name(): inode = %p\n", inode));
|
||||
|
||||
@ -1131,10 +1140,10 @@ pipefs_get_vnode_name(fs_volume _volume, fs_vnode _node, char *buffer,
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_get_vnode(fs_volume _volume, ino_t id, fs_vnode *_inode,
|
||||
bool reenter)
|
||||
pipefs_get_vnode(fs_volume *_volume, ino_t id, fs_vnode *_inode, int *_type,
|
||||
uint32 *_flags, bool reenter)
|
||||
{
|
||||
Volume *volume = (Volume *)_volume;
|
||||
Volume *volume = (Volume *)_volume->private_volume;
|
||||
Inode *inode;
|
||||
|
||||
TRACE(("pipefs_getvnode: asking for vnode 0x%Lx, r %d\n", id, reenter));
|
||||
@ -1152,16 +1161,19 @@ pipefs_get_vnode(fs_volume _volume, ino_t id, fs_vnode *_inode,
|
||||
if (inode == NULL)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
*_inode = inode;
|
||||
_inode->private_node = inode;
|
||||
_inode->ops = &kVnodeOps;
|
||||
*_type = inode->Type();
|
||||
*_flags = 0;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_put_vnode(fs_volume _volume, fs_vnode _node, bool reenter)
|
||||
pipefs_put_vnode(fs_volume *_volume, fs_vnode *_node, bool reenter)
|
||||
{
|
||||
#ifdef TRACE_PIPEFS
|
||||
Inode *inode = (Inode *)_node;
|
||||
Inode *inode = (Inode *)_node->private_node;
|
||||
TRACE(("pipefs_putvnode: entry on vnode 0x%Lx, r %d\n", inode->ID(),
|
||||
reenter));
|
||||
#endif
|
||||
@ -1171,10 +1183,10 @@ pipefs_put_vnode(fs_volume _volume, fs_vnode _node, bool reenter)
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_remove_vnode(fs_volume _volume, fs_vnode _node, bool reenter)
|
||||
pipefs_remove_vnode(fs_volume *_volume, fs_vnode *_node, bool reenter)
|
||||
{
|
||||
Volume *volume = (Volume *)_volume;
|
||||
Inode *inode = (Inode *)_node;
|
||||
Volume *volume = (Volume *)_volume->private_volume;
|
||||
Inode *inode = (Inode *)_node->private_node;
|
||||
|
||||
TRACE(("pipefs_removevnode: remove %p (0x%Lx), r %d\n", inode, inode->ID(),
|
||||
reenter));
|
||||
@ -1198,10 +1210,10 @@ pipefs_remove_vnode(fs_volume _volume, fs_vnode _node, bool reenter)
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_create(fs_volume _volume, fs_vnode _dir, const char *name, int openMode,
|
||||
int mode, fs_cookie *_cookie, ino_t *_newVnodeID)
|
||||
pipefs_create(fs_volume *_volume, fs_vnode *_dir, const char *name,
|
||||
int openMode, int mode, void **_cookie, ino_t *_newVnodeID)
|
||||
{
|
||||
Volume *volume = (Volume *)_volume;
|
||||
Volume *volume = (Volume *)_volume->private_volume;
|
||||
bool wasCreated = true;
|
||||
|
||||
TRACE(("pipefs_create(): dir = %p, name = '%s', perms = %d, &id = %p\n",
|
||||
@ -1213,7 +1225,7 @@ pipefs_create(fs_volume _volume, fs_vnode _dir, const char *name, int openMode,
|
||||
|
||||
volume->Lock();
|
||||
|
||||
Inode *directory = (Inode *)_dir;
|
||||
Inode *directory = (Inode *)_dir->private_node;
|
||||
status_t status = B_OK;
|
||||
|
||||
Inode *inode = volume->Lookup(name);
|
||||
@ -1232,7 +1244,7 @@ pipefs_create(fs_volume _volume, fs_vnode _dir, const char *name, int openMode,
|
||||
} else {
|
||||
// we can just open the pipe again
|
||||
void *dummy;
|
||||
get_vnode(volume->ID(), inode->ID(), &dummy);
|
||||
get_vnode(volume->FSVolume(), inode->ID(), &dummy);
|
||||
wasCreated = false;
|
||||
}
|
||||
|
||||
@ -1259,10 +1271,10 @@ err:
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_open(fs_volume _volume, fs_vnode _node, int openMode,
|
||||
fs_cookie *_cookie)
|
||||
pipefs_open(fs_volume *_volume, fs_vnode *_node, int openMode,
|
||||
void **_cookie)
|
||||
{
|
||||
Inode *inode = (Inode *)_node;
|
||||
Inode *inode = (Inode *)_node->private_node;
|
||||
|
||||
TRACE(("pipefs_open(): node = %p, openMode = %d\n", inode, openMode));
|
||||
|
||||
@ -1281,11 +1293,11 @@ pipefs_open(fs_volume _volume, fs_vnode _node, int openMode,
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_close(fs_volume _volume, fs_vnode _node, fs_cookie _cookie)
|
||||
pipefs_close(fs_volume *_volume, fs_vnode *_node, void *_cookie)
|
||||
{
|
||||
file_cookie *cookie = (file_cookie *)_cookie;
|
||||
Volume *volume = (Volume *)_volume;
|
||||
Inode *inode = (Inode *)_node;
|
||||
Volume *volume = (Volume *)_volume->private_volume;
|
||||
Inode *inode = (Inode *)_node->private_node;
|
||||
|
||||
TRACE(("pipefs_close: entry vnode %p, cookie %p\n", _node, _cookie));
|
||||
|
||||
@ -1300,7 +1312,7 @@ pipefs_close(fs_volume _volume, fs_vnode _node, fs_cookie _cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_free_cookie(fs_volume _volume, fs_vnode _node, fs_cookie _cookie)
|
||||
pipefs_free_cookie(fs_volume *_volume, fs_vnode *_node, void *_cookie)
|
||||
{
|
||||
file_cookie *cookie = (file_cookie *)_cookie;
|
||||
|
||||
@ -1313,21 +1325,23 @@ pipefs_free_cookie(fs_volume _volume, fs_vnode _node, fs_cookie _cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_fsync(fs_volume _volume, fs_vnode _v)
|
||||
pipefs_fsync(fs_volume *_volume, fs_vnode *_v)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_read(fs_volume _volume, fs_vnode _node, fs_cookie _cookie,
|
||||
pipefs_read(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
||||
off_t /*pos*/, void *buffer, size_t *_length)
|
||||
{
|
||||
file_cookie *cookie = (file_cookie *)_cookie;
|
||||
Inode *inode = (Inode *)_node;
|
||||
Inode *inode = (Inode *)_node->private_node;
|
||||
|
||||
TRACE(("pipefs_read(vnode = %p, cookie = %p, length = %lu, mode = %d)\n",
|
||||
_node, cookie, *_length, cookie->open_mode));
|
||||
inode, cookie, *_length, cookie->open_mode));
|
||||
//dprintf("[%ld] pipefs_read(vnode = %p, cookie = %p, length = %lu, mode = %d)\n",
|
||||
//find_thread(NULL), inode, cookie, *_length, cookie->open_mode);
|
||||
|
||||
if (!S_ISFIFO(inode->Type()))
|
||||
return B_IS_A_DIRECTORY;
|
||||
@ -1355,6 +1369,10 @@ pipefs_read(fs_volume _volume, fs_vnode _node, fs_cookie _cookie,
|
||||
size_t length = *_length;
|
||||
status_t status = inode->ReadDataFromBuffer(buffer, &length,
|
||||
(cookie->open_mode & O_NONBLOCK) != 0, request);
|
||||
//if (status != B_OK) {
|
||||
//dprintf("[%ld] pipefs_read(): ReadDataFromBuffer() returned: 0x%lx\n",
|
||||
//find_thread(NULL), status);
|
||||
//}
|
||||
|
||||
inode->RemoveReadRequest(request);
|
||||
inode->NotifyReadDone();
|
||||
@ -1368,11 +1386,11 @@ pipefs_read(fs_volume _volume, fs_vnode _node, fs_cookie _cookie,
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_write(fs_volume _volume, fs_vnode _node, fs_cookie _cookie,
|
||||
pipefs_write(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
||||
off_t /*pos*/, const void *buffer, size_t *_length)
|
||||
{
|
||||
file_cookie *cookie = (file_cookie *)_cookie;
|
||||
Inode *inode = (Inode *)_node;
|
||||
Inode *inode = (Inode *)_node->private_node;
|
||||
|
||||
TRACE(("pipefs_write(vnode = %p, cookie = %p, length = %lu)\n",
|
||||
_node, cookie, *_length));
|
||||
@ -1402,7 +1420,7 @@ pipefs_write(fs_volume _volume, fs_vnode _node, fs_cookie _cookie,
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_create_dir(fs_volume _volume, fs_vnode _dir, const char *name,
|
||||
pipefs_create_dir(fs_volume *_volume, fs_vnode *_dir, const char *name,
|
||||
int perms, ino_t *_newID)
|
||||
{
|
||||
TRACE(("pipefs: create directory \"%s\" requested...\n", name));
|
||||
@ -1411,16 +1429,16 @@ pipefs_create_dir(fs_volume _volume, fs_vnode _dir, const char *name,
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_remove_dir(fs_volume _volume, fs_vnode _dir, const char *name)
|
||||
pipefs_remove_dir(fs_volume *_volume, fs_vnode *_dir, const char *name)
|
||||
{
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_open_dir(fs_volume _volume, fs_vnode _node, fs_cookie *_cookie)
|
||||
pipefs_open_dir(fs_volume *_volume, fs_vnode *_node, void **_cookie)
|
||||
{
|
||||
Volume *volume = (Volume *)_volume;
|
||||
Volume *volume = (Volume *)_volume->private_volume;
|
||||
|
||||
TRACE(("pipefs_open_dir(): vnode = %p\n", _node));
|
||||
|
||||
@ -1450,17 +1468,17 @@ pipefs_open_dir(fs_volume _volume, fs_vnode _node, fs_cookie *_cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_read_dir(fs_volume _volume, fs_vnode _node, fs_cookie _cookie,
|
||||
pipefs_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
||||
struct dirent *dirent, size_t bufferSize, uint32 *_num)
|
||||
{
|
||||
Volume *volume = (Volume *)_volume;
|
||||
Inode *inode = (Inode *)_node;
|
||||
Volume *volume = (Volume *)_volume->private_volume;
|
||||
Inode *inode = (Inode *)_node->private_node;
|
||||
status_t status = 0;
|
||||
|
||||
TRACE(("pipefs_read_dir: vnode %p, cookie %p, buffer = %p, bufferSize = %ld, num = %p\n",
|
||||
_node, _cookie, dirent, bufferSize,_num));
|
||||
|
||||
if (_node != &volume->RootNode())
|
||||
if (inode != &volume->RootNode())
|
||||
return B_BAD_VALUE;
|
||||
|
||||
volume->Lock();
|
||||
@ -1525,9 +1543,9 @@ err:
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_rewind_dir(fs_volume _volume, fs_vnode _vnode, fs_cookie _cookie)
|
||||
pipefs_rewind_dir(fs_volume *_volume, fs_vnode *_vnode, void *_cookie)
|
||||
{
|
||||
Volume *volume = (Volume *)_volume;
|
||||
Volume *volume = (Volume *)_volume->private_volume;
|
||||
volume->Lock();
|
||||
|
||||
dir_cookie *cookie = (dir_cookie *)_cookie;
|
||||
@ -1540,7 +1558,7 @@ pipefs_rewind_dir(fs_volume _volume, fs_vnode _vnode, fs_cookie _cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_close_dir(fs_volume _volume, fs_vnode _node, fs_cookie _cookie)
|
||||
pipefs_close_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie)
|
||||
{
|
||||
TRACE(("pipefs_close: entry vnode %p, cookie %p\n", _node, _cookie));
|
||||
|
||||
@ -1549,10 +1567,10 @@ pipefs_close_dir(fs_volume _volume, fs_vnode _node, fs_cookie _cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_free_dir_cookie(fs_volume _volume, fs_vnode _vnode, fs_cookie _cookie)
|
||||
pipefs_free_dir_cookie(fs_volume *_volume, fs_vnode *_vnode, void *_cookie)
|
||||
{
|
||||
dir_cookie *cookie = (dir_cookie *)_cookie;
|
||||
Volume *volume = (Volume *)_volume;
|
||||
Volume *volume = (Volume *)_volume->private_volume;
|
||||
|
||||
TRACE(("pipefs_freecookie: entry vnode %p, cookie %p\n", _vnode, cookie));
|
||||
|
||||
@ -1566,7 +1584,7 @@ pipefs_free_dir_cookie(fs_volume _volume, fs_vnode _vnode, fs_cookie _cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_ioctl(fs_volume _volume, fs_vnode _vnode, fs_cookie _cookie, ulong op,
|
||||
pipefs_ioctl(fs_volume *_volume, fs_vnode *_vnode, void *_cookie, ulong op,
|
||||
void *buffer, size_t length)
|
||||
{
|
||||
TRACE(("pipefs_ioctl: vnode %p, cookie %p, op %ld, buf %p, len %ld\n",
|
||||
@ -1577,7 +1595,8 @@ pipefs_ioctl(fs_volume _volume, fs_vnode _vnode, fs_cookie _cookie, ulong op,
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_set_flags(fs_volume _volume, fs_vnode _vnode, fs_cookie _cookie, int flags)
|
||||
pipefs_set_flags(fs_volume *_volume, fs_vnode *_vnode, void *_cookie,
|
||||
int flags)
|
||||
{
|
||||
file_cookie *cookie = (file_cookie *)_cookie;
|
||||
|
||||
@ -1588,13 +1607,13 @@ pipefs_set_flags(fs_volume _volume, fs_vnode _vnode, fs_cookie _cookie, int flag
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_select(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, uint8 event,
|
||||
uint32 ref, selectsync *sync)
|
||||
pipefs_select(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
||||
uint8 event, uint32 ref, selectsync *sync)
|
||||
{
|
||||
file_cookie *cookie = (file_cookie *)_cookie;
|
||||
|
||||
TRACE(("pipefs_select(vnode = %p)\n", _node));
|
||||
Inode *inode = (Inode *)_node;
|
||||
Inode *inode = (Inode *)_node->private_node;
|
||||
if (!inode)
|
||||
return B_ERROR;
|
||||
|
||||
@ -1604,13 +1623,13 @@ pipefs_select(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, uint8 event,
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_deselect(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, uint8 event,
|
||||
selectsync *sync)
|
||||
pipefs_deselect(fs_volume *_volume, fs_vnode *_node, void *_cookie,
|
||||
uint8 event, selectsync *sync)
|
||||
{
|
||||
file_cookie *cookie = (file_cookie *)_cookie;
|
||||
|
||||
TRACE(("pipefs_deselect(vnode = %p)\n", _node));
|
||||
Inode *inode = (Inode *)_node;
|
||||
Inode *inode = (Inode *)_node->private_node;
|
||||
if (!inode)
|
||||
return B_ERROR;
|
||||
|
||||
@ -1620,14 +1639,14 @@ pipefs_deselect(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, uint8 event,
|
||||
|
||||
|
||||
static bool
|
||||
pipefs_can_page(fs_volume _volume, fs_vnode _v, fs_cookie cookie)
|
||||
pipefs_can_page(fs_volume *_volume, fs_vnode *_v, void *cookie)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_read_pages(fs_volume _volume, fs_vnode _v, fs_cookie cookie, off_t pos,
|
||||
pipefs_read_pages(fs_volume *_volume, fs_vnode *_v, void *cookie, off_t pos,
|
||||
const iovec *vecs, size_t count, size_t *_numBytes, bool reenter)
|
||||
{
|
||||
return B_NOT_ALLOWED;
|
||||
@ -1635,18 +1654,18 @@ pipefs_read_pages(fs_volume _volume, fs_vnode _v, fs_cookie cookie, off_t pos,
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_write_pages(fs_volume _volume, fs_vnode _v, fs_cookie cookie, off_t pos,
|
||||
const iovec *vecs, size_t count, size_t *_numBytes, bool reenter)
|
||||
pipefs_write_pages(fs_volume *_volume, fs_vnode *_v, void *cookie,
|
||||
off_t pos, const iovec *vecs, size_t count, size_t *_numBytes, bool reenter)
|
||||
{
|
||||
return B_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_unlink(fs_volume _volume, fs_vnode _dir, const char *name)
|
||||
pipefs_unlink(fs_volume *_volume, fs_vnode *_dir, const char *name)
|
||||
{
|
||||
Volume *volume = (Volume *)_volume;
|
||||
Inode *directory = (Inode *)_dir;
|
||||
Volume *volume = (Volume *)_volume->private_volume;
|
||||
Inode *directory = (Inode *)_dir->private_node;
|
||||
|
||||
TRACE(("pipefs_unlink: dir %p (0x%Lx), name '%s'\n",
|
||||
_dir, directory->ID(), name));
|
||||
@ -1656,10 +1675,10 @@ pipefs_unlink(fs_volume _volume, fs_vnode _dir, const char *name)
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_read_stat(fs_volume _volume, fs_vnode _node, struct stat *stat)
|
||||
pipefs_read_stat(fs_volume *_volume, fs_vnode *_node, struct stat *stat)
|
||||
{
|
||||
Volume *volume = (Volume *)_volume;
|
||||
Inode *inode = (Inode *)_node;
|
||||
Volume *volume = (Volume *)_volume->private_volume;
|
||||
Inode *inode = (Inode *)_node->private_node;
|
||||
|
||||
TRACE(("pipefs_read_stat: vnode %p (0x%Lx), stat %p\n",
|
||||
inode, inode->ID(), stat));
|
||||
@ -1687,11 +1706,11 @@ pipefs_read_stat(fs_volume _volume, fs_vnode _node, struct stat *stat)
|
||||
|
||||
|
||||
static status_t
|
||||
pipefs_write_stat(fs_volume _volume, fs_vnode _node, const struct stat *stat,
|
||||
pipefs_write_stat(fs_volume *_volume, fs_vnode *_node, const struct stat *stat,
|
||||
uint32 statMask)
|
||||
{
|
||||
Volume *volume = (Volume *)_volume;
|
||||
Inode *inode = (Inode *)_node;
|
||||
Volume *volume = (Volume *)_volume->private_volume;
|
||||
Inode *inode = (Inode *)_node->private_node;
|
||||
|
||||
TRACE(("pipefs_write_stat: vnode %p (0x%Lx), stat %p\n",
|
||||
inode, inode->ID(), stat));
|
||||
@ -1739,35 +1758,22 @@ pipefs_std_ops(int32 op, ...)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pipefs
|
||||
|
||||
using namespace pipefs;
|
||||
|
||||
file_system_module_info gPipeFileSystem = {
|
||||
{
|
||||
"file_systems/pipefs" B_CURRENT_FS_API_VERSION,
|
||||
0,
|
||||
pipefs_std_ops,
|
||||
},
|
||||
|
||||
"Pipe File System",
|
||||
0, // DDM flags
|
||||
|
||||
NULL, // identify_partition()
|
||||
NULL, // scan_partition()
|
||||
NULL, // free_identify_partition_cookie()
|
||||
NULL, // free_partition_content_cookie()
|
||||
|
||||
&pipefs_mount,
|
||||
fs_volume_ops kVolumeOps = {
|
||||
&pipefs_unmount,
|
||||
NULL,
|
||||
NULL,
|
||||
&pipefs_sync,
|
||||
&pipefs_get_vnode,
|
||||
|
||||
// the other operations are not supported (indices, queries)
|
||||
NULL,
|
||||
};
|
||||
|
||||
fs_vnode_ops kVnodeOps = {
|
||||
&pipefs_lookup,
|
||||
&pipefs_get_vnode_name,
|
||||
|
||||
&pipefs_get_vnode,
|
||||
&pipefs_put_vnode,
|
||||
&pipefs_remove_vnode,
|
||||
|
||||
@ -1788,7 +1794,7 @@ file_system_module_info gPipeFileSystem = {
|
||||
NULL, // fs_symlink()
|
||||
NULL, // fs_link()
|
||||
&pipefs_unlink,
|
||||
NULL, // fs_rename()
|
||||
NULL, // rename()
|
||||
|
||||
NULL, // fs_access()
|
||||
&pipefs_read_stat,
|
||||
@ -1811,7 +1817,287 @@ file_system_module_info gPipeFileSystem = {
|
||||
&pipefs_read_dir,
|
||||
&pipefs_rewind_dir,
|
||||
|
||||
// the other operations are not supported (attributes, indices, queries)
|
||||
// the other operations are not supported (attributes)
|
||||
NULL,
|
||||
};
|
||||
|
||||
} // namespace pipefs
|
||||
|
||||
using namespace pipefs;
|
||||
|
||||
file_system_module_info gPipeFileSystem = {
|
||||
{
|
||||
"file_systems/pipefs" B_CURRENT_FS_API_VERSION,
|
||||
0,
|
||||
pipefs_std_ops,
|
||||
},
|
||||
|
||||
"Pipe File System",
|
||||
0, // DDM flags
|
||||
|
||||
NULL, // identify_partition()
|
||||
NULL, // scan_partition()
|
||||
NULL, // free_identify_partition_cookie()
|
||||
NULL, // free_partition_content_cookie()
|
||||
|
||||
&pipefs_mount,
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - FIFO
|
||||
|
||||
|
||||
class FIFOInode : public Inode {
|
||||
public:
|
||||
FIFOInode(fs_vnode* vnode)
|
||||
:
|
||||
Inode(-1, NULL, "", S_IFIFO),
|
||||
fSuperVnode(*vnode)
|
||||
{
|
||||
}
|
||||
|
||||
fs_vnode* SuperVnode() { return &fSuperVnode; }
|
||||
|
||||
private:
|
||||
fs_vnode fSuperVnode;
|
||||
};
|
||||
|
||||
|
||||
static status_t
|
||||
fifo_put_vnode(fs_volume *volume, fs_vnode *vnode, bool reenter)
|
||||
{
|
||||
FIFOInode* fifo = (FIFOInode*)vnode->private_node;
|
||||
fs_vnode* superVnode = fifo->SuperVnode();
|
||||
dprintf("[%ld] fifo_put_vnode(%p (%p), %p (%p), %d)\n", find_thread(NULL),
|
||||
volume, volume->private_volume, vnode, fifo, reenter);
|
||||
|
||||
status_t error = B_OK;
|
||||
if (superVnode->ops->put_vnode != NULL)
|
||||
error = superVnode->ops->put_vnode(volume, superVnode, reenter);
|
||||
|
||||
delete fifo;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
fifo_remove_vnode(fs_volume *volume, fs_vnode *vnode, bool reenter)
|
||||
{
|
||||
FIFOInode* fifo = (FIFOInode*)vnode->private_node;
|
||||
fs_vnode* superVnode = fifo->SuperVnode();
|
||||
dprintf("[%ld] fifo_remove_vnode(%p (%p), %p (%p), %d)\n", find_thread(NULL),
|
||||
volume, volume->private_volume, vnode, fifo, reenter);
|
||||
|
||||
status_t error = B_OK;
|
||||
if (superVnode->ops->remove_vnode != NULL)
|
||||
error = superVnode->ops->remove_vnode(volume, superVnode, reenter);
|
||||
|
||||
delete fifo;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
fifo_read_stat(fs_volume *volume, fs_vnode *vnode, struct ::stat *st)
|
||||
{
|
||||
FIFOInode* fifo = (FIFOInode*)vnode->private_node;
|
||||
fs_vnode* superVnode = fifo->SuperVnode();
|
||||
dprintf("[%ld] fifo_read_stat(%p (%p), %p (%p), %p)\n", find_thread(NULL),
|
||||
volume, volume->private_volume, vnode, fifo, st);
|
||||
|
||||
if (superVnode->ops->read_stat == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t error = superVnode->ops->read_stat(volume, superVnode, st);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
|
||||
BenaphoreLocker locker(fifo->RequestLock());
|
||||
|
||||
st->st_size = fifo->BytesAvailable();
|
||||
// st->st_mode = inode->Type();
|
||||
|
||||
// st->st_nlink = 1;
|
||||
st->st_blksize = 4096;
|
||||
|
||||
// st->st_uid = inode->UserID();
|
||||
// st->st_gid = inode->GroupID();
|
||||
|
||||
// TODO: Just pass the changes to our modification time on to the super node.
|
||||
st->st_atime = time(NULL);
|
||||
st->st_mtime = st->st_ctime = fifo->ModificationTime();
|
||||
// st->st_crtime = inode->CreationTime();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
fifo_write_stat(fs_volume *volume, fs_vnode *vnode, const struct ::stat *st,
|
||||
uint32 statMask)
|
||||
{
|
||||
// we cannot change the size of anything
|
||||
if (statMask & B_STAT_SIZE)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
FIFOInode* fifo = (FIFOInode*)vnode->private_node;
|
||||
fs_vnode* superVnode = fifo->SuperVnode();
|
||||
dprintf("[%ld] fifo_write_stat(%p (%p), %p (%p), %p, 0x%lx)\n",
|
||||
find_thread(NULL), volume, volume->private_volume, vnode, fifo, st, statMask);
|
||||
|
||||
if (superVnode->ops->write_stat == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t error = superVnode->ops->write_stat(volume, superVnode, st,
|
||||
statMask);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
fifo_open(fs_volume *volume, fs_vnode *vnode, int openMode,
|
||||
void **_cookie)
|
||||
{
|
||||
file_cookie *cookie = (file_cookie *)_cookie;
|
||||
FIFOInode* fifo = (FIFOInode*)vnode->private_node;
|
||||
dprintf("[%ld] fifo_open(%p (%p), %p (%p), 0x%x, %p)\n",
|
||||
find_thread(NULL), volume, volume->private_volume, vnode, fifo, openMode, _cookie);
|
||||
|
||||
return pipefs_open(volume, vnode, openMode, _cookie);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
fifo_close(fs_volume *volume, fs_vnode *vnode, void *_cookie)
|
||||
{
|
||||
file_cookie *cookie = (file_cookie *)_cookie;
|
||||
FIFOInode* fifo = (FIFOInode*)vnode->private_node;
|
||||
dprintf("[%ld] fifo_close(%p (%p), %p (%p), %p)\n",
|
||||
find_thread(NULL), volume, volume->private_volume, vnode, fifo, _cookie);
|
||||
|
||||
fifo->Close(cookie->open_mode);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
fifo_get_super_vnode(fs_volume *volume, fs_vnode *vnode, fs_volume *superVolume,
|
||||
fs_vnode *_superVnode)
|
||||
{
|
||||
FIFOInode* fifo = (FIFOInode*)vnode->private_node;
|
||||
fs_vnode* superVnode = fifo->SuperVnode();
|
||||
dprintf("[%ld] fifo_get_super_vnode(%p (%p), %p (%p), %p, %p)\n",
|
||||
find_thread(NULL), volume, volume->private_volume, vnode, fifo, superVolume,
|
||||
_superVnode);
|
||||
|
||||
if (superVnode->ops->get_super_vnode != NULL) {
|
||||
return superVnode->ops->get_super_vnode(volume, superVnode, superVolume,
|
||||
_superVnode);
|
||||
}
|
||||
|
||||
*_superVnode = *superVnode;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static fs_vnode_ops sFIFOVnodeOps = {
|
||||
NULL, // lookup()
|
||||
NULL, // get_vnode_name()
|
||||
// TODO: This is suboptimal! We'd need to forward the
|
||||
// super node's hook, if it has got one.
|
||||
|
||||
&fifo_put_vnode,
|
||||
&fifo_remove_vnode,
|
||||
|
||||
&pipefs_can_page,
|
||||
&pipefs_read_pages,
|
||||
&pipefs_write_pages,
|
||||
|
||||
NULL, // get_file_map()
|
||||
|
||||
/* common */
|
||||
&pipefs_ioctl,
|
||||
&pipefs_set_flags,
|
||||
&pipefs_select,
|
||||
&pipefs_deselect,
|
||||
&pipefs_fsync,
|
||||
|
||||
NULL, // fs_read_link()
|
||||
NULL, // fs_symlink()
|
||||
NULL, // fs_link()
|
||||
NULL, // unlink()
|
||||
NULL, // rename()
|
||||
|
||||
NULL, // fs_access()
|
||||
&fifo_read_stat,
|
||||
&fifo_write_stat,
|
||||
|
||||
/* file */
|
||||
NULL, // &create()
|
||||
&pipefs_open,
|
||||
&fifo_close,
|
||||
&pipefs_free_cookie,
|
||||
&pipefs_read,
|
||||
&pipefs_write,
|
||||
|
||||
/* directory */
|
||||
NULL, // &pipefs_create_dir,
|
||||
NULL, // &pipefs_remove_dir,
|
||||
NULL, // &pipefs_open_dir,
|
||||
NULL, // &pipefs_close_dir,
|
||||
NULL, // &pipefs_free_dir_cookie,
|
||||
NULL, // &pipefs_read_dir,
|
||||
NULL, // &pipefs_rewind_dir,
|
||||
|
||||
/* attribute directory operations */
|
||||
NULL, // open_attr_dir
|
||||
NULL, // close_attr_dir
|
||||
NULL, // free_attr_dir_cookie
|
||||
NULL, // read_attr_dir
|
||||
NULL, // rewind_attr_dir
|
||||
|
||||
/* attribute operations */
|
||||
NULL, // create_attr
|
||||
NULL, // open_attr
|
||||
NULL, // close_attr
|
||||
NULL, // free_attr_cookie
|
||||
NULL, // read_attr
|
||||
NULL, // write_attr
|
||||
|
||||
NULL, // read_attr_stat
|
||||
NULL, // write_attr_stat
|
||||
NULL, // rename_attr
|
||||
NULL, // remove_attr
|
||||
|
||||
/* support for node and FS layers */
|
||||
NULL, // create_special_node
|
||||
&fifo_get_super_vnode,
|
||||
};
|
||||
|
||||
|
||||
status_t
|
||||
create_fifo_vnode(fs_volume* superVolume, fs_vnode* vnode)
|
||||
{
|
||||
FIFOInode *fifo = new(std::nothrow) FIFOInode(vnode);
|
||||
if (fifo == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t status = fifo->InitCheck();
|
||||
if (status != B_OK) {
|
||||
delete fifo;
|
||||
return status;
|
||||
}
|
||||
|
||||
vnode->private_node = fifo;
|
||||
vnode->ops = &sFIFOVnodeOps;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
# include <debug.h>
|
||||
# include <khash.h>
|
||||
# include <lock.h>
|
||||
# include <util/AutoLock.h>
|
||||
# include <vm.h>
|
||||
|
||||
# include <NodeMonitor.h>
|
||||
@ -70,6 +71,7 @@ struct rootfs_vnode {
|
||||
};
|
||||
|
||||
struct rootfs {
|
||||
fs_volume *volume;
|
||||
dev_t id;
|
||||
mutex lock;
|
||||
ino_t next_vnode_id;
|
||||
@ -92,6 +94,12 @@ enum {
|
||||
ITERATION_STATE_BEGIN = ITERATION_STATE_DOT,
|
||||
};
|
||||
|
||||
// extern and in a private namespace only to make forward declaration possible
|
||||
namespace {
|
||||
extern fs_volume_ops sVolumeOps;
|
||||
extern fs_vnode_ops sVnodeOps;
|
||||
}
|
||||
|
||||
#define ROOTFS_HASH_SIZE 16
|
||||
|
||||
|
||||
@ -273,7 +281,10 @@ static status_t
|
||||
remove_node(struct rootfs *fs, struct rootfs_vnode *directory, struct rootfs_vnode *vnode)
|
||||
{
|
||||
// schedule this vnode to be removed when it's ref goes to zero
|
||||
status_t status = remove_vnode(fs->id, vnode->id);
|
||||
// TODO: This can fail, if the caller doesn't have a reference to the node
|
||||
// in question. And some code paths don't guarantee that (rootfs_remove_dir()
|
||||
// for example).
|
||||
status_t status = remove_vnode(fs->volume, vnode->id);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
@ -318,8 +329,8 @@ err:
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_mount(dev_t id, const char *device, uint32 flags, const char *args,
|
||||
fs_volume *_fs, ino_t *root_vnid)
|
||||
rootfs_mount(fs_volume *volume, const char *device, uint32 flags,
|
||||
const char *args, ino_t *root_vnid)
|
||||
{
|
||||
struct rootfs *fs;
|
||||
struct rootfs_vnode *vnode;
|
||||
@ -331,7 +342,10 @@ rootfs_mount(dev_t id, const char *device, uint32 flags, const char *args,
|
||||
if (fs == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
fs->id = id;
|
||||
volume->private_volume = fs;
|
||||
volume->ops = &sVolumeOps;
|
||||
fs->volume = volume;
|
||||
fs->id = volume->id;
|
||||
fs->next_vnode_id = 1;
|
||||
|
||||
err = mutex_init(&fs->lock, "rootfs_mutex");
|
||||
@ -355,10 +369,9 @@ rootfs_mount(dev_t id, const char *device, uint32 flags, const char *args,
|
||||
|
||||
fs->root_vnode = vnode;
|
||||
hash_insert(fs->vnode_list_hash, vnode);
|
||||
publish_vnode(id, vnode->id, vnode);
|
||||
publish_vnode(volume, vnode->id, vnode, &sVnodeOps, vnode->stream.type, 0);
|
||||
|
||||
*root_vnid = vnode->id;
|
||||
*_fs = fs;
|
||||
|
||||
return B_OK;
|
||||
|
||||
@ -374,16 +387,16 @@ err1:
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_unmount(fs_volume _fs)
|
||||
rootfs_unmount(fs_volume *_volume)
|
||||
{
|
||||
struct rootfs *fs = (struct rootfs *)_fs;
|
||||
struct rootfs *fs = (struct rootfs *)_volume->private_volume;
|
||||
struct rootfs_vnode *v;
|
||||
struct hash_iterator i;
|
||||
|
||||
TRACE(("rootfs_unmount: entry fs = %p\n", fs));
|
||||
|
||||
// release the reference to the root
|
||||
put_vnode(fs->id, fs->root_vnode->id);
|
||||
put_vnode(fs->volume, fs->root_vnode->id);
|
||||
|
||||
// delete all of the vnodes
|
||||
hash_open(fs->vnode_list_hash, &i);
|
||||
@ -401,7 +414,7 @@ rootfs_unmount(fs_volume _fs)
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_sync(fs_volume fs)
|
||||
rootfs_sync(fs_volume *_volume)
|
||||
{
|
||||
TRACE(("rootfs_sync: entry\n"));
|
||||
|
||||
@ -410,10 +423,10 @@ rootfs_sync(fs_volume fs)
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_lookup(fs_volume _fs, fs_vnode _dir, const char *name, ino_t *_id, int *_type)
|
||||
rootfs_lookup(fs_volume *_volume, fs_vnode *_dir, const char *name, ino_t *_id)
|
||||
{
|
||||
struct rootfs *fs = (struct rootfs *)_fs;
|
||||
struct rootfs_vnode *dir = (struct rootfs_vnode *)_dir;
|
||||
struct rootfs *fs = (struct rootfs *)_volume->private_volume;
|
||||
struct rootfs_vnode *dir = (struct rootfs_vnode *)_dir->private_node;
|
||||
struct rootfs_vnode *vnode,*vdummy;
|
||||
status_t status;
|
||||
|
||||
@ -430,12 +443,11 @@ rootfs_lookup(fs_volume _fs, fs_vnode _dir, const char *name, ino_t *_id, int *_
|
||||
goto err;
|
||||
}
|
||||
|
||||
status = get_vnode(fs->id, vnode->id, (fs_vnode *)&vdummy);
|
||||
status = get_vnode(fs->volume, vnode->id, (void**)&vdummy);
|
||||
if (status < B_OK)
|
||||
goto err;
|
||||
|
||||
*_id = vnode->id;
|
||||
*_type = vnode->stream.type;
|
||||
|
||||
err:
|
||||
mutex_unlock(&fs->lock);
|
||||
@ -445,9 +457,10 @@ err:
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_get_vnode_name(fs_volume _fs, fs_vnode _vnode, char *buffer, size_t bufferSize)
|
||||
rootfs_get_vnode_name(fs_volume *_volume, fs_vnode *_vnode, char *buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_vnode;
|
||||
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_vnode->private_node;
|
||||
|
||||
TRACE(("rootfs_get_vnode_name: vnode = %p (name = %s)\n", vnode, vnode->name));
|
||||
|
||||
@ -457,9 +470,10 @@ rootfs_get_vnode_name(fs_volume _fs, fs_vnode _vnode, char *buffer, size_t buffe
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_get_vnode(fs_volume _fs, ino_t id, fs_vnode *_vnode, bool reenter)
|
||||
rootfs_get_vnode(fs_volume *_volume, ino_t id, fs_vnode *_vnode, int *_type,
|
||||
uint32 *_flags, bool reenter)
|
||||
{
|
||||
struct rootfs *fs = (struct rootfs *)_fs;
|
||||
struct rootfs *fs = (struct rootfs *)_volume->private_volume;
|
||||
struct rootfs_vnode *vnode;
|
||||
|
||||
TRACE(("rootfs_getvnode: asking for vnode %Ld, r %d\n", id, reenter));
|
||||
@ -477,16 +491,20 @@ rootfs_get_vnode(fs_volume _fs, ino_t id, fs_vnode *_vnode, bool reenter)
|
||||
if (vnode == NULL)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
*_vnode = vnode;
|
||||
_vnode->private_node = vnode;
|
||||
_vnode->ops = &sVnodeOps;
|
||||
*_type = vnode->stream.type;
|
||||
*_flags = 0;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_put_vnode(fs_volume _fs, fs_vnode _vnode, bool reenter)
|
||||
rootfs_put_vnode(fs_volume *_volume, fs_vnode *_vnode, bool reenter)
|
||||
{
|
||||
#ifdef TRACE_ROOTFS
|
||||
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_vnode;
|
||||
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_vnode->private_node;
|
||||
|
||||
TRACE(("rootfs_putvnode: entry on vnode 0x%Lx, r %d\n", vnode->id, reenter));
|
||||
#endif
|
||||
@ -495,10 +513,10 @@ rootfs_put_vnode(fs_volume _fs, fs_vnode _vnode, bool reenter)
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_remove_vnode(fs_volume _fs, fs_vnode _vnode, bool reenter)
|
||||
rootfs_remove_vnode(fs_volume *_volume, fs_vnode *_vnode, bool reenter)
|
||||
{
|
||||
struct rootfs *fs = (struct rootfs *)_fs;
|
||||
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_vnode;
|
||||
struct rootfs *fs = (struct rootfs *)_volume->private_volume;
|
||||
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_vnode->private_node;
|
||||
|
||||
TRACE(("rootfs_remove_vnode: remove %p (0x%Lx), r %d\n", vnode, vnode->id, reenter));
|
||||
|
||||
@ -520,15 +538,15 @@ rootfs_remove_vnode(fs_volume _fs, fs_vnode _vnode, bool reenter)
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_create(fs_volume _fs, fs_vnode _dir, const char *name, int omode,
|
||||
int perms, fs_cookie *_cookie, ino_t *new_vnid)
|
||||
rootfs_create(fs_volume *_volume, fs_vnode *_dir, const char *name, int omode,
|
||||
int perms, void **_cookie, ino_t *_newID)
|
||||
{
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_open(fs_volume _fs, fs_vnode _v, int oflags, fs_cookie *_cookie)
|
||||
rootfs_open(fs_volume *_volume, fs_vnode *_v, int oflags, void **_cookie)
|
||||
{
|
||||
// allow to open the file, but it can't be done anything with it
|
||||
|
||||
@ -538,11 +556,11 @@ rootfs_open(fs_volume _fs, fs_vnode _v, int oflags, fs_cookie *_cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_close(fs_volume _fs, fs_vnode _v, fs_cookie _cookie)
|
||||
rootfs_close(fs_volume *_volume, fs_vnode *_v, void *_cookie)
|
||||
{
|
||||
#ifdef TRACE_ROOTFS
|
||||
struct rootfs_vnode *v = _v;
|
||||
struct rootfs_cookie *cookie = _cookie;
|
||||
struct rootfs_vnode *v = _v->private_node;
|
||||
struct rootvoid **cookie = _cookie;
|
||||
|
||||
TRACE(("rootfs_close: entry vnode %p, cookie %p\n", v, cookie));
|
||||
#endif
|
||||
@ -551,21 +569,21 @@ rootfs_close(fs_volume _fs, fs_vnode _v, fs_cookie _cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_free_cookie(fs_volume _fs, fs_vnode _v, fs_cookie _cookie)
|
||||
rootfs_free_cookie(fs_volume *_volume, fs_vnode *_v, void *_cookie)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_fsync(fs_volume _fs, fs_vnode _v)
|
||||
rootfs_fsync(fs_volume *_volume, fs_vnode *_v)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_read(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie,
|
||||
rootfs_read(fs_volume *_volume, fs_vnode *_vnode, void *_cookie,
|
||||
off_t pos, void *buffer, size_t *_length)
|
||||
{
|
||||
return EINVAL;
|
||||
@ -573,7 +591,7 @@ rootfs_read(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie,
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_write(fs_volume fs, fs_vnode vnode, fs_cookie cookie,
|
||||
rootfs_write(fs_volume *_volume, fs_vnode *vnode, void *cookie,
|
||||
off_t pos, const void *buffer, size_t *_length)
|
||||
{
|
||||
TRACE(("rootfs_write: vnode %p, cookie %p, pos 0x%Lx , len 0x%lx\n",
|
||||
@ -584,11 +602,11 @@ rootfs_write(fs_volume fs, fs_vnode vnode, fs_cookie cookie,
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_create_dir(fs_volume _fs, fs_vnode _dir, const char *name, int mode,
|
||||
ino_t *_newID)
|
||||
rootfs_create_dir(fs_volume *_volume, fs_vnode *_dir, const char *name,
|
||||
int mode, ino_t *_newID)
|
||||
{
|
||||
struct rootfs *fs = (rootfs*)_fs;
|
||||
struct rootfs_vnode *dir = (rootfs_vnode*)_dir;
|
||||
struct rootfs *fs = (rootfs*)_volume->private_volume;
|
||||
struct rootfs_vnode *dir = (rootfs_vnode*)_dir->private_node;
|
||||
struct rootfs_vnode *vnode;
|
||||
status_t status = 0;
|
||||
|
||||
@ -626,10 +644,10 @@ err:
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_remove_dir(fs_volume _fs, fs_vnode _dir, const char *name)
|
||||
rootfs_remove_dir(fs_volume *_volume, fs_vnode *_dir, const char *name)
|
||||
{
|
||||
struct rootfs *fs = (rootfs*)_fs;
|
||||
struct rootfs_vnode *dir = (rootfs_vnode*)_dir;
|
||||
struct rootfs *fs = (rootfs*)_volume->private_volume;
|
||||
struct rootfs_vnode *dir = (rootfs_vnode*)_dir->private_node;
|
||||
|
||||
TRACE(("rootfs_remove_dir: dir %p (0x%Lx), name '%s'\n", dir, dir->id, name));
|
||||
|
||||
@ -638,10 +656,10 @@ rootfs_remove_dir(fs_volume _fs, fs_vnode _dir, const char *name)
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_open_dir(fs_volume _fs, fs_vnode _v, fs_cookie *_cookie)
|
||||
rootfs_open_dir(fs_volume *_volume, fs_vnode *_v, void **_cookie)
|
||||
{
|
||||
struct rootfs *fs = (struct rootfs *)_fs;
|
||||
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_v;
|
||||
struct rootfs *fs = (struct rootfs *)_volume->private_volume;
|
||||
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_v->private_node;
|
||||
struct rootfs_dir_cookie *cookie;
|
||||
|
||||
TRACE(("rootfs_open: vnode %p\n", vnode));
|
||||
@ -668,11 +686,11 @@ rootfs_open_dir(fs_volume _fs, fs_vnode _v, fs_cookie *_cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_free_dir_cookie(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
|
||||
rootfs_free_dir_cookie(fs_volume *_volume, fs_vnode *_vnode, void *_cookie)
|
||||
{
|
||||
struct rootfs_dir_cookie *cookie = (rootfs_dir_cookie*)_cookie;
|
||||
struct rootfs_vnode *vnode = (rootfs_vnode*)_vnode;
|
||||
struct rootfs *fs = (rootfs*)_fs;
|
||||
struct rootfs_vnode *vnode = (rootfs_vnode*)_vnode->private_node;
|
||||
struct rootfs *fs = (rootfs*)_volume->private_volume;
|
||||
|
||||
mutex_lock(&fs->lock);
|
||||
list_remove_item(&vnode->stream.dir.cookies, cookie);
|
||||
@ -684,11 +702,12 @@ rootfs_free_dir_cookie(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_read_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, struct dirent *dirent, size_t bufferSize, uint32 *_num)
|
||||
rootfs_read_dir(fs_volume *_volume, fs_vnode *_vnode, void *_cookie,
|
||||
struct dirent *dirent, size_t bufferSize, uint32 *_num)
|
||||
{
|
||||
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_vnode;
|
||||
struct rootfs_vnode *vnode = (struct rootfs_vnode *)_vnode->private_node;
|
||||
struct rootfs_dir_cookie *cookie = (rootfs_dir_cookie*)_cookie;
|
||||
struct rootfs *fs = (rootfs*)_fs;
|
||||
struct rootfs *fs = (rootfs*)_volume->private_volume;
|
||||
status_t status = B_OK;
|
||||
struct rootfs_vnode *childNode = NULL;
|
||||
const char *name = NULL;
|
||||
@ -753,11 +772,11 @@ err:
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_rewind_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
|
||||
rootfs_rewind_dir(fs_volume *_volume, fs_vnode *_vnode, void *_cookie)
|
||||
{
|
||||
struct rootfs_dir_cookie *cookie = (rootfs_dir_cookie*)_cookie;
|
||||
struct rootfs_vnode *vnode = (rootfs_vnode*)_vnode;
|
||||
struct rootfs *fs = (rootfs*)_fs;
|
||||
struct rootfs_vnode *vnode = (rootfs_vnode*)_vnode->private_node;
|
||||
struct rootfs *fs = (rootfs*)_volume->private_volume;
|
||||
|
||||
mutex_lock(&fs->lock);
|
||||
|
||||
@ -770,7 +789,8 @@ rootfs_rewind_dir(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_ioctl(fs_volume _fs, fs_vnode _v, fs_cookie _cookie, ulong op, void *buf, size_t len)
|
||||
rootfs_ioctl(fs_volume *_volume, fs_vnode *_v, void *_cookie, ulong op,
|
||||
void *buf, size_t len)
|
||||
{
|
||||
TRACE(("rootfs_ioctl: vnode %p, cookie %p, op %ld, buf %p, len %ld\n", _v, _cookie, op, buf, len));
|
||||
|
||||
@ -779,14 +799,14 @@ rootfs_ioctl(fs_volume _fs, fs_vnode _v, fs_cookie _cookie, ulong op, void *buf,
|
||||
|
||||
|
||||
static bool
|
||||
rootfs_can_page(fs_volume _fs, fs_vnode _v, fs_cookie cookie)
|
||||
rootfs_can_page(fs_volume *_volume, fs_vnode *_v, void *cookie)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_read_pages(fs_volume _fs, fs_vnode _v, fs_cookie cookie, off_t pos,
|
||||
rootfs_read_pages(fs_volume *_volume, fs_vnode *_v, void *cookie, off_t pos,
|
||||
const iovec *vecs, size_t count, size_t *_numBytes, bool reenter)
|
||||
{
|
||||
return B_NOT_ALLOWED;
|
||||
@ -794,7 +814,7 @@ rootfs_read_pages(fs_volume _fs, fs_vnode _v, fs_cookie cookie, off_t pos,
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_write_pages(fs_volume _fs, fs_vnode _v, fs_cookie cookie, off_t pos,
|
||||
rootfs_write_pages(fs_volume *_volume, fs_vnode *_v, void *cookie, off_t pos,
|
||||
const iovec *vecs, size_t count, size_t *_numBytes, bool reenter)
|
||||
{
|
||||
return B_NOT_ALLOWED;
|
||||
@ -802,9 +822,10 @@ rootfs_write_pages(fs_volume _fs, fs_vnode _v, fs_cookie cookie, off_t pos,
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_read_link(fs_volume _fs, fs_vnode _link, char *buffer, size_t *_bufferSize)
|
||||
rootfs_read_link(fs_volume *_volume, fs_vnode *_link, char *buffer,
|
||||
size_t *_bufferSize)
|
||||
{
|
||||
struct rootfs_vnode *link = (rootfs_vnode*)_link;
|
||||
struct rootfs_vnode *link = (rootfs_vnode*)_link->private_node;
|
||||
|
||||
if (!S_ISLNK(link->stream.type))
|
||||
return B_BAD_VALUE;
|
||||
@ -818,10 +839,11 @@ rootfs_read_link(fs_volume _fs, fs_vnode _link, char *buffer, size_t *_bufferSiz
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_symlink(fs_volume _fs, fs_vnode _dir, const char *name, const char *path, int mode)
|
||||
rootfs_symlink(fs_volume *_volume, fs_vnode *_dir, const char *name,
|
||||
const char *path, int mode)
|
||||
{
|
||||
struct rootfs *fs = (rootfs*)_fs;
|
||||
struct rootfs_vnode *dir = (rootfs_vnode*)_dir;
|
||||
struct rootfs *fs = (rootfs*)_volume->private_volume;
|
||||
struct rootfs_vnode *dir = (rootfs_vnode*)_dir->private_node;
|
||||
struct rootfs_vnode *vnode;
|
||||
status_t status = B_OK;
|
||||
|
||||
@ -866,10 +888,10 @@ err:
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_unlink(fs_volume _fs, fs_vnode _dir, const char *name)
|
||||
rootfs_unlink(fs_volume *_volume, fs_vnode *_dir, const char *name)
|
||||
{
|
||||
struct rootfs *fs = (rootfs*)_fs;
|
||||
struct rootfs_vnode *dir = (rootfs_vnode*)_dir;
|
||||
struct rootfs *fs = (rootfs*)_volume->private_volume;
|
||||
struct rootfs_vnode *dir = (rootfs_vnode*)_dir->private_node;
|
||||
|
||||
TRACE(("rootfs_unlink: dir %p (0x%Lx), name '%s'\n", dir, dir->id, name));
|
||||
|
||||
@ -878,11 +900,12 @@ rootfs_unlink(fs_volume _fs, fs_vnode _dir, const char *name)
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_rename(fs_volume _fs, fs_vnode _fromDir, const char *fromName, fs_vnode _toDir, const char *toName)
|
||||
rootfs_rename(fs_volume *_volume, fs_vnode *_fromDir, const char *fromName,
|
||||
fs_vnode *_toDir, const char *toName)
|
||||
{
|
||||
struct rootfs *fs = (rootfs*)_fs;
|
||||
struct rootfs_vnode *fromDirectory = (rootfs_vnode*)_fromDir;
|
||||
struct rootfs_vnode *toDirectory = (rootfs_vnode*)_toDir;
|
||||
struct rootfs *fs = (rootfs*)_volume->private_volume;
|
||||
struct rootfs_vnode *fromDirectory = (rootfs_vnode*)_fromDir->private_node;
|
||||
struct rootfs_vnode *toDirectory = (rootfs_vnode*)_toDir->private_node;
|
||||
struct rootfs_vnode *vnode, *targetVnode, *parent;
|
||||
status_t status;
|
||||
char *nameBuffer = NULL;
|
||||
@ -961,10 +984,10 @@ err:
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_read_stat(fs_volume _fs, fs_vnode _v, struct stat *stat)
|
||||
rootfs_read_stat(fs_volume *_volume, fs_vnode *_v, struct stat *stat)
|
||||
{
|
||||
struct rootfs *fs = (rootfs*)_fs;
|
||||
struct rootfs_vnode *vnode = (rootfs_vnode*)_v;
|
||||
struct rootfs *fs = (rootfs*)_volume->private_volume;
|
||||
struct rootfs_vnode *vnode = (rootfs_vnode*)_v->private_node;
|
||||
|
||||
TRACE(("rootfs_read_stat: vnode %p (0x%Lx), stat %p\n", vnode, vnode->id, stat));
|
||||
|
||||
@ -992,10 +1015,11 @@ rootfs_read_stat(fs_volume _fs, fs_vnode _v, struct stat *stat)
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_write_stat(fs_volume _fs, fs_vnode _vnode, const struct stat *stat, uint32 statMask)
|
||||
rootfs_write_stat(fs_volume *_volume, fs_vnode *_vnode, const struct stat *stat,
|
||||
uint32 statMask)
|
||||
{
|
||||
struct rootfs *fs = (rootfs*)_fs;
|
||||
struct rootfs_vnode *vnode = (rootfs_vnode*)_vnode;
|
||||
struct rootfs *fs = (rootfs*)_volume->private_volume;
|
||||
struct rootfs_vnode *vnode = (rootfs_vnode*)_vnode->private_node;
|
||||
|
||||
TRACE(("rootfs_write_stat: vnode %p (0x%Lx), stat %p\n", vnode, vnode->id, stat));
|
||||
|
||||
@ -1025,6 +1049,50 @@ rootfs_write_stat(fs_volume _fs, fs_vnode _vnode, const struct stat *stat, uint3
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_create_special_node(fs_volume *_volume, fs_vnode *_dir, const char *name,
|
||||
fs_vnode *subVnode, mode_t mode, uint32 flags, fs_vnode *_superVnode,
|
||||
ino_t *_nodeID)
|
||||
{
|
||||
struct rootfs *fs = (rootfs*)_volume->private_volume;
|
||||
struct rootfs_vnode *dir = (rootfs_vnode*)_dir->private_node;
|
||||
struct rootfs_vnode *vnode;
|
||||
|
||||
MutexLocker _(fs->lock);
|
||||
|
||||
// TODO: Support (NULL, NULL) (dir, name)!
|
||||
vnode = rootfs_find_in_dir(dir, name);
|
||||
if (vnode != NULL)
|
||||
return B_FILE_EXISTS;
|
||||
|
||||
vnode = rootfs_create_vnode(fs, dir, name, mode);
|
||||
if (vnode == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
rootfs_insert_in_dir(fs, dir, vnode);
|
||||
hash_insert(fs->vnode_list_hash, vnode);
|
||||
|
||||
_superVnode->private_node = vnode;
|
||||
_superVnode->ops = &sVnodeOps;
|
||||
*_nodeID = vnode->id;
|
||||
|
||||
if (subVnode == NULL)
|
||||
subVnode = _superVnode;
|
||||
|
||||
status_t status = publish_vnode(fs->volume, vnode->id,
|
||||
subVnode->private_node, subVnode->ops, mode, flags);
|
||||
if (status != B_OK) {
|
||||
rootfs_remove_from_dir(fs, dir, vnode);
|
||||
rootfs_delete_vnode(fs, vnode, false);
|
||||
return status;
|
||||
}
|
||||
|
||||
notify_entry_created(fs->id, dir->id, name, vnode->id);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
rootfs_std_ops(int32 op, ...)
|
||||
{
|
||||
@ -1041,31 +1109,23 @@ rootfs_std_ops(int32 op, ...)
|
||||
}
|
||||
|
||||
|
||||
file_system_module_info gRootFileSystem = {
|
||||
{
|
||||
"file_systems/rootfs" B_CURRENT_FS_API_VERSION,
|
||||
0,
|
||||
rootfs_std_ops,
|
||||
},
|
||||
namespace {
|
||||
|
||||
"Root File System",
|
||||
0, // DDM flags
|
||||
|
||||
NULL, // identify_partition()
|
||||
NULL, // scan_partition()
|
||||
NULL, // free_identify_partition_cookie()
|
||||
NULL, // free_partition_content_cookie()
|
||||
|
||||
&rootfs_mount,
|
||||
fs_volume_ops sVolumeOps = {
|
||||
&rootfs_unmount,
|
||||
NULL,
|
||||
NULL,
|
||||
&rootfs_sync,
|
||||
&rootfs_get_vnode,
|
||||
|
||||
// the other operations are not supported (indices, queries)
|
||||
NULL,
|
||||
};
|
||||
|
||||
fs_vnode_ops sVnodeOps = {
|
||||
&rootfs_lookup,
|
||||
&rootfs_get_vnode_name,
|
||||
|
||||
&rootfs_get_vnode,
|
||||
&rootfs_put_vnode,
|
||||
&rootfs_remove_vnode,
|
||||
|
||||
@ -1109,7 +1169,48 @@ file_system_module_info gRootFileSystem = {
|
||||
&rootfs_read_dir,
|
||||
&rootfs_rewind_dir,
|
||||
|
||||
// the other operations are not supported (attributes, indices, queries)
|
||||
NULL,
|
||||
/* attribute directory operations */
|
||||
NULL, // open_attr_dir
|
||||
NULL, // close_attr_dir
|
||||
NULL, // free_attr_dir_cookie
|
||||
NULL, // read_attr_dir
|
||||
NULL, // rewind_attr_dir
|
||||
|
||||
/* attribute operations */
|
||||
NULL, // create_attr
|
||||
NULL, // open_attr
|
||||
NULL, // close_attr
|
||||
NULL, // free_attr_cookie
|
||||
NULL, // read_attr
|
||||
NULL, // write_attr
|
||||
|
||||
NULL, // read_attr_stat
|
||||
NULL, // write_attr_stat
|
||||
NULL, // rename_attr
|
||||
NULL, // remove_attr
|
||||
|
||||
/* support for node and FS layers */
|
||||
&rootfs_create_special_node,
|
||||
NULL, // get_super_vnode,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
file_system_module_info gRootFileSystem = {
|
||||
{
|
||||
"file_systems/rootfs" B_CURRENT_FS_API_VERSION,
|
||||
0,
|
||||
rootfs_std_ops,
|
||||
},
|
||||
|
||||
"Root File System",
|
||||
0, // DDM flags
|
||||
|
||||
NULL, // identify_partition()
|
||||
NULL, // scan_partition()
|
||||
NULL, // free_identify_partition_cookie()
|
||||
NULL, // free_partition_content_cookie()
|
||||
|
||||
&rootfs_mount,
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,7 @@
|
||||
int
|
||||
mkfifo(const char *path, mode_t mode)
|
||||
{
|
||||
// ToDo: implement me for real!
|
||||
RETURN_AND_SET_ERRNO(B_BAD_VALUE);
|
||||
status_t error = _kern_create_fifo(path, mode);
|
||||
|
||||
RETURN_AND_SET_ERRNO(error);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user