VFS - Rework to remove function pointers from tVFS_Node
[tpg/acess2.git] / Modules / Filesystems / FAT / fat.c
index f65cb42..f5d1916 100644 (file)
@@ -90,6 +90,24 @@ MODULE_DEFINE(0, (0<<8)|50 /*v0.50*/, VFAT, FAT_Install, NULL, NULL);
 tFAT_VolInfo   gFAT_Disks[8];\r
  int   giFAT_PartCount = 0;\r
 tVFS_Driver    gFAT_FSInfo = {"fat", 0, FAT_InitDevice, FAT_Unmount, FAT_GetNodeFromINode, NULL};\r
+tVFS_NodeType  gFAT_DirType = {\r
+       .TypeName = "FAT-Dir",\r
+       .ReadDir = FAT_ReadDir,\r
+       .FindDir = FAT_FindDir,\r
+       #if SUPPORT_WRITE\r
+       .MkNod = FAT_Mknod,\r
+       .Relink = FAT_Relink,\r
+       #endif\r
+       .Close = FAT_CloseFile\r
+       };\r
+tVFS_NodeType  gFAT_FileType = {\r
+       .TypeName = "FAT-File",\r
+       .Read = FAT_Read,\r
+       #if SUPPORT_WRITE\r
+       .Write = FAT_Write,\r
+       #endif\r
+       .Close = FAT_CloseFile\r
+       };\r
 \r
 // === CODE ===\r
 /**\r
@@ -273,18 +291,8 @@ tVFS_Node *FAT_InitDevice(const char *Device, const char **Options)
        node->ACLs = &gVFS_ACL_EveryoneRWX;\r
        node->Flags = VFS_FFLAG_DIRECTORY;\r
        node->CTime = node->MTime = node->ATime = now();\r
-       \r
-       node->Read = node->Write = NULL;\r
-       node->ReadDir = FAT_ReadDir;\r
-       node->FindDir = FAT_FindDir;\r
-       #if SUPPORT_WRITE\r
-       node->Relink = FAT_Relink;\r
-       node->MkNod = FAT_Mknod;\r
-       #else\r
-       node->Relink = NULL;\r
-       node->MkNod = NULL;\r
-       #endif\r
-       //node->Close = FAT_Unmount;\r
+\r
+       node->Type = &gFAT_DirType;     \r
        \r
        giFAT_PartCount ++;\r
        return node;\r
@@ -614,6 +622,7 @@ void FAT_int_ReadCluster(tFAT_VolInfo *Disk, Uint32 Cluster, int Length, void *B
 Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
 {\r
         int    preSkip, count;\r
+       Uint64  final_bytes;\r
         int    i, cluster, pos;\r
        tFAT_VolInfo    *disk = Node->ImplPtr;\r
        char    tmpBuf[disk->BytesPerCluster];\r
@@ -623,7 +632,7 @@ Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        \r
        // Sanity Check offset\r
        if(Offset > Node->Size) {\r
-               LOG("Reading past EOF (%i > %i)", Offset, Node->Size);\r
+               LOG("Seek past EOF (%i > %i)", Offset, Node->Size);\r
                LEAVE('i', 0);\r
                return 0;\r
        }\r
@@ -632,28 +641,18 @@ Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        cluster = Node->Inode & 0xFFFFFFFF;\r
        \r
        // Clamp Size\r
-       if(Offset >= Node->Size || Offset + Length > Node->Size) {\r
+       if(Offset + Length > Node->Size) {\r
                LOG("Reading past EOF (%lli + %lli > %lli), clamped to %lli",\r
                        Offset, Length, Node->Size, Node->Size - Offset);\r
                Length = Node->Size - Offset;\r
        }\r
        \r
-       // Reading from within the first cluster only?\r
-       if((int)Offset + (int)Length < bpc)\r
-       {\r
-               LOG("First cluster only");\r
-               FAT_int_ReadCluster(disk, cluster, bpc, tmpBuf);\r
-               memcpy( Buffer, (void*)( tmpBuf + Offset%bpc ), Length );\r
-               #if DEBUG\r
-               //Debug_HexDump("FAT_Read", Buffer, Length);\r
-               #endif\r
-               LEAVE('i', 1);\r
-               return Length;\r
-       }\r
-       \r
        // Skip previous clusters\r
        preSkip = Offset / bpc;\r
-       for(i = preSkip; i--; ) {\r
+       Offset %= bpc;\r
+       LOG("preSkip = %i, Offset = %i", preSkip, (int)Offset);\r
+       for(i = preSkip; i--; )\r
+       {\r
                cluster = FAT_int_GetFatValue(disk, cluster);\r
                if(cluster == -1) {\r
                        Log_Warning("FAT", "Offset is past end of cluster chain mark");\r
@@ -661,75 +660,69 @@ Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                        return 0;\r
                }\r
        }\r
-       \r
-       // Get Count of Clusters to read\r
-       count = ((Offset%bpc + Length) / bpc) + 1;\r
-       \r
-       // Get buffer Position after 1st cluster\r
-       pos = bpc - Offset%bpc;\r
-       \r
-       // Read 1st Cluster (performs alignment for us)\r
-       if( pos == bpc && (int)Length >= bpc ) {\r
-               FAT_int_ReadCluster(disk, cluster, bpc, Buffer);\r
-       }\r
-       else {\r
+\r
+       // Reading from within one cluster\r
+       if((int)Offset + (int)Length <= bpc)\r
+       {\r
+               LOG("single cluster only");\r
                FAT_int_ReadCluster(disk, cluster, bpc, tmpBuf);\r
-               memcpy(\r
-                       Buffer,\r
-                       (void*)( tmpBuf + (bpc-pos) ),\r
-                       (pos < (int)Length ? (Uint)pos : Length)\r
-                       );\r
-       }\r
-       \r
-       // Simple return\r
-       if( count == 1 ) {\r
-               #if DEBUG\r
-               //Debug_HexDump("FAT_Read", Buffer, Length);\r
-               #endif\r
-               LEAVE('i', 1);\r
+               memcpy( Buffer, (void*)( tmpBuf + Offset%bpc ), Length );\r
+               LEAVE('X', Length);\r
                return Length;\r
        }\r
        \r
-       #if DEBUG\r
-       LOG("pos = %i", pos);\r
-       LOG("Reading the rest of the clusters");\r
-       #endif\r
-       \r
-       // Read the rest of the cluster data\r
-       for( i = 1; i < count-1; i++ )\r
+       // Align read to a cluster\r
+       if( Offset > 0 )\r
        {\r
+               pos = bpc - Offset;\r
+               FAT_int_ReadCluster(disk, cluster, bpc, tmpBuf);\r
+               memcpy( Buffer, (void*)( tmpBuf + Offset ), pos );\r
+               LOG("pos = %i, Reading the rest of the clusters");\r
                // Get next cluster in the chain\r
                cluster = FAT_int_GetFatValue(disk, cluster);\r
                if(cluster == -1) {\r
-                       Log_Warning("FAT", "FAT_Read: Read past End of Cluster Chain");\r
-                       LEAVE('i', 0);\r
-                       return 0;\r
+                       Log_Warning("FAT", "Read past End of Cluster Chain (Align)");\r
+                       LEAVE('X', pos);\r
+                       return pos;\r
+               }\r
+       }\r
+       else\r
+               pos = 0;\r
+\r
+       // Get Count of Clusters to read\r
+//     count = DivMod64U(Length - pos, bpc, &final_bytes);\r
+       count = (Length - pos) / bpc;\r
+       final_bytes = (Length - pos) % bpc;\r
+       LOG("Offset = %i, Length = %i, count = %i, final_bytes = %i", (int)Offset, (int)Length, count, final_bytes);\r
+       \r
+       // Read the rest of the cluster data\r
+       for( ; count; count -- )\r
+       {\r
+               if(cluster == -1) {\r
+                       Log_Warning("FAT", "Read past End of Cluster Chain (Bulk)");\r
+                       LEAVE('X', pos);\r
+                       return pos;\r
                }\r
                // Read cluster\r
                FAT_int_ReadCluster(disk, cluster, bpc, (void*)(Buffer+pos));\r
                pos += bpc;\r
+               // Get next cluster in the chain\r
+               cluster = FAT_int_GetFatValue(disk, cluster);\r
        }\r
-       \r
-       // Get next cluster in the chain\r
-       cluster = FAT_int_GetFatValue(disk, cluster);\r
-       if(cluster == -1) {\r
-               Log_Warning("FAT", "FAT_Read: Read past End of Cluster Chain");\r
-               LEAVE('i', 0);\r
-               return 0;\r
-       }\r
-       \r
-       // Read final cluster\r
-       if( (int)Length - pos == bpc )\r
+\r
+       if( final_bytes > 0 )\r
        {\r
-               FAT_int_ReadCluster( disk, cluster, bpc, (void*)(Buffer+pos) );\r
-       }\r
-       else {\r
+               if(cluster == -1) {\r
+                       Log_Warning("FAT", "Read past End of Cluster Chain (Final)");\r
+                       LEAVE('X', pos);\r
+                       return pos;\r
+               }\r
+               // Read final cluster\r
                FAT_int_ReadCluster( disk, cluster, bpc, tmpBuf );\r
                memcpy( (void*)(Buffer+pos), tmpBuf, Length-pos );\r
        }\r
-       \r
+               \r
        #if DEBUG\r
-       LOG("Free tmpBuf(0x%x) and Return", tmpBuf);\r
        //Debug_HexDump("FAT_Read", Buffer, Length);\r
        #endif\r
        \r
@@ -992,21 +985,12 @@ tVFS_Node *FAT_int_CreateNode(tVFS_Node *Parent, fat_filetable *Entry, int Pos)
        // Set pointers\r
        if(node.Flags & VFS_FFLAG_DIRECTORY) {\r
                //Log_Debug("FAT", "Directory %08x has size 0x%x", node.Inode, node.Size);\r
-               node.ReadDir = FAT_ReadDir;\r
-               node.FindDir = FAT_FindDir;\r
-               #if SUPPORT_WRITE\r
-               node.MkNod = FAT_Mknod;\r
-               node.Relink = FAT_Relink;\r
-               #endif\r
+               node.Type = &gFAT_DirType;      \r
                node.Size = -1;\r
        }\r
        else {\r
-               node.Read = FAT_Read;\r
-               #if SUPPORT_WRITE\r
-               node.Write = FAT_Write;\r
-               #endif\r
+               node.Type = &gFAT_FileType;\r
        }\r
-       node.Close = FAT_CloseFile;\r
        \r
        ret = Inode_CacheNode(disk->inodeHandle, &node);\r
        LEAVE('p', ret);\r
@@ -1322,8 +1306,8 @@ tVFS_Node *FAT_FindDir(tVFS_Node *Node, const char *Name)
        tFAT_VolInfo    *disk = Node->ImplPtr;\r
        Uint32  cluster;\r
        \r
-       ENTER("pNode sname", Node, Name);\r
-       \r
+       ENTER("pNode sname", Node, Name);       \r
+\r
        // Fast Returns\r
        if(!Name || Name[0] == '\0') {\r
                LEAVE('n');\r

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