From e93b9c1fe4068dd5b07049c0926dbb910d20a99b Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 17 Jul 2012 13:36:28 +0800 Subject: [PATCH] Modules/EXT2 - Working on write support --- KernelLand/Modules/Filesystems/Ext2/dir.c | 52 +++++++++---------- KernelLand/Modules/Filesystems/Ext2/ext2.c | 40 +++++++++++--- .../Modules/Filesystems/Ext2/ext2_common.h | 2 + KernelLand/Modules/Filesystems/Ext2/write.c | 5 ++ 4 files changed, 64 insertions(+), 35 deletions(-) diff --git a/KernelLand/Modules/Filesystems/Ext2/dir.c b/KernelLand/Modules/Filesystems/Ext2/dir.c index 0887ed28..30cc86ed 100644 --- a/KernelLand/Modules/Filesystems/Ext2/dir.c +++ b/KernelLand/Modules/Filesystems/Ext2/dir.c @@ -172,34 +172,32 @@ tVFS_Node *Ext2_FindDir(tVFS_Node *Node, const char *Filename) */ int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags) { - #if 0 - tVFS_Node *child; - Uint64 inodeNum; - tExt2_Inode inode; - inodeNum = Ext2_int_AllocateInode(Parent->ImplPtr, Parent->Inode); - - memset(&inode, 0, sizeof(tExt2_Inode)); + ENTER("pParent sName xFlags", Parent, Name, Flags); - // File type - inode.i_mode = 0664; - if( Flags & VFS_FFLAG_READONLY ) - inode.i_mode &= ~0222; - if( Flags & VFS_FFLAG_SYMLINK ) - inode.i_mode |= EXT2_S_IFLNK; - else if( Flags & VFS_FFLAG_DIRECTORY ) - inode.i_mode |= EXT2_S_IFDIR | 0111; - - inode.i_uid = Threads_GetUID(); - inode.i_gid = Threads_GetGID(); - inode.i_ctime = - inode.i_mtime = - inode.i_atime = now() / 1000; - - child = Ext2_int_CreateNode(Parent->ImplPtr, inodeNum); - return Ext2_Link(Parent, child, Name); - #else - return 1; - #endif + Uint64 inodeNum = Ext2_int_AllocateInode(Parent->ImplPtr, Parent->Inode); + if( inodeNum == 0 ) { + return -1; + } + tVFS_Node *child = Ext2_int_CreateNode(Parent->ImplPtr, inodeNum); + if( !child ) { + Ext2_int_DereferenceInode(Parent->ImplPtr, inodeNum); + return -1; + } + + child->Flags = Flags & (VFS_FFLAG_DIRECTORY|VFS_FFLAG_SYMLINK|VFS_FFLAG_READONLY); + child->UID = Threads_GetUID(); + child->GID = Threads_GetGID(); + child->CTime = + child->MTime = + child->ATime = + now(); + child->ImplInt = 0; // ImplInt is the link count + // TODO: Set up ACLs + + int rv = Ext2_Link(Parent, Name, child); + child->Type->Close(child); + LEAVE('i', rv); + return rv; } /** diff --git a/KernelLand/Modules/Filesystems/Ext2/ext2.c b/KernelLand/Modules/Filesystems/Ext2/ext2.c index 971ef28e..f8f942d5 100644 --- a/KernelLand/Modules/Filesystems/Ext2/ext2.c +++ b/KernelLand/Modules/Filesystems/Ext2/ext2.c @@ -17,15 +17,16 @@ extern tVFS_NodeType gExt2_DirType; int Ext2_Install(char **Arguments); int Ext2_Cleanup(void); // - Interface Functions - int Ext2_Detect(int FD); + int Ext2_Detect(int FD); tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options); -void Ext2_Unmount(tVFS_Node *Node); -void Ext2_CloseFile(tVFS_Node *Node); +void Ext2_Unmount(tVFS_Node *Node); +void Ext2_CloseFile(tVFS_Node *Node); // - Internal Helpers - int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode); -Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum); -Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent); -void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk); + int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode); +Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum); +Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent); +void Ext2_int_DereferenceInode(tExt2_Disk *Disk, Uint32 Inode); +void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk); // === SEMI-GLOBALS === MODULE_DEFINE(0, VERSION, FS_Ext2, Ext2_Install, Ext2_Cleanup); @@ -208,7 +209,22 @@ void Ext2_Unmount(tVFS_Node *Node) void Ext2_CloseFile(tVFS_Node *Node) { tExt2_Disk *disk = Node->ImplPtr; - Inode_UncacheNode(disk->CacheID, Node->Inode); + + if( Mutex_Acquire(&Node->Lock) != 0 ) + { + return ; + } + + if( Node->Flags & VFS_FFLAG_DIRTY ) + { + // Commit changes + } + + int was_not_referenced = (Node->ImplInt == 0); + if( Inode_UncacheNode(disk->CacheID, Node->Inode) && was_not_referenced ) + { + // Remove inode + } return ; } @@ -337,6 +353,14 @@ Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent) return 0; } +/** + * \brief Reduce the reference count on an inode + */ +void Ext2_int_DereferenceInode(tExt2_Disk *Disk, Uint32 Inode) +{ + +} + /** * \fn void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk) * \brief Updates the superblock diff --git a/KernelLand/Modules/Filesystems/Ext2/ext2_common.h b/KernelLand/Modules/Filesystems/Ext2/ext2_common.h index 036cd59f..1d994ddb 100644 --- a/KernelLand/Modules/Filesystems/Ext2/ext2_common.h +++ b/KernelLand/Modules/Filesystems/Ext2/ext2_common.h @@ -32,6 +32,8 @@ typedef struct { extern void Ext2_CloseFile(tVFS_Node *Node); extern Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum); extern void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk); +extern Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent); +extern void Ext2_int_DereferenceInode(tExt2_Disk *Disk, Uint32 Inode); extern int Ext2_int_ReadInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode); extern int Ext2_int_WriteInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode); // --- Dir --- diff --git a/KernelLand/Modules/Filesystems/Ext2/write.c b/KernelLand/Modules/Filesystems/Ext2/write.c index 60b176ca..22e256bf 100644 --- a/KernelLand/Modules/Filesystems/Ext2/write.c +++ b/KernelLand/Modules/Filesystems/Ext2/write.c @@ -119,7 +119,12 @@ addBlocks: } base = block * disk->BlockSize; VFS_WriteAt(disk->FD, base, retLen, Buffer); + + // TODO: When should the size update be committed? inode.i_size += retLen; + Node->Size += retLen; + Node->Flags |= VFS_FFLAG_DIRTY; + retLen = 0; ret: // Makes sure the changes to the inode are committed -- 2.20.1