Kernel - Added 'Flags' param to VFS Read/Write/FindDir
[tpg/acess2.git] / KernelLand / Modules / Filesystems / Ext2 / dir.c
index ef347ad..2f2b72f 100644 (file)
 #define BLOCK_DIR_OFS(_data, _block)   (((Uint16*)(_data))[(_block)])
 
 // === PROTOTYPES ===
-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_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
+tVFS_Node      *Ext2_FindDir(tVFS_Node *Node, const char *FileName, Uint Flags);
+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 = {
@@ -44,7 +42,7 @@ tVFS_NodeType gExt2_FileType = {
  * \param Node Directory node
  * \param Pos  Position of desired element
  */
-char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
+int Ext2_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tExt2_Inode     inode;
        tExt2_DirEnt    dirent;
@@ -92,8 +90,8 @@ char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
        
        // Check for the end of the list
        if(size <= 0 || size > inode.i_size) {
-               LEAVE('n');
-               return NULL;
+               LEAVE('i', -ENOENT);
+               return -ENOENT;
        }
        
        // Read Entry
@@ -103,20 +101,21 @@ char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
        dirent.name[ dirent.name_len ] = '\0';  // Cap off string
        
        if( dirent.name_len == 0 ) {
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;
+               LEAVE('i', 1);
+               return 1;
        }
        
        // Ignore . and .. (these are done in the VFS)
        if( (dirent.name[0] == '.' && dirent.name[1] == '\0')
        ||  (dirent.name[0] == '.' && dirent.name[1] == '.' && dirent.name[2]=='\0')) {
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;        // Skip
+               LEAVE('i', 1);
+               return 1;       // Skip
        }
        
-       LEAVE('s', dirent.name);
-       // Create new node
-       return strdup(dirent.name);
+       LOG("Name '%s'", dirent.name);
+       strncpy(Dest, dirent.name, FILENAME_MAX);
+       LEAVE('i', 0);
+       return 0;
 }
 
 /**
@@ -125,7 +124,7 @@ char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
  * \param Filename     Name of wanted file
  * \return VFS Node of file
  */
-tVFS_Node *Ext2_FindDir(tVFS_Node *Node, const char *Filename)
+tVFS_Node *Ext2_FindDir(tVFS_Node *Node, const char *Filename, Uint Flags)
 {
        tExt2_Disk      *disk = Node->ImplPtr;
        tExt2_Inode     inode;
@@ -148,10 +147,8 @@ 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)
+               if(dirent.name_len == filenameLen && strncmp(dirent.name, Filename, filenameLen) == 0)
                        return Ext2_int_CreateNode( disk, dirent.inode );
                // Increment pointers
                ofs += dirent.rec_len;
@@ -177,22 +174,20 @@ tVFS_Node *Ext2_FindDir(tVFS_Node *Node, const char *Filename)
  * \fn int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
  * \brief Create a new node
  */
-int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
+tVFS_Node *Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
 {
        ENTER("pParent sName xFlags", Parent, Name, Flags);
        
        Uint64 inodeNum = Ext2_int_AllocateInode(Parent->ImplPtr, Parent->Inode);
        if( inodeNum == 0 ) {
                LOG("Inode allocation failed");
-               LEAVE('i', -1);
-               return -1;
+               LEAVE_RET('n', NULL);
        }
        tVFS_Node *child = Ext2_int_CreateNode(Parent->ImplPtr, inodeNum);
        if( !child ) {
                Ext2_int_DereferenceInode(Parent->ImplPtr, inodeNum);
                Log_Warning("Ext2", "Ext2_MkNod - Node creation failed");
-               LEAVE('i', -1);
-               return -1;
+               LEAVE_RET('n', NULL);
        }
 
        child->Flags = Flags & (VFS_FFLAG_DIRECTORY|VFS_FFLAG_SYMLINK|VFS_FFLAG_READONLY);
@@ -206,9 +201,11 @@ int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
        // TODO: Set up ACLs
 
        int rv = Ext2_Link(Parent, Name, child);
-       child->Type->Close(child);
-       LEAVE('i', rv);
-       return rv;
+       if( rv ) {
+               Ext2_CloseFile(child);
+               return NULL;
+       }
+       LEAVE_RET('p', child);
 }
 
 /**
@@ -233,7 +230,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;
@@ -242,7 +238,8 @@ int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child)
         int    block = 0, ofs = 0;
        Uint    size;
        void    *blockData;
-        int    bestMatch = -1, bestSize, bestBlock, bestOfs, bestNeedsSplit;
+        int    bestMatch = -1;
+        int    bestSize=0, bestBlock=0, bestOfs=0, bestNeedsSplit=0;
         int    nEntries;
 
        ENTER("pNode sName pChild",
@@ -276,6 +273,7 @@ int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child)
        base = inode.i_block[0] * disk->BlockSize;
        VFS_ReadAt( disk->FD, base, disk->BlockSize, blockData );
        block = 0;
+       nEntries = 0;
        // Find File
        while(size > 0)
        {
@@ -398,83 +396,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;
 }
 

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