Renamed libc filename, disabled debug and reenabled lfn in FAT
[tpg/acess2.git] / Modules / Filesystems / FAT / fat.c
index 491a4d5..93911de 100644 (file)
@@ -3,7 +3,7 @@
  * FAT12/16/32 Driver Version (Incl LFN)\r
  * \r
  * NOTE: This driver will only support _reading_ long file names, not\r
- * writing. I don't even know why i'm adding write-support. FAT sucks.\r
+ * writing. I don't even know why I'm adding write-support. FAT sucks.\r
  * \r
  * Known Bugs:\r
  * - LFN Is buggy in FAT_ReadDir\r
@@ -60,6 +60,9 @@ tVFS_Node     *FAT_FindDir(tVFS_Node *Node, char *Name);
  int   FAT_Relink(tVFS_Node *node, char *OldName, char *NewName);\r
 void   FAT_CloseFile(tVFS_Node *node);\r
 \r
+// === Options ===\r
+ int   giFAT_MaxCachedClusters = 1024*512/4;\r
+\r
 // === SEMI-GLOBALS ===\r
 MODULE_DEFINE(0, (0<<8)|50 /*v0.50*/, VFAT, FAT_Install, NULL, NULL);\r
 tFAT_VolInfo   gFAT_Disks[8];\r
@@ -176,53 +179,54 @@ tVFS_Node *FAT_InitDevice(char *Device, char **Options)
        \r
        //Allow for Caching the FAT\r
        #if CACHE_FAT\r
+       if( diskInfo->ClusterCount <= giFAT_MaxCachedClusters )\r
        {\r
-       Uint32  Ofs;\r
-       diskInfo->FATCache = (Uint32*)malloc(sizeof(Uint32)*diskInfo->ClusterCount);\r
-       if(diskInfo->FATCache == NULL) {\r
-               Log_Warning("FAT", "Heap Exhausted");\r
-               return NULL;\r
-       }\r
-       Ofs = bs->resvSectCount*512;\r
-       if(diskInfo->type == FAT12)\r
-       {\r
-               Uint32  val;\r
-                int    j;\r
-               char    buf[1536];\r
-               for(i = 0; i < diskInfo->ClusterCount/2; i++) {\r
-                       j = i & 511;    //%512\r
-                       if( j == 0 ) {\r
-                               VFS_ReadAt(diskInfo->fileHandle, Ofs, 3*512, buf);\r
-                               Ofs += 3*512;\r
+               Uint32  Ofs;\r
+               diskInfo->FATCache = (Uint32*)malloc(sizeof(Uint32)*diskInfo->ClusterCount);\r
+               if(diskInfo->FATCache == NULL) {\r
+                       Log_Warning("FAT", "Heap Exhausted");\r
+                       return NULL;\r
+               }\r
+               Ofs = bs->resvSectCount*512;\r
+               if(diskInfo->type == FAT12)\r
+               {\r
+                       Uint32  val;\r
+                        int    j;\r
+                       char    buf[1536];\r
+                       for(i = 0; i < diskInfo->ClusterCount/2; i++) {\r
+                               j = i & 511;    //%512\r
+                               if( j == 0 ) {\r
+                                       VFS_ReadAt(diskInfo->fileHandle, Ofs, 3*512, buf);\r
+                                       Ofs += 3*512;\r
+                               }\r
+                               val = *((int*)(buf+j*3));\r
+                               diskInfo->FATCache[i*2] = val & 0xFFF;\r
+                               diskInfo->FATCache[i*2+1] = (val>>12) & 0xFFF;\r
                        }\r
-                       val = *((int*)(buf+j*3));\r
-                       diskInfo->FATCache[i*2] = val & 0xFFF;\r
-                       diskInfo->FATCache[i*2+1] = (val>>12) & 0xFFF;\r
                }\r
-       }\r
-       else if(diskInfo->type == FAT16)\r
-       {\r
-               Uint16  buf[256];\r
-               for(i=0;i<diskInfo->ClusterCount;i++) {\r
-                       if( (i & 255) == 0 ) {\r
-                               VFS_ReadAt(diskInfo->fileHandle, Ofs, 512, buf);\r
-                               Ofs += 512;\r
+               else if(diskInfo->type == FAT16)\r
+               {\r
+                       Uint16  buf[256];\r
+                       for(i=0;i<diskInfo->ClusterCount;i++) {\r
+                               if( (i & 255) == 0 ) {\r
+                                       VFS_ReadAt(diskInfo->fileHandle, Ofs, 512, buf);\r
+                                       Ofs += 512;\r
+                               }\r
+                               diskInfo->FATCache[i] = buf[i&255];\r
                        }\r
-                       diskInfo->FATCache[i] = buf[i&255];\r
                }\r
-       }\r
-       else if(diskInfo->type == FAT32)\r
-       {\r
-               Uint32  buf[128];\r
-               for(i=0;i<diskInfo->ClusterCount;i++) {\r
-                       if( (i & 127) == 0 ) {\r
-                               VFS_ReadAt(diskInfo->fileHandle, Ofs, 512, buf);\r
-                               Ofs += 512;\r
+               else if(diskInfo->type == FAT32)\r
+               {\r
+                       Uint32  buf[128];\r
+                       for(i=0;i<diskInfo->ClusterCount;i++) {\r
+                               if( (i & 127) == 0 ) {\r
+                                       VFS_ReadAt(diskInfo->fileHandle, Ofs, 512, buf);\r
+                                       Ofs += 512;\r
+                               }\r
+                               diskInfo->FATCache[i] = buf[i&127];\r
                        }\r
-                       diskInfo->FATCache[i] = buf[i&127];\r
                }\r
-       }\r
-       LOG("FAT Fully Cached");\r
+               LOG("FAT Fully Cached");\r
        }\r
        #endif /*CACHE_FAT*/\r
        \r
@@ -234,7 +238,8 @@ tVFS_Node *FAT_InitDevice(char *Device, char **Options)
        \r
        // == VFS Interface\r
        node = &diskInfo->rootNode;\r
-       node->Size = bs->files_in_root;\r
+       //node->Size = bs->files_in_root;\r
+       node->Size = -1;\r
        node->Inode = diskInfo->rootOffset;     // 0:31 - Cluster, 32:63 - Parent Directory Cluster\r
        node->ImplPtr = diskInfo;       // Disk info pointer\r
        node->ImplInt = 0;      // 0:15 - Directory Index, 16: Dirty Flag, 17: Deletion Flag\r
@@ -323,6 +328,8 @@ int FAT_int_GetAddress(tVFS_Node *Node, Uint64 Offset, Uint64 *Addr, Uint32 *Clu
                if(Cluster)     *Cluster = cluster;\r
        }\r
        \r
+       LOG("cluster = %08x", cluster);\r
+       \r
        // Bounds Checking (Used to spot corruption)\r
        if(cluster > disk->ClusterCount + 2)\r
        {\r
@@ -362,27 +369,33 @@ int FAT_int_GetAddress(tVFS_Node *Node, Uint64 Offset, Uint64 *Addr, Uint32 *Clu
 Uint32 FAT_int_GetFatValue(tFAT_VolInfo *Disk, Uint32 cluster)\r
 {\r
        Uint32  val = 0;\r
-       #if !CACHE_FAT\r
-       Uint32  ofs = Disk->bootsect.resvSectCount*512;\r
-       #endif\r
+       Uint32  ofs;\r
        ENTER("pDisk xCluster", Disk, cluster);\r
        LOCK( &Disk->lFAT );\r
        #if CACHE_FAT\r
-       val = Disk->FATCache[cluster];\r
-       if(Disk->type == FAT12 && val == EOC_FAT12)     val = -1;\r
-       if(Disk->type == FAT16 && val == EOC_FAT16)     val = -1;\r
-       if(Disk->type == FAT32 && val == EOC_FAT32)     val = -1;\r
-       #else\r
-       if(Disk->type == FAT12) {\r
-               VFS_ReadAt(Disk->fileHandle, ofs+(cluster>>1)*3, 3, &val);\r
-               val = (cluster&1 ? val&0xFFF : val>>12);\r
-               if(val == EOC_FAT12)    val = -1;\r
-       } else if(Disk->type == FAT16) {\r
-               VFS_ReadAt(Disk->fileHandle, ofs+cluster*2, 2, &val);\r
-               if(val == EOC_FAT16)    val = -1;\r
-       } else {\r
-               VFS_ReadAt(Disk->fileHandle, ofs+cluster*4, 4, &val);\r
-               if(val == EOC_FAT32)    val = -1;\r
+       if( Disk->ClusterCount <= giFAT_MaxCachedClusters )\r
+       {\r
+               val = Disk->FATCache[cluster];\r
+               if(Disk->type == FAT12 && val == EOC_FAT12)     val = -1;\r
+               if(Disk->type == FAT16 && val == EOC_FAT16)     val = -1;\r
+               if(Disk->type == FAT32 && val == EOC_FAT32)     val = -1;\r
+       }\r
+       else\r
+       {\r
+       #endif\r
+               ofs = Disk->bootsect.resvSectCount*512;\r
+               if(Disk->type == FAT12) {\r
+                       VFS_ReadAt(Disk->fileHandle, ofs+(cluster>>1)*3, 3, &val);\r
+                       val = (cluster&1 ? val&0xFFF : val>>12);\r
+                       if(val == EOC_FAT12)    val = -1;\r
+               } else if(Disk->type == FAT16) {\r
+                       VFS_ReadAt(Disk->fileHandle, ofs+cluster*2, 2, &val);\r
+                       if(val == EOC_FAT16)    val = -1;\r
+               } else {\r
+                       VFS_ReadAt(Disk->fileHandle, ofs+cluster*4, 4, &val);\r
+                       if(val == EOC_FAT32)    val = -1;\r
+               }\r
+       #if CACHE_FAT\r
        }\r
        #endif /*CACHE_FAT*/\r
        RELEASE( &Disk->lFAT );\r
@@ -398,78 +411,85 @@ Uint32 FAT_int_AllocateCluster(tFAT_VolInfo *Disk, Uint32 Previous)
 {\r
        Uint32  ret = Previous;\r
        #if CACHE_FAT\r
-       Uint32  eoc;\r
-       \r
-       LOCK(Disk->lFAT);\r
-       for(ret = Previous; ret < Disk->ClusterCount; ret++)\r
-       {\r
-               if(Disk->FATCache[ret] == 0)\r
-                       goto append;\r
-       }\r
-       for(ret = 0; ret < Previous; ret++)\r
-       {\r
-               if(Disk->FATCache[ret] == 0)\r
-                       goto append;\r
-       }\r
-       \r
-       RELEASE(Disk->lFAT);\r
-       return 0;\r
-       \r
-append:\r
-       switch(Disk->type)\r
-       {\r
-       case FAT12:     eoc = EOC_FAT12;        break;\r
-       case FAT16:     eoc = EOC_FAT16;        break;\r
-       case FAT32:     eoc = EOC_FAT32;        break;\r
-       default:        return 0;\r
-       }\r
-       \r
-       Disk->FATCache[ret] = eoc;\r
-       Disk->FATCache[Previous] = ret;\r
-       \r
-       RELEASE(Disk->lFAT);\r
-       return ret;\r
-       #else\r
-       Uint32  val;\r
-       //Uint8 buf[512];\r
-       Log_Warning("FAT", "TODO: Implement cluster allocation with non cached FAT");\r
-       return 0;\r
-       \r
-       switch(Disk->type)\r
+       if( Disk->ClusterCount <= giFAT_MaxCachedClusters )\r
        {\r
-       case FAT12:\r
-               VFS_ReadAt(Disk->fileHandle, ofs+(Previous>>1)*3, 3, &val);\r
-               if( Previous & 1 ) {\r
-                       val &= 0xFFF000;\r
-                       val |= ret;\r
+               Uint32  eoc;\r
+               \r
+               LOCK(Disk->lFAT);\r
+               for(ret = Previous; ret < Disk->ClusterCount; ret++)\r
+               {\r
+                       if(Disk->FATCache[ret] == 0)\r
+                               goto append;\r
                }\r
-               else {\r
-                       val &= 0xFFF;\r
-                       val |= ret<<12;\r
+               for(ret = 0; ret < Previous; ret++)\r
+               {\r
+                       if(Disk->FATCache[ret] == 0)\r
+                               goto append;\r
                }\r
-               VFS_WriteAt(Disk->fileHandle, ofs+(Previous>>1)*3, 3, &val);\r
                \r
-               VFS_ReadAt(Disk->fileHandle, ofs+(ret>>1)*3, 3, &val);\r
-               if( Cluster & 1 ) {\r
-                       val &= 0xFFF000;\r
-                       val |= eoc;\r
+               RELEASE(Disk->lFAT);\r
+               return 0;\r
+       \r
+       append:\r
+               switch(Disk->type)\r
+               {\r
+               case FAT12:     eoc = EOC_FAT12;        break;\r
+               case FAT16:     eoc = EOC_FAT16;        break;\r
+               case FAT32:     eoc = EOC_FAT32;        break;\r
+               default:        return 0;\r
                }\r
-               else {\r
-                       val &= 0x000FFF;\r
-                       val |= eoc<<12;\r
+               \r
+               Disk->FATCache[ret] = eoc;\r
+               Disk->FATCache[Previous] = ret;\r
+               \r
+               RELEASE(Disk->lFAT);\r
+               return ret;\r
+       }\r
+       else\r
+       {\r
+       #endif\r
+               Uint32  val;\r
+               Uint32  ofs = Disk->bootsect.resvSectCount*512;\r
+               Log_Warning("FAT", "TODO: Implement cluster allocation with non cached FAT");\r
+               return 0;\r
+               \r
+               switch(Disk->type)\r
+               {\r
+               case FAT12:\r
+                       VFS_ReadAt(Disk->fileHandle, ofs+(Previous>>1)*3, 3, &val);\r
+                       if( Previous & 1 ) {\r
+                               val &= 0xFFF000;\r
+                               val |= ret;\r
+                       }\r
+                       else {\r
+                               val &= 0xFFF;\r
+                               val |= ret<<12;\r
+                       }\r
+                       VFS_WriteAt(Disk->fileHandle, ofs+(Previous>>1)*3, 3, &val);\r
+                       \r
+                       VFS_ReadAt(Disk->fileHandle, ofs+(ret>>1)*3, 3, &val);\r
+                       if( Cluster & 1 ) {\r
+                               val &= 0xFFF000;\r
+                               val |= eoc;\r
+                       }\r
+                       else {\r
+                               val &= 0x000FFF;\r
+                               val |= eoc<<12;\r
+                       }\r
+                       VFS_WriteAt(Disk->fileHandle, ofs+(ret>>1)*3, 3, &val);\r
+                       break;\r
+               case FAT16:\r
+                       VFS_ReadAt(Disk->fileHandle, ofs+Previous*2, 2, &ret);\r
+                       VFS_WriteAt(Disk->fileHandle, ofs+ret*2, 2, &eoc);\r
+                       break;\r
+               case FAT32:\r
+                       VFS_ReadAt(Disk->fileHandle, ofs+Previous*4, 4, &ret);\r
+                       VFS_WriteAt(Disk->fileHandle, ofs+ret*4, 4, &eoc);\r
+                       break;\r
                }\r
-               VFS_WriteAt(Disk->fileHandle, ofs+(ret>>1)*3, 3, &val);\r
-               break;\r
-       case FAT16:\r
-               VFS_ReadAt(Disk->fileHandle, ofs+Previous*2, 2, &ret);\r
-               VFS_WriteAt(Disk->fileHandle, ofs+ret*2, 2, &eoc);\r
-               break;\r
-       case FAT32:\r
-               VFS_ReadAt(Disk->fileHandle, ofs+Previous*4, 4, &ret);\r
-               VFS_WriteAt(Disk->fileHandle, ofs+ret*4, 4, &eoc);\r
-               break;\r
+               return ret;\r
+       #if CACHE_FAT\r
        }\r
-       return ret;\r
        #endif\r
 }\r
 \r
@@ -481,41 +501,49 @@ Uint32 FAT_int_FreeCluster(tFAT_VolInfo *Disk, Uint32 Cluster)
 {\r
        Uint32  ret;\r
        #if CACHE_FAT\r
-       LOCK(Disk->lFAT);\r
-       \r
-       ret = Disk->FATCache[Cluster];\r
-       Disk->FATCache[Cluster] = 0;\r
-       \r
-       RELEASE(Disk->lFAT);\r
-       #else\r
-       Uint32  val;\r
-       LOCK(Disk->lFAT);\r
-       switch(Disk->type)\r
+       if( Disk->ClusterCount <= giFAT_MaxCachedClusters )\r
        {\r
-       case FAT12:\r
-               VFS_ReadAt(Disk->fileHandle, ofs+(Cluster>>1)*3, 3, &val);\r
-               if( Cluster & 1 ) {\r
-                       ret = val & 0xFFF0000;\r
-                       val &= 0xFFF;\r
-               }\r
-               else {\r
-                       ret = val & 0xFFF;\r
-                       val &= 0xFFF000;\r
+               LOCK(Disk->lFAT);\r
+               \r
+               ret = Disk->FATCache[Cluster];\r
+               Disk->FATCache[Cluster] = 0;\r
+               \r
+               RELEASE(Disk->lFAT);\r
+       }\r
+       else\r
+       {\r
+       #endif\r
+               Uint32  val;\r
+               Uint32  ofs = Disk->bootsect.resvSectCount*512;\r
+               LOCK(Disk->lFAT);\r
+               switch(Disk->type)\r
+               {\r
+               case FAT12:\r
+                       VFS_ReadAt(Disk->fileHandle, ofs+(Cluster>>1)*3, 3, &val);\r
+                       if( Cluster & 1 ) {\r
+                               ret = val & 0xFFF0000;\r
+                               val &= 0xFFF;\r
+                       }\r
+                       else {\r
+                               ret = val & 0xFFF;\r
+                               val &= 0xFFF000;\r
+                       }\r
+                       VFS_WriteAt(Disk->fileHandle, ofs+(Previous>>1)*3, 3, &val);\r
+                       break;\r
+               case FAT16:\r
+                       VFS_ReadAt(Disk->fileHandle, ofs+Previous*2, 2, &ret);\r
+                       val = 0;\r
+                       VFS_WriteAt(Disk->fileHandle, ofs+Cluster*2, 2, &val);\r
+                       break;\r
+               case FAT32:\r
+                       VFS_ReadAt(Disk->fileHandle, ofs+Previous*4, 4, &ret);\r
+                       val = 0;\r
+                       VFS_WriteAt(Disk->fileHandle, ofs+Cluster*2, 2, &val);\r
+                       break;\r
                }\r
-               VFS_WriteAt(Disk->fileHandle, ofs+(Previous>>1)*3, 3, &val);\r
-               break;\r
-       case FAT16:\r
-               VFS_ReadAt(Disk->fileHandle, ofs+Previous*2, 2, &ret);\r
-               val = 0;\r
-               VFS_WriteAt(Disk->fileHandle, ofs+Cluster*2, 2, &val);\r
-               break;\r
-       case FAT32:\r
-               VFS_ReadAt(Disk->fileHandle, ofs+Previous*4, 4, &ret);\r
-               val = 0;\r
-               VFS_WriteAt(Disk->fileHandle, ofs+Cluster*2, 2, &val);\r
-               break;\r
+               RELEASE(Disk->lFAT);\r
+       #if CACHE_FAT\r
        }\r
-       RELEASE(Disk->lFAT);\r
        #endif\r
        if(Disk->type == FAT12 && ret == EOC_FAT12)     ret = -1;\r
        if(Disk->type == FAT16 && ret == EOC_FAT16)     ret = -1;\r
@@ -574,14 +602,14 @@ 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("Reading past EOF (%i > %i)", offset, Node->Size);\r
                LEAVE('i', 0);\r
                return 0;\r
        }\r
        // Clamp 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
+               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
@@ -639,12 +667,12 @@ Uint64 FAT_Read(tVFS_Node *Node, Uint64 offset, Uint64 length, void *buffer)
        cluster = FAT_int_GetFatValue(disk, cluster);\r
        \r
        #if DEBUG\r
-       LOG("pos=%i", pos);\r
+       LOG("pos = %i", pos);\r
        LOG("Reading the rest of the clusters");\r
        #endif\r
        \r
        \r
-       //Read the rest of the cluster data\r
+       // Read the rest of the cluster data\r
        for( i = 1; i < count-1; i++ )\r
        {\r
                FAT_int_ReadCluster(disk, cluster, bpc, tmpBuf);\r
@@ -831,14 +859,11 @@ void FAT_int_ProperFilename(char *dest, char *src)
 char *FAT_int_CreateName(fat_filetable *ft, char *LongFileName)\r
 {\r
        char    *ret;\r
-        int    len;\r
        ENTER("pft sLongFileName", ft, LongFileName);\r
        #if USE_LFN\r
        if(LongFileName && LongFileName[0] != '\0')\r
        {       \r
-               len = strlen(LongFileName);\r
-               ret = malloc(len+1);\r
-               strcpy(ret, LongFileName);\r
+               ret = strdup(LongFileName);\r
        }\r
        else\r
        {\r
@@ -953,6 +978,7 @@ int FAT_int_ReadDirSector(tVFS_Node *Node, int Sector, fat_filetable *Buffer)
                return 1;\r
        }\r
        \r
+       LOG("addr = 0x%llx", addr);\r
        // Read Sector\r
        if(VFS_ReadAt(disk->fileHandle, addr, 512, Buffer) != 512)\r
        {\r
@@ -1083,6 +1109,7 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
        \r
        if(FAT_int_ReadDirSector(Node, ID/16, fileinfo))\r
        {\r
+               LOG("End of chain, end of dir");\r
                LEAVE('n');\r
                return NULL;\r
        }\r
@@ -1090,9 +1117,7 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
        // Offset in sector\r
        a = ID % 16;\r
 \r
-       LOG("a = %i", a);\r
-       \r
-       LOG("name[0] = 0x%x", (Uint8)fileinfo[a].name[0]);\r
+       LOG("fileinfo[%i].name[0] = 0x%x", a, (Uint8)fileinfo[a].name[0]);\r
        \r
        // Check if this is the last entry\r
        if( fileinfo[a].name[0] == '\0' ) {\r
@@ -1105,8 +1130,13 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
        // Check for empty entry\r
        if( (Uint8)fileinfo[a].name[0] == 0xE5 ) {\r
                LOG("Empty Entry");\r
+               #if 0   // Stop on empty entry?\r
+               LEAVE('n');\r
+               return NULL;    // Stop\r
+               #else\r
                LEAVE('p', VFS_SKIP);\r
                return VFS_SKIP;        // Skip\r
+               #endif\r
        }\r
        \r
        #if USE_LFN\r
@@ -1235,6 +1265,8 @@ tVFS_Node *FAT_FindDir(tVFS_Node *Node, char *Name)
                {\r
                        // Remove LFN if it does not apply\r
                        if(lfnId != i)  lfn[0] = '\0';\r
+               #else\r
+               if(fileinfo[i&0xF].attrib == ATTR_LFN)  continue;\r
                #endif\r
                        // Get Real Filename\r
                        FAT_int_ProperFilename(tmpName, fileinfo[i&0xF].name);\r

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