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
\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
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
{\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
{\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
\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
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