223 lines
7.6 KiB
C
223 lines
7.6 KiB
C
#pragma once
|
|
|
|
struct vfs_node;
|
|
struct vfs_filesys;
|
|
|
|
#define VO_FREAD 0x0001 /**< Open the file to read from it. */
|
|
#define VO_FWRITE 0x0002 /**< Open the file to write into it. */
|
|
#define VO_FBINARY 0x004 /**< Open the file in binary mode. */
|
|
|
|
#define VN_FREGFILE 0x1
|
|
#define VN_FDIR 0x2
|
|
#define VN_FCHARDEV 0x3
|
|
#define VN_FBLOCKDEV 0x4
|
|
|
|
/**
|
|
* \brief Virtual File System Operations
|
|
*
|
|
* A file system implementation will implement some of the hooks in this
|
|
* data structure. If the operating system receives a hook request on behalf
|
|
* of a specific node, it will call the hook implementation as long as the
|
|
* node operations table implements the given function.
|
|
*/
|
|
typedef struct vfs_ops {
|
|
/**
|
|
* \brief Open a VFS node for further access.
|
|
*
|
|
* This hook can only be implemented by regular files and devices.
|
|
*
|
|
* The file system implementation should allocate a way for the system
|
|
* to send further VFS requests to the node, such as reading or
|
|
* writing.
|
|
*
|
|
* \param node the VFS node that will be opened
|
|
* \param flags a flags mask with the node open mode.
|
|
* \return status code: zero on success, non-zero on failure.
|
|
*/
|
|
int (*vfs_open)(struct vfs_node *node, unsigned int flags);
|
|
|
|
/**
|
|
* \brief Read from a VFS node.
|
|
*
|
|
* This hook can only be implemented by regular files and devices.
|
|
*
|
|
* A file system implementation that uses this hook should copy into
|
|
* the given buffer \p buf up to \p len bytes from the underlying
|
|
* container mapped to the VFS node, starting at offset \p offt.
|
|
*
|
|
* \param node the VFS node that will be read
|
|
* \param offt the offset to apply within the container
|
|
* \param buf the buffer where the read bytes should be copied
|
|
* \param len the number of bytes to copy into the buffer
|
|
* \return the actual number of bytes that were copied to the buffer
|
|
*/
|
|
unsigned int (*vfs_read)(struct vfs_node *node,
|
|
unsigned int offt,
|
|
void *buf,
|
|
unsigned int len);
|
|
|
|
/**
|
|
* \brief Write to a VFS node.
|
|
*
|
|
* This hook can only be implemented by regular files and devices.
|
|
*
|
|
* A file system implementation that uses this hook should copy from
|
|
* the given buffer \p buf up to \p len bytes into the underlying
|
|
* container mapped to the VFS node, starting at offset \p offt.
|
|
*
|
|
* \param node the VFS node that will be written
|
|
* \param offt the offset to apply within the container
|
|
* \param buf the buffer where the bytes to copy are located
|
|
* \param len the number of bytes to copy into the container
|
|
* \return the actual number of bytes that were copied from the buffer
|
|
*/
|
|
unsigned int (*vfs_write)(struct vfs_node *node,
|
|
unsigned int offt,
|
|
void *buf,
|
|
unsigned int len);
|
|
|
|
/**
|
|
* \brief IO Control for VFS nodes.
|
|
*
|
|
* This hook can only be implemented by devices.
|
|
*
|
|
* ioctl is a special hack that has been in use for a very long time
|
|
* to execute side requests into device driver files. It can only be
|
|
* used by devices, and the semantics of the request depend in the
|
|
* device driver itself.
|
|
*
|
|
* \param node the VFS node where the request will be sent
|
|
* \param iorq the request code number to send to the device
|
|
* \param args additional iorq-dependent parameter payload
|
|
* \return the outcome of the ioctl request as defined by the driver
|
|
*/
|
|
int (*vfs_ioctl)(struct vfs_node *node, int iorq, void *args);
|
|
|
|
/**
|
|
* \brief Close an VFS node
|
|
*
|
|
* This hook can only be implemented by regular files and devices.
|
|
*
|
|
* This hook is used by the file system implementation to mark the
|
|
* node as closed. The file system implementation should assume that
|
|
* after this hook is called, no further requests to the given VFS
|
|
* node will be received until another open request is received.
|
|
*
|
|
* \param node the VFS node to close.
|
|
* \return zero if successful, non-zero if not successful
|
|
*/
|
|
int (*vfs_close)(struct vfs_node *node);
|
|
|
|
/**
|
|
* \brief Read a directory entry
|
|
*
|
|
* This hook can only be implemented by directories.
|
|
*
|
|
* This hook is used to traverse the VFS node representation of a
|
|
* directory in order to look for child VFS nodes that are contained
|
|
* inside the directory. To iterate, an \p index number is given,
|
|
* which should return a proper node if it points to a valid node
|
|
* inside this directory. Otherwise, it should return NULL to mark
|
|
* that the index is out of the bounds of the directory children.
|
|
*
|
|
* \todo This is not a directory entry, this is an vfs_node.
|
|
* \param node the VFS node to iterate
|
|
* \param index the index number of the child VFS node to find.
|
|
* \return a pointer to the child VFS node or NULL.
|
|
*/
|
|
struct vfs_node *(*vfs_readdir)(struct vfs_node *node,
|
|
unsigned int index);
|
|
|
|
/**
|
|
* \brief Find a directory entry
|
|
*
|
|
* This hook can only be implemented by directories.
|
|
*
|
|
* This hook is used to locate a specific node inside the given
|
|
* VFS node by its name. It is a way to lookup a specific entry
|
|
* given the name of the entry. It should return a pointer to the
|
|
* VFS node if the given directory contains a child VFS node
|
|
* that matches this name. Otherwise, it should return NULL.
|
|
*
|
|
* \todo This is not a directory entry, this is an vfs_node.
|
|
* \param node the VFS node to lookup into
|
|
* \param nodename the name of the child node to lookup
|
|
* \return a pointer to the child VFS ndoe or NULL.
|
|
*/
|
|
struct vfs_node *(*vfs_finddir)(struct vfs_node *node, char *nodename);
|
|
} vfs_ops_t;
|
|
|
|
typedef struct vfs_node {
|
|
char vn_name[64];
|
|
unsigned int vn_flags;
|
|
struct vfs_node *vn_parent;
|
|
struct vfs_volume *vn_volume;
|
|
void *vn_payload;
|
|
} vfs_node_t;
|
|
|
|
typedef struct vfs_volume {
|
|
char *vv_name;
|
|
struct vfs_filesys *vv_family;
|
|
struct vfs_node *vv_root;
|
|
void *vv_payload;
|
|
} vfs_volume_t;
|
|
|
|
typedef struct vfs_filesys {
|
|
/** The identifier name of the file system driver. */
|
|
char *fsd_ident;
|
|
|
|
/** The public name of the file system driver. */
|
|
char *fsd_name;
|
|
|
|
/** A hook to tell the FS Driver it is being initialised. */
|
|
void (*fsd_init)(void);
|
|
|
|
/** A hook to tell the FS Driver it is being destructed. */
|
|
void (*fsd_tini)(void);
|
|
|
|
/** A hook used to tell the FS Driver that a volume is mounted. */
|
|
int (*fsd_mount)(vfs_volume_t *vol);
|
|
|
|
/** A pointer to the operations table for this FS Driver. */
|
|
vfs_ops_t *fsd_ops;
|
|
} vfs_filesys_t;
|
|
|
|
/**
|
|
* \brief Get the file system operations table for a VFS node.
|
|
* \param node the file system node to retrieve the operations table.
|
|
* \return the operations table for the given node.
|
|
*/
|
|
#define NODE_OPS(node) \
|
|
((node && node->vn_volume && node->vn_volume \
|
|
&& node->vn_volume->vv_family) \
|
|
? node->vn_volume->vv_family->fsd_ops \
|
|
: 0)
|
|
|
|
#define FS_DESCRIPTOR(name, fs) \
|
|
vfs_filesys_t *fs_descriptor_##name \
|
|
__attribute__((section(".text.fs"), used)) = &fs
|
|
|
|
void vfs_init(void);
|
|
|
|
int vfs_mount(char *driver, char *name, void *argp);
|
|
int vfs_umount(char *mountname);
|
|
|
|
vfs_node_t *vfs_get_volume(char *mountname);
|
|
|
|
/**
|
|
* @brief Given a path, locate the node in the mounted filesystems
|
|
* @param path the path to the node we want to find
|
|
* @return a pointer to the found node or NULL if not found
|
|
*/
|
|
vfs_node_t *fs_resolve(const char *path);
|
|
|
|
int fs_open(vfs_node_t *node, unsigned int flags);
|
|
unsigned int
|
|
fs_read(vfs_node_t *node, unsigned int offset, void *buf, unsigned int len);
|
|
unsigned int
|
|
fs_write(vfs_node_t *node, unsigned int offset, void *buf, unsigned int len);
|
|
int fs_ioctl(vfs_node_t *node, int iorq, void *args);
|
|
int fs_close(vfs_node_t *node);
|
|
vfs_node_t *fs_readdir(vfs_node_t *node, unsigned int index);
|
|
vfs_node_t *fs_finddir(vfs_node_t *node, char *name);
|