Added lspci to core build and initrd
[tpg/acess2.git] / KernelLand / Modules / Filesystems / Ext2 / dir.c
index 5eb476f..4039a7c 100644 (file)
@@ -1,13 +1,11 @@
 /*
- * Acess OS
- * Ext2 Driver Version 1
+ * Acess2 Ext2 Driver
+ * - By John Hodge (thePowersGang)
+ *
+ * dir.c
+ * - Directory Handling
  */
-/**
- * \file dir.c
- * \brief Second Extended Filesystem Driver
- * \todo Implement file full write support
- */
-#define DEBUG  1
+#define DEBUG  0
 #define VERBOSE        0
 #include "ext2_common.h"
 
@@ -18,8 +16,8 @@
 char   *Ext2_ReadDir(tVFS_Node *Node, int Pos);
 tVFS_Node      *Ext2_FindDir(tVFS_Node *Node, const char *FileName);
  int   Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
- int   Ext2_Relink(tVFS_Node *Node, const char *OldName, const char *NewName);
- int   Ext2_Link(tVFS_Node *Parent, tVFS_Node *Node, const char *Name);
+ 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);
 
@@ -29,7 +27,7 @@ tVFS_NodeType gExt2_DirType = {
        .ReadDir = Ext2_ReadDir,
        .FindDir = Ext2_FindDir,
        .MkNod = Ext2_MkNod,
-       .Relink = Ext2_Relink,
+       .Unlink = Ext2_Unlink,
        .Link = Ext2_Link,
        .Close = Ext2_CloseFile
        };
@@ -63,14 +61,14 @@ char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
        Ext2_int_ReadInode(disk, Node->Inode, &inode);
        size = inode.i_size;
        
-       LOG("inode.i_block[0] = 0x%x", inode.i_block[0]);
+       LOG("inode={.i_block[0]= 0x%x, .i_size=0x%x}", inode.i_block[0], inode.i_size);
        
        // Find Entry
        // Get First Block
        // - Do this ourselves as it is a simple operation
        Base = inode.i_block[0] * disk->BlockSize;
        // Scan directory
-       while(Pos -- && size > 0)
+       while(Pos -- && size > 0 && size <= inode.i_size)
        {
                VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);
                ofs += dirent.rec_len;
@@ -85,22 +83,29 @@ char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
                        }
                        ofs = 0;
                        Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );
+                       if( Base == 0 ) {
+                               size = 0;
+                               break;
+                       }
                }
        }
        
        // Check for the end of the list
-       if(size <= 0) {
+       if(size <= 0 || size > inode.i_size) {
                LEAVE('n');
                return NULL;
        }
        
        // Read Entry
        VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent );
-       //LOG("dirent.inode = %i", dirent.inode);
-       //LOG("dirent.rec_len = %i", dirent.rec_len);
-       //LOG("dirent.name_len = %i", dirent.name_len);
+       LOG("dirent={.rec_len=%i,.inode=0x%x,.name_len=%i}",
+               dirent.rec_len, dirent.inode, dirent.name_len);
        dirent.name[ dirent.name_len ] = '\0';  // Cap off string
        
+       if( dirent.name_len == 0 ) {
+               LEAVE('p', VFS_SKIP);
+               return VFS_SKIP;
+       }
        
        // Ignore . and .. (these are done in the VFS)
        if( (dirent.name[0] == '.' && dirent.name[1] == '\0')
@@ -143,6 +148,7 @@ tVFS_Node *Ext2_FindDir(tVFS_Node *Node, const char *Filename)
        while(size > 0)
        {
                VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);
+               // TODO: Possible overrun if name_len == 255?
                dirent.name[ dirent.name_len ] = '\0';  // Cap off string
                // If it matches, create a node and return it
                if(dirent.name_len == filenameLen && strcmp(dirent.name, Filename) == 0)
@@ -173,34 +179,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));
-       
-       // 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;
+       ENTER("pParent sName xFlags", Parent, Name, Flags);
        
-       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;
 }
 
 /**
@@ -208,9 +212,9 @@ int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
  * \param Node This (directory) node
  * \param OldName      Old name of file
  * \param NewName      New name for file
- * \return Boolean Failure - See ::tVFS_Node.Relink for info
+ * \return Boolean Failure - See ::tVFS_Node.Unlink for info
  */
-int Ext2_Relink(tVFS_Node *Node, const char *OldName, const char *NewName)
+int Ext2_Unlink(tVFS_Node *Node, const char *OldName)
 {
        return 1;
 }
@@ -218,11 +222,11 @@ int Ext2_Relink(tVFS_Node *Node, const char *OldName, const char *NewName)
 /**
  * \brief Links an existing node to a new name
  * \param Parent       Parent (directory) node
- * \param Node Node to link
  * \param Name New name for the node
+ * \param Node Node to link
  * \return Boolean Failure - See ::tVFS_Node.Link for info
  */
-int Ext2_Link(tVFS_Node *Node, tVFS_Node *Child, const char *Name)
+int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child)
 {      
        #if 0
        tExt2_Disk      *disk = Node->ImplPtr;
@@ -345,7 +349,8 @@ tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)
        
        if( (tmpNode = Inode_GetCache(Disk->CacheID, InodeID)) )
                return tmpNode;
-       
+
+       memset(&retNode, 0, sizeof(retNode));   
        
        // Set identifiers
        retNode.Inode = InodeID;
@@ -353,7 +358,6 @@ tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)
        
        // Set file length
        retNode.Size = inode.i_size;
-       retNode.Data = NULL;
        
        // Set Access Permissions
        retNode.UID = inode.i_uid;

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