*/
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;
}
/**
int Ext2_Install(char **Arguments);\r
int Ext2_Cleanup(void);\r
// - Interface Functions\r
- int Ext2_Detect(int FD);\r
+ int Ext2_Detect(int FD);\r
tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options);\r
-void Ext2_Unmount(tVFS_Node *Node);\r
-void Ext2_CloseFile(tVFS_Node *Node);\r
+void Ext2_Unmount(tVFS_Node *Node);\r
+void Ext2_CloseFile(tVFS_Node *Node);\r
// - Internal Helpers\r
- int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode);\r
-Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum);\r
-Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent);\r
-void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);\r
+ int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode);\r
+Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum);\r
+Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent);\r
+void Ext2_int_DereferenceInode(tExt2_Disk *Disk, Uint32 Inode);\r
+void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);\r
\r
// === SEMI-GLOBALS ===\r
MODULE_DEFINE(0, VERSION, FS_Ext2, Ext2_Install, Ext2_Cleanup);\r
void Ext2_CloseFile(tVFS_Node *Node)\r
{\r
tExt2_Disk *disk = Node->ImplPtr;\r
- Inode_UncacheNode(disk->CacheID, Node->Inode);\r
+\r
+ if( Mutex_Acquire(&Node->Lock) != 0 )\r
+ {\r
+ return ;\r
+ }\r
+\r
+ if( Node->Flags & VFS_FFLAG_DIRTY )\r
+ {\r
+ // Commit changes\r
+ }\r
+\r
+ int was_not_referenced = (Node->ImplInt == 0);\r
+ if( Inode_UncacheNode(disk->CacheID, Node->Inode) && was_not_referenced )\r
+ {\r
+ // Remove inode\r
+ }\r
return ;\r
}\r
\r
return 0;\r
}\r
\r
+/**\r
+ * \brief Reduce the reference count on an inode\r
+ */\r
+void Ext2_int_DereferenceInode(tExt2_Disk *Disk, Uint32 Inode)\r
+{\r
+ \r
+}\r
+\r
/**\r
* \fn void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)\r
* \brief Updates the superblock\r
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 ---
}
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