Kernel - VFS mmap spec (Node level)
[tpg/acess2.git] / Kernel / include / vfs.h
index 337d8e7..248a1ac 100644 (file)
@@ -5,6 +5,16 @@
 /**
  * \file vfs.h
  * \brief Acess VFS Layer
+ * 
+ * The Acess Virtual File System (VFS) provides abstraction of multiple
+ * physical filesystems, network storage and devices (both hardware and
+ * virtual) to the user.
+ * 
+ * The core of the VFS is the concept of a \ref tVFS_Node "VFS Node".
+ * A VFS Node represents a "file" in the VFS tree, this can be any sort
+ * of file (an ordinary file, a directory, a symbolic link or a device)
+ * depending on the bits set in the \ref tVFS_Node.Flags Flags field.
+ * - For more information see "VFS Node Flags"
  */
 #ifndef _VFS_H
 #define _VFS_H
 #include <acess.h>
 
 /**
- * \name VFS Node Flags
+ * \brief Thread list datatype for VFS_Select
+ */
+typedef struct sVFS_SelectList tVFS_SelectList;
+
+/**
+ * \name tVFS_Node Flags
+ * \brief Flag values for tVFS_Node.Flags
  * \{
  */
-#define VFS_FFLAG_READONLY     0x01    //!< Read-only file
-#define VFS_FFLAG_DIRECTORY    0x02    //!< Directory
-#define VFS_FFLAG_SYMLINK      0x04    //!< Symbolic Link
+//! \todo Is this still needed
+#define VFS_FFLAG_READONLY     0x01    //!< Readonly File
+/**
+ * \brief Directory Flag
+ * 
+ * This flag marks the tVFS_Node as describing a directory, and says
+ * that the tVFS_Node.FindDir, tVFS_Node.ReadDir, tVFS_Node.MkNod and
+ * tVFS_Node.Relink function pointers are valid.
+ * For a directory the tVFS_Node.Size field contains the number of files
+ * within the directory, or -1 for undetermined.
+ */
+#define VFS_FFLAG_DIRECTORY    0x02
+/**
+ * \brief Symbolic Link Flag
+ * 
+ * Marks a file as a symbolic link
+ */
+#define VFS_FFLAG_SYMLINK      0x04
+/**
+ * \brief Set User ID Flag
+ * 
+ * Allows an executable file to change it's executing user to the file's
+ * owner.
+ * In the case of a directory, it means that all immediate children will
+ * inherit the UID of the parent.
+ */
+#define VFS_FFLAG_SETUID       0x08
+/**
+ * \brief Set Group ID Flag
+ * 
+ * Allows an executable file to change it's executing group to the file's
+ * owning group.
+ * In the case of a directory, it means that all immediate children will
+ * inherit the GID of the parent.
+ */
+#define VFS_FFLAG_SETGID       0x10
+
+/**
+ * \brief "Don't do Write-Back" Flag
+ *
+ * Stops the VFS from calling tVFS_Node.Write on dirty pages when a region
+ * is unmapped. Nice for read-only files and memory-only files (or 
+ * pseudo-readonly filesystems)
+ */
+#define VFS_FFLAG_NOWRITEBACK
 /**
  * \}
  */
 
 /**
- * \brief VFS Node
- * \todo Complete / Finalise
+ * \brief Represents a node (file or directory) in the VFS tree
+ * 
+ * This structure provides the VFS with the functions required to read/write
+ * the file (or directory) that it represents.
  */
-typedef struct sVFS_Node {     
-       Uint64  Inode;  //!< Inode ID
+typedef struct sVFS_Node
+{
+       /**
+        * \name Identifiers
+        * \brief Fields used by the driver to identify what data this node
+        *        corresponds to.
+        * \{
+        */
+       Uint64  Inode;  //!< Inode ID (Essentially another ImplInt)
        Uint    ImplInt;        //!< Implementation Usable Integer
        void    *ImplPtr;       //!< Implementation Usable Pointer
+       /**
+        * \}
+        */
        
+       /**
+        * \name Node State
+        * \brief Stores the misc information about the node
+        * \{
+        */
         int    ReferenceCount; //!< Number of times the node is used
        
        Uint64  Size;   //!< File Size
        
        Uint32  Flags;  //!< File Flags
        
+       /**
+        * \brief Pointer to cached data (FS Specific)
+        * \note The Inode_* functions will free when the node is uncached
+        *       this if needed
+        */
+       void    *Data;
+       
+       /**
+        * \brief Node mutex
+        * \note Provided for the Filesystem driver's use
+        */
+       tMutex  Lock;
+       
+       /**
+        * \}
+        */
+       
+       /**
+        * \name Times
+        * \{
+        */
        Sint64  ATime;  //!< Last Accessed Time
        Sint64  MTime;  //!< Last Modified Time
        Sint64  CTime;  //!< Creation Time
+       /**
+        * \}
+        */
        
-       Uint    UID;    //!< Owning User
-       Uint    GID;    //!< Owning Group
+       /**
+        * \name Access control
+        * \{
+        */
+       tUID    UID;    //!< ID of Owning User
+       tGID    GID;    //!< ID of Owning Group
        
         int    NumACLs;        //!< Number of ACL entries
-       tVFS_ACL        *ACLs;  //!< ACL Entries
+       tVFS_ACL        *ACLs;  //!< Access Controll List pointer
+       /**
+        * \}
+        */
        
+       /**
+        * \name VFS_Select() fields
+        * \{
+        */
+        int    DataAvaliable;
+       tVFS_SelectList *ReadThreads;   //!< Threads waiting to read
+        int    BufferFull;
+       tVFS_SelectList *WriteThreads;  //!< Threads waiting to write
+        int    ErrorOccurred;
+       tVFS_SelectList *ErrorThreads;  //!< Threads waiting for an error
+       /**
+        * \}
+        */
+       
+       /**
+        * \name Common Functions
+        * \brief Functions that are used no matter the value of .Flags
+        * \{
+        */
        /**
         * \brief Reference the node
         * \param Node Pointer to this node
@@ -70,6 +195,17 @@ typedef struct sVFS_Node {
         */
         int    (*IOCtl)(struct sVFS_Node *Node, int Id, void *Data);
        
+       /**
+        * \}
+        */
+       
+       /**
+        * \name Buffer Functions
+        * \brief Functions for accessing a buffer-type file (normal file or
+        *        symbolic link)
+        * \{
+        */
+       
        /**
         * \brief Read from the file
         * \param Node  Pointer to this node
@@ -88,7 +224,26 @@ typedef struct sVFS_Node {
         * \return Number of bytes read
         */
        Uint64  (*Write)(struct sVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+
+       /**
+        * \brief Map a region of a file into memory
+        * \param Node  Pointer to this node
+        * \param Offset        Start of the region (page aligned)
+        * \param Length        Length of the region (page aligned)
+        * \param Dest  Location to which to map
+        * \return Boolean Failure
+        * \note If NULL, the VFS implements it using .Read
+        */
+        int    (*MMap)(struct sVFS_Node *Node, Uint64 Offset, int Length, void *Dest);
        
+       /**
+        * \}
+        */
+       
+       /**
+        * \name Directory Functions
+        * \{
+        */
        /**
         * \brief Find an directory entry by name
         * \param Node  Pointer to this node
@@ -97,7 +252,7 @@ typedef struct sVFS_Node {
         * \note The node returned must be accessable until ::tVFS_Node.Close
         *       is called and ReferenceCount reaches zero.
         */
-       struct sVFS_Node        *(*FindDir)(struct sVFS_Node *Node, char *Name);
+       struct sVFS_Node        *(*FindDir)(struct sVFS_Node *Node, const char *Name);
        
        /**
         * \brief Read from a directory
@@ -116,18 +271,31 @@ typedef struct sVFS_Node {
         * \param Node  Pointer to this node
         * \param Name  Name of the new child
         * \param Flags Flags to apply to the new child (directory or symlink)
-        * \return Boolean success
+        * \return Zero on Success, non-zero on error (see errno.h)
         */
-        int    (*MkNod)(struct sVFS_Node *Node, char *Name, Uint Flags);
+        int    (*MkNod)(struct sVFS_Node *Node, const char *Name, Uint Flags);
        
        /**
         * \brief Relink (Rename/Remove) a file/directory
         * \param Node  Pointer to this node
         * \param OldName       Name of the item to move/delete
         * \param NewName       New name (or NULL if unlinking is wanted)
-        * \return Boolean Success
+        * \return Zero on Success, non-zero on error (see errno.h)
+        */
+        int    (*Relink)(struct sVFS_Node *Node, const char *OldName, const char *NewName);
+       
+       /**
+        * \brief Link a node to a name
+        * \param Node  Pointer to this node (directory)
+        * \param Child Node to create a new link to
+        * \param NewName       Name for the new link
+        * \return Zeron on success, non-zero on error (see errno.h)
         */
-        int    (*Relink)(struct sVFS_Node *Node, char *OldName, char *NewName);
+        int    (*Link)(struct sVFS_Node *Node, struct sVFS_Node *Child, const char *NewName);
+        
+        /**
+         * \}
+         */
 } tVFS_Node;
 
 /**
@@ -136,12 +304,12 @@ typedef struct sVFS_Node {
 typedef struct sVFS_Driver
 {
        //! \brief Unique Identifier for this filesystem type
-       char    *Name;
+       const char      *Name;
        //! \brief Flags applying to this driver
        Uint    Flags;
        
        //! \brief Callback to mount a device
-       tVFS_Node       *(*InitDevice)(char *Device, char **Options);
+       tVFS_Node       *(*InitDevice)(const char *Device, const char **Options);
        //! \brief Callback to unmount a device
        void    (*Unmount)(tVFS_Node *Node);
        //! \brief Used internally (next driver in the chain)
@@ -158,7 +326,8 @@ typedef struct sVFS_Driver
 
 extern tVFS_Node       NULLNode;       //!< NULL VFS Node (Ignored/Skipped)
 /**
- * \name Simple ACLs to aid writing drivers
+ * \name Static ACLs
+ * \brief Simple ACLs to aid writing drivers
  * \{
  */
 extern tVFS_ACL        gVFS_ACL_EveryoneRWX;   //!< Everyone Read/Write/Execute
@@ -181,7 +350,21 @@ extern int VFS_AddDriver(tVFS_Driver *Info);
  * \brief Get the information structure of a driver given its name
  * \param Name Name of filesystem driver to find
  */
-extern tVFS_Driver     *VFS_GetFSByName(char *Name);
+extern tVFS_Driver     *VFS_GetFSByName(const char *Name);
+
+
+/**
+ * \brief Prepare a node for use
+ */
+extern void    VFS_InitNode(tVFS_Node *Node);
+
+/**
+ * \brief Clean up a node, ready for deletion
+ * \note This should ALWAYS be called before a node is freed, as it
+ *       cleans up VFS internal structures.
+ */
+extern void    VFS_CleanupNode(tVFS_Node *Node);
+
 /**
  * \fn tVFS_ACL *VFS_UnixToAcessACL(Uint Mode, Uint Owner, Uint Group)
  * \brief Transforms Unix Permssions into Acess ACLs
@@ -192,15 +375,50 @@ extern tVFS_Driver        *VFS_GetFSByName(char *Name);
  */
 extern tVFS_ACL        *VFS_UnixToAcessACL(Uint Mode, Uint Owner, Uint Group);
 
+/**
+ * \brief Flags fro \a TypeFlag of VFS_SelectNode
+ * \{
+ */
+#define VFS_SELECT_READ        0x01
+#define VFS_SELECT_WRITE       0x02
+#define VFS_SELECT_ERROR       0x04
+/**
+ * \}
+ */
+
+/**
+ * \brief Wait for an event on a node
+ * \param Node Node to wait on
+ * \param Type Type of wait
+ * \param Timeout      Time to wait (NULL for infinite wait)
+ * \param Name Name to show in debug output
+ * \return Number of nodes that actioned (0 or 1)
+ */
+extern int     VFS_SelectNode(tVFS_Node *Node, int Type, tTime *Timeout, const char *Name);
+
+/**
+ * \brief Change the full flag on a node
+ */
+extern int     VFS_MarkFull(tVFS_Node *Node, BOOL IsBufferFull);
+extern int     VFS_MarkAvaliable(tVFS_Node *Node, BOOL IsDataAvaliable);
+extern int     VFS_MarkError(tVFS_Node *Node, BOOL IsErrorState);
+
 // --- Node Cache --
-//! \name Node Cache
-//! \{
 /**
- * \fn int Inode_GetHandle()
+ * \name Node Cache
+ * \brief Functions to allow a node to be cached in memory by the VFS
+ * 
+ * These functions store a node for the driver, to prevent it from having
+ * to re-generate the node on each call to FindDir. It also allows for
+ * fast cleanup when a filesystem is unmounted.
+ * \{
+ */
+/**
+ * \fn int Inode_GetHandle(void)
  * \brief Gets a unique handle to the Node Cache
  * \return A unique handle for use for the rest of the Inode_* functions
  */
-extern int     Inode_GetHandle();
+extern int     Inode_GetHandle(void);
 /**
  * \fn tVFS_Node *Inode_GetCache(int Handle, Uint64 Inode)
  * \brief Gets an inode from the node cache
@@ -218,7 +436,7 @@ extern tVFS_Node    *Inode_GetCache(int Handle, Uint64 Inode);
  */
 extern tVFS_Node       *Inode_CacheNode(int Handle, tVFS_Node *Node);
 /**
- * \fn void Inode_UncacheNode(int Handle, Uint64 Inode)
+ * \fn int Inode_UncacheNode(int Handle, Uint64 Inode)
  * \brief Dereferences (and removes if needed) a node from the cache
  * \param Handle       A handle returned by Inode_GetHandle()
  * \param Inode        Value of the Inode field of the ::tVFS_Node you want to remove
@@ -231,6 +449,8 @@ extern void Inode_UncacheNode(int Handle, Uint64 Inode);
  */
 extern void    Inode_ClearCache(int Handle);
 
-//! \}
+/**
+ * \}
+ */
 
 #endif

UCC git Repository :: git.ucc.asn.au