X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=KernelLand%2FModules%2FFilesystems%2FFAT%2Ffatio.c;h=7bf62efc6c89b57311a8bc10fc17f5d005eaeb30;hb=24a52dc748126b1449a104c7f756b201c8ac1b02;hp=43bd62268d2d6fefe0ed25ecb4341c72b22adae2;hpb=17be74ac4510cfe4962b1423e70c3b3a0333102f;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/Filesystems/FAT/fatio.c b/KernelLand/Modules/Filesystems/FAT/fatio.c index 43bd6226..7bf62efc 100644 --- a/KernelLand/Modules/Filesystems/FAT/fatio.c +++ b/KernelLand/Modules/Filesystems/FAT/fatio.c @@ -5,7 +5,7 @@ * fatio.c * - FAT Manipulation and Cluster IO */ -#define DEBUG 1 +#define DEBUG 0 #include #include #include "common.h" @@ -20,14 +20,15 @@ Uint32 FAT_int_GetFatValue(tFAT_VolInfo *Disk, Uint32 cluster) Uint32 val = 0; Uint32 ofs; ENTER("pDisk xCluster", Disk, cluster); + Mutex_Acquire( &Disk->lFAT ); #if CACHE_FAT if( Disk->ClusterCount <= giFAT_MaxCachedClusters ) { val = Disk->FATCache[cluster]; - if(Disk->type == FAT12 && val == EOC_FAT12) val = -1; - if(Disk->type == FAT16 && val == EOC_FAT16) val = -1; - if(Disk->type == FAT32 && val == EOC_FAT32) val = -1; + if(Disk->type == FAT12 && val == EOC_FAT12) val = GETFATVALUE_EOC; + if(Disk->type == FAT16 && val == EOC_FAT16) val = GETFATVALUE_EOC; + if(Disk->type == FAT32 && val == EOC_FAT32) val = GETFATVALUE_EOC; } else { @@ -35,14 +36,15 @@ Uint32 FAT_int_GetFatValue(tFAT_VolInfo *Disk, Uint32 cluster) ofs = Disk->bootsect.resvSectCount*512; if(Disk->type == FAT12) { VFS_ReadAt(Disk->fileHandle, ofs+(cluster/2)*3, 3, &val); - val = (cluster & 1 ? val>>12 : val & 0xFFF); - if(val == EOC_FAT12) val = -1; + LOG("3 bytes at 0x%x are (Uint32)0x%x", ofs+(cluster/2)*3, val); + val = (cluster & 1) ? (val>>12) : (val & 0xFFF); + if(val == EOC_FAT12) val = GETFATVALUE_EOC; } else if(Disk->type == FAT16) { VFS_ReadAt(Disk->fileHandle, ofs+cluster*2, 2, &val); - if(val == EOC_FAT16) val = -1; + if(val == EOC_FAT16) val = GETFATVALUE_EOC; } else { VFS_ReadAt(Disk->fileHandle, ofs+cluster*4, 4, &val); - if(val == EOC_FAT32) val = -1; + if(val == EOC_FAT32) val = GETFATVALUE_EOC; } #if CACHE_FAT } @@ -58,20 +60,22 @@ Uint32 FAT_int_GetFatValue(tFAT_VolInfo *Disk, Uint32 cluster) */ Uint32 FAT_int_AllocateCluster(tFAT_VolInfo *Disk, Uint32 Previous) { - Uint32 ret = -1, eoc; - - switch(Disk->type) - { - case FAT12: eoc = EOC_FAT12; break; - case FAT16: eoc = EOC_FAT16; break; - case FAT32: eoc = EOC_FAT32; break; - default: return 0; - } + Uint32 ret = -1; #if CACHE_FAT if( Disk->ClusterCount <= giFAT_MaxCachedClusters ) { int bFoundCluster = 0; + Uint32 eoc; + + switch(Disk->type) + { + case FAT12: eoc = EOC_FAT12; break; + case FAT16: eoc = EOC_FAT16; break; + case FAT32: eoc = EOC_FAT32; break; + default: return 0; + } + Mutex_Acquire(&Disk->lFAT); if( Previous != -1 ) { @@ -106,6 +110,7 @@ Uint32 FAT_int_AllocateCluster(tFAT_VolInfo *Disk, Uint32 Previous) } Mutex_Release(&Disk->lFAT); + LOG("Allocated cluster %x", ret); return ret; } else @@ -135,7 +140,7 @@ Uint32 FAT_int_AllocateCluster(tFAT_VolInfo *Disk, Uint32 Previous) // Search within the same block as the previous cluster first do { - VFS_ReadAt(Disk->fileHandle, base + block, block_size, sector_data); + VFS_ReadAt(Disk->fileHandle, base + block*block_size, block_size, sector_data); for( block_ofs = 0; block_ofs < ents_per_block_12; block_ofs ++ ) { Uint32 *valptr = (void*)( sector_data + block_ofs / 2 * 3 ); @@ -164,16 +169,21 @@ Uint32 FAT_int_AllocateCluster(tFAT_VolInfo *Disk, Uint32 Previous) VFS_WriteAt(Disk->fileHandle, base + block, block_size, sector_data); // Note the new cluster in the chain - VFS_ReadAt(Disk->fileHandle, base + (Previous>>1)*3, 3, &val); - if( ret & 1 ) { - val &= 0x000FFF; - val |= ret << 12; - } - else { - val &= 0xFFF000; - val |= ret << 0; + if( Previous != -1 ) + { + LOG("Updating cluster %x to point to %x (offset %x)", Previous, ret, + base + (Previous>>1)*3); + VFS_ReadAt(Disk->fileHandle, base + (Previous>>1)*3, 3, &val); + if( Previous & 1 ) { + val &= 0x000FFF; + val |= ret << 12; + } + else { + val &= 0xFFF000; + val |= ret << 0; + } + VFS_WriteAt(Disk->fileHandle, base + (Previous>>1)*3, 3, &val); } - VFS_WriteAt(Disk->fileHandle, base + (Previous>>1)*3, 3, &val); } break; case FAT16: @@ -188,6 +198,7 @@ Uint32 FAT_int_AllocateCluster(tFAT_VolInfo *Disk, Uint32 Previous) break; } Mutex_Release(&Disk->lFAT); + LOG("Allocated cluster %x", ret); return ret; #if CACHE_FAT } @@ -201,6 +212,13 @@ Uint32 FAT_int_AllocateCluster(tFAT_VolInfo *Disk, Uint32 Previous) Uint32 FAT_int_FreeCluster(tFAT_VolInfo *Disk, Uint32 Cluster) { Uint32 ret; + + if( Cluster < 2 || Cluster > Disk->ClusterCount ) // oops? + { + Log_Notice("FAT", "Cluster 0x%x is out of range (2 ... 0x%x)", + Cluster, Disk->ClusterCount-1); + return -1; + } Mutex_Acquire(&Disk->lFAT); #if CACHE_FAT @@ -213,40 +231,50 @@ Uint32 FAT_int_FreeCluster(tFAT_VolInfo *Disk, Uint32 Cluster) else { #endif - Uint32 val; + Uint32 val = 0; Uint32 ofs = Disk->bootsect.resvSectCount*512; switch(Disk->type) { case FAT12: VFS_ReadAt(Disk->fileHandle, ofs+(Cluster>>1)*3, 3, &val); + val = LittleEndian32(val); if( Cluster & 1 ) { - ret = val & 0xFFF0000; + ret = (val >> 12) & 0xFFF; val &= 0xFFF; } else { ret = val & 0xFFF; val &= 0xFFF000; } + val = LittleEndian32(val); VFS_WriteAt(Disk->fileHandle, ofs+(Cluster>>1)*3, 3, &val); break; case FAT16: VFS_ReadAt(Disk->fileHandle, ofs+Cluster*2, 2, &ret); + ret = LittleEndian16(ret); val = 0; VFS_WriteAt(Disk->fileHandle, ofs+Cluster*2, 2, &val); break; case FAT32: VFS_ReadAt(Disk->fileHandle, ofs+Cluster*4, 4, &ret); + ret = LittleEndian32(ret); val = 0; - VFS_WriteAt(Disk->fileHandle, ofs+Cluster*2, 2, &val); + VFS_WriteAt(Disk->fileHandle, ofs+Cluster*2, 4, &val); break; } #if CACHE_FAT } #endif Mutex_Release(&Disk->lFAT); + LOG("ret = %07x, eoc = %07x", ret, EOC_FAT12); + if(ret == 0) { + Log_Notice("FAT", "Cluster 0x%x was already free", Cluster); + return -1; + } if(Disk->type == FAT12 && ret == EOC_FAT12) ret = -1; if(Disk->type == FAT16 && ret == EOC_FAT16) ret = -1; if(Disk->type == FAT32 && ret == EOC_FAT32) ret = -1; + LOG("ret = %07x", ret); return ret; } #endif