Modules/Ext2 - Adding inode creation/writeback on file close
authorJohn Hodge <[email protected]>
Tue, 28 Aug 2012 01:30:56 +0000 (09:30 +0800)
committerJohn Hodge <[email protected]>
Tue, 28 Aug 2012 01:30:56 +0000 (09:30 +0800)
- Also added VFS_CleanupNode (does nothing atm)

KernelLand/Kernel/vfs/main.c
KernelLand/Modules/Filesystems/Ext2/dir.c
KernelLand/Modules/Filesystems/Ext2/ext2.c
KernelLand/Modules/Filesystems/Ext2/ext2_common.h
KernelLand/Modules/Filesystems/FAT/nodecache.c

index fb1da89..0261eca 100644 (file)
@@ -172,3 +172,9 @@ void VFS_UpdateDriverFile(void)
        if(gsVFS_DriverFile)    free(gsVFS_DriverFile);
        gsVFS_DriverFile = buf;
 }
+
+void VFS_CleanupNode(tVFS_Node *Node)
+{
+       
+}
+
index de0b30a..33df847 100644 (file)
@@ -5,7 +5,7 @@
  * dir.c
  * - Directory Handling
  */
-#define DEBUG  1
+#define DEBUG  0
 #define VERBOSE        0
 #include "ext2_common.h"
 
@@ -18,8 +18,6 @@ tVFS_Node     *Ext2_FindDir(tVFS_Node *Node, const char *FileName);
 tVFS_Node      *Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
  int   Ext2_Unlink(tVFS_Node *Node, const char *OldName);
  int   Ext2_Link(tVFS_Node *Parent, const char *Name, tVFS_Node *Node);
-// --- Helpers ---
-tVFS_Node      *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeId);
 
 // === GLOBALS ===
 tVFS_NodeType  gExt2_DirType = {
@@ -234,7 +232,6 @@ int Ext2_Unlink(tVFS_Node *Node, const char *OldName)
  */
 int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child)
 {      
-       #if 1
        tExt2_Disk      *disk = Node->ImplPtr;
        tExt2_Inode     inode;
        tExt2_DirEnt    *dirent;
@@ -401,83 +398,5 @@ int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child)
        Mutex_Release(&Node->Lock);
        LEAVE('i', 0);
        return 0;
-       #else
-       Log_Warning("Ext2", "TODO: Impliment Ext2_Link");
-       return 1;
-       #endif
-}
-
-// ---- INTERNAL FUNCTIONS ----
-/**
- * \fn vfs_node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)
- * \brief Create a new VFS Node
- */
-tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)
-{
-       tExt2_Inode     inode;
-       tVFS_Node       retNode;
-       tVFS_Node       *tmpNode;
-       
-       if( !Ext2_int_ReadInode(Disk, InodeID, &inode) )
-               return NULL;
-       
-       if( (tmpNode = Inode_GetCache(Disk->CacheID, InodeID)) )
-               return tmpNode;
-
-       memset(&retNode, 0, sizeof(retNode));   
-       
-       // Set identifiers
-       retNode.Inode = InodeID;
-       retNode.ImplPtr = Disk;
-       retNode.ImplInt = inode.i_links_count;
-       
-       // Set file length
-       retNode.Size = inode.i_size;
-       
-       // Set Access Permissions
-       retNode.UID = inode.i_uid;
-       retNode.GID = inode.i_gid;
-       retNode.NumACLs = 3;
-       retNode.ACLs = VFS_UnixToAcessACL(inode.i_mode & 0777, inode.i_uid, inode.i_gid);
-       
-       //  Set Function Pointers
-       retNode.Type = &gExt2_FileType;
-       
-       switch(inode.i_mode & EXT2_S_IFMT)
-       {
-       // Symbolic Link
-       case EXT2_S_IFLNK:
-               retNode.Flags = VFS_FFLAG_SYMLINK;
-               break;
-       // Regular File
-       case EXT2_S_IFREG:
-               retNode.Flags = 0;
-               retNode.Size |= (Uint64)inode.i_dir_acl << 32;
-               break;
-       // Directory
-       case EXT2_S_IFDIR:
-               retNode.Type = &gExt2_DirType;
-               retNode.Flags = VFS_FFLAG_DIRECTORY;
-               retNode.Data = calloc( sizeof(Uint16), DivUp(retNode.Size, Disk->BlockSize) );
-               break;
-       // Unknown, Write protect it to be safe 
-       default:
-               retNode.Flags = VFS_FFLAG_READONLY;
-               break;
-       }
-       
-       // Set Timestamps
-       retNode.ATime = inode.i_atime * 1000;
-       retNode.MTime = inode.i_mtime * 1000;
-       retNode.CTime = inode.i_ctime * 1000;
-       
-       // Save in node cache and return saved node
-       return Inode_CacheNode(Disk->CacheID, &retNode);
-}
-
-int Ext2_int_WritebackNode(tExt2_Disk *Disk, tVFS_Node *Node)
-{
-       Log_Warning("Ext2","TODO: Impliment Ext2_int_WritebackNode");
-       return 0;
 }
 
index adf9163..4d13f1e 100644 (file)
@@ -13,9 +13,6 @@
 #define MIN_BLOCKS_PER_GROUP   2\r
 #define MAX_BLOCK_LOG_SIZE     10      // 1024 << 10 = 1MiB\r
 \r
-// === IMPORTS ===\r
-extern tVFS_NodeType   gExt2_DirType;\r
-\r
 // === PROTOTYPES ===\r
  int   Ext2_Install(char **Arguments);\r
  int   Ext2_Cleanup(void);\r
@@ -236,7 +233,8 @@ void Ext2_CloseFile(tVFS_Node *Node)
        if( Node->Flags & VFS_FFLAG_DIRTY )\r
        {\r
                // Commit changes\r
-               Log_Warning("Ext2", "TODO: Commit node changes");\r
+               Ext2_int_WritebackNode(disk, Node);\r
+               Node->Flags &= ~VFS_FFLAG_DIRTY;\r
        }\r
 \r
        int was_not_referenced = (Node->ImplInt == 0);\r
@@ -247,7 +245,7 @@ void Ext2_CloseFile(tVFS_Node *Node)
                {\r
                        LOG("Removng inode");\r
                        // Remove inode\r
-                       Log_Warning("Ext2", "TODO: Remove inode when not referenced");\r
+                       Log_Warning("Ext2", "TODO: Remove inode when not referenced (%x)", (Uint32)Node->Inode);\r
                }\r
                if( acls != &gVFS_ACL_EveryoneRW ) {\r
                        free(acls);\r
@@ -325,6 +323,118 @@ int Ext2_int_WriteInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode)
        return 1;\r
 }\r
 \r
+/**\r
+ * \fn vfs_node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)\r
+ * \brief Create a new VFS Node\r
+ */\r
+tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)\r
+{\r
+       tExt2_Inode     inode;\r
+       tVFS_Node       retNode;\r
+       tVFS_Node       *tmpNode;\r
+       \r
+       if( !Ext2_int_ReadInode(Disk, InodeID, &inode) )\r
+               return NULL;\r
+       \r
+       if( (tmpNode = Inode_GetCache(Disk->CacheID, InodeID)) )\r
+               return tmpNode;\r
+\r
+       memset(&retNode, 0, sizeof(retNode));   \r
+       \r
+       // Set identifiers\r
+       retNode.Inode = InodeID;\r
+       retNode.ImplPtr = Disk;\r
+       retNode.ImplInt = inode.i_links_count;\r
+       if( inode.i_links_count == 0 ) {\r
+               Log_Notice("Ext2", "Inode %p:%x is not referenced, bug?", Disk, InodeID);\r
+       }\r
+       \r
+       // Set file length\r
+       retNode.Size = inode.i_size;\r
+       \r
+       // Set Access Permissions\r
+       retNode.UID = inode.i_uid;\r
+       retNode.GID = inode.i_gid;\r
+       retNode.NumACLs = 3;\r
+       retNode.ACLs = VFS_UnixToAcessACL(inode.i_mode & 0777, inode.i_uid, inode.i_gid);\r
+       \r
+       //  Set Function Pointers\r
+       retNode.Type = &gExt2_FileType;\r
+       \r
+       switch(inode.i_mode & EXT2_S_IFMT)\r
+       {\r
+       // Symbolic Link\r
+       case EXT2_S_IFLNK:\r
+               retNode.Flags = VFS_FFLAG_SYMLINK;\r
+               break;\r
+       // Regular File\r
+       case EXT2_S_IFREG:\r
+               retNode.Flags = 0;\r
+               retNode.Size |= (Uint64)inode.i_dir_acl << 32;\r
+               break;\r
+       // Directory\r
+       case EXT2_S_IFDIR:\r
+               retNode.Type = &gExt2_DirType;\r
+               retNode.Flags = VFS_FFLAG_DIRECTORY;\r
+               retNode.Data = calloc( sizeof(Uint16), DivUp(retNode.Size, Disk->BlockSize) );\r
+               break;\r
+       // Unknown, Write protect it to be safe \r
+       default:\r
+               retNode.Flags = VFS_FFLAG_READONLY;\r
+               break;\r
+       }\r
+       \r
+       // Set Timestamps\r
+       retNode.ATime = inode.i_atime * 1000;\r
+       retNode.MTime = inode.i_mtime * 1000;\r
+       retNode.CTime = inode.i_ctime * 1000;\r
+       \r
+       // Save in node cache and return saved node\r
+       return Inode_CacheNode(Disk->CacheID, &retNode);\r
+}\r
+\r
+int Ext2_int_WritebackNode(tExt2_Disk *Disk, tVFS_Node *Node)\r
+{\r
+       tExt2_Inode     inode;\r
+\r
+       if( Disk != Node->ImplPtr ) {\r
+               Log_Error("Ext2", "Ext2_int_WritebackNode - Disk != Node->ImplPtr");\r
+               return -1;\r
+       }\r
+       \r
+       if( Node->Flags & VFS_FFLAG_SYMLINK ) {\r
+               inode.i_mode = EXT2_S_IFLNK;\r
+       }\r
+       else if( Node->Flags & VFS_FFLAG_DIRECTORY ) {\r
+               inode.i_mode = EXT2_S_IFDIR;\r
+       }\r
+       else if( Node->Flags & VFS_FFLAG_READONLY ) {\r
+               Log_Notice("Ext2", "Not writing back readonly inode %p:%x", Disk, Node->Inode);\r
+               return 1;\r
+       }\r
+       else {\r
+               inode.i_mode = EXT2_S_IFREG;\r
+               inode.i_dir_acl = Node->Size >> 32;\r
+       }\r
+\r
+       inode.i_size = Node->Size & 0xFFFFFFFF;\r
+       inode.i_links_count = Node->ImplInt;\r
+\r
+       inode.i_uid = Node->UID;\r
+       inode.i_gid = Node->GID;\r
+\r
+       inode.i_atime = Node->ATime / 1000;\r
+       inode.i_mtime = Node->MTime / 1000;\r
+       inode.i_ctime = Node->CTime / 1000;\r
+\r
+       // TODO: Compact ACLs into unix mode\r
+       Log_Warning("Ext2", "TODO: Support converting Acess ACLs into unix modes");\r
+\r
+       Ext2_int_WriteInode(Disk, Node->Inode, &inode);\r
+\r
+       return 0;\r
+}\r
+\r
 /**\r
  * \fn Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)\r
  * \brief Get the address of a block from an inode's list\r
index 5515429..4c8c45e 100644 (file)
@@ -23,6 +23,10 @@ typedef struct {
        tExt2_Group             Groups[];
 } tExt2_Disk;
 
+// === GLOBALS ===
+extern tVFS_NodeType   gExt2_FileType;
+extern tVFS_NodeType   gExt2_DirType;
+
 // === FUNCTIONS ===
 // --- Common ---
 extern void    Ext2_CloseFile(tVFS_Node *Node);
@@ -37,6 +41,8 @@ extern int    Ext2_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 extern tVFS_Node       *Ext2_FindDir(tVFS_Node *Node, const char *FileName);
 extern tVFS_Node       *Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
 extern int     Ext2_Link(tVFS_Node *Parent, const char *Name, tVFS_Node *Node);
+extern tVFS_Node       *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeId);
+extern int     Ext2_int_WritebackNode(tExt2_Disk *Disk, tVFS_Node *Node);
 // --- Read ---
 extern size_t  Ext2_Read(tVFS_Node *node, off_t offset, size_t length, void *buffer);
 // --- Write ---
index a0b3b31..1ad26e5 100644 (file)
@@ -223,6 +223,7 @@ int FAT_int_DerefNode(tVFS_Node *Node)
                // Already out of the list :)
                if(cnode->Node.Data)
                        free(cnode->Node.Data);
+               VFS_CleanupNode(&cnode->Node);
                free(cnode);
                bFreed = 1;
        }

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