X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FFilesystems%2FFAT%2Ffat.c;h=1411902ad2ef4bdb6fbe32a9c9c8fdca199a7a6b;hb=13078002b01ee4f63eb2001d2ef479a2a006ea32;hp=be0a51c7f20e9a0b77e37b76a43eb7b6788ed89b;hpb=04a050f42807686dc119838c82372409246d55bb;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/Filesystems/FAT/fat.c b/KernelLand/Modules/Filesystems/FAT/fat.c index be0a51c7..1411902a 100644 --- a/KernelLand/Modules/Filesystems/FAT/fat.c +++ b/KernelLand/Modules/Filesystems/FAT/fat.c @@ -33,9 +33,9 @@ void FAT_Unmount(tVFS_Node *Node); // --- Helpers int FAT_int_GetAddress(tVFS_Node *Node, Uint64 Offset, Uint64 *Addr, Uint32 *Cluster); // --- File IO -size_t FAT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer); +size_t FAT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags); #if SUPPORT_WRITE -size_t FAT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer); +size_t FAT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags); #endif void FAT_CloseFile(tVFS_Node *node); @@ -200,8 +200,10 @@ tVFS_Node *FAT_InitDevice(const char *Device, const char **Options) // Compute Root directory offset if(diskInfo->type == FAT32) diskInfo->rootOffset = bs->spec.fat32.rootClust; - else + else { + diskInfo->RootSector = FATSz * bs->fatCount; diskInfo->rootOffset = (FATSz * bs->fatCount) / bs->spc; + } diskInfo->firstDataSect = bs->resvSectCount + (bs->fatCount * FATSz) + RootDirSectors; @@ -325,31 +327,43 @@ int FAT_int_GetAddress(tVFS_Node *Node, Uint64 Offset, Uint64 *Addr, Uint32 *Clu cluster = base_cluster = Node->Inode & 0xFFFFFFF; // Cluster ID // LOG("base cluster = 0x%07x", cluster); - - // Do Cluster Skip + + // Handle root directory // - Pre FAT32 had a reserved area for the root. - if( disk->type == FAT32 || cluster != disk->rootOffset ) + if( disk->type != FAT32 && Node == &disk->rootNode ) { - skip = Offset / disk->BytesPerCluster; - LOG("skip = %i", skip); - // Skip previous clusters - for(; skip-- ; ) - { - if(Cluster) *Cluster = cluster; - cluster = FAT_int_GetFatValue(disk, cluster); - // Check for end of cluster chain - if(cluster == GETFATVALUE_EOC) { LEAVE('i', 1); return 1; } + Uint32 root_byte_count = disk->bootsect.files_in_root * 32 ; + if( Offset >= root_byte_count ) { + LOG("FAT12/16 root out of range (%i >= %i)", Offset, root_byte_count); + LEAVE('i', 1); + return 1; } - if(Cluster) *Cluster = cluster; + LOG("FAT12/16 root"); + + // Calculate address + addr = (disk->bootsect.resvSectCount + disk->RootSector) * disk->bootsect.bps; + addr += Offset; + + LOG("addr = %llx", addr); + *Addr = addr; + LEAVE('i', 0); + return 0; } - else { - // TODO: Bounds checking on root -// LOG("Root cluster count %i", disk->bootsect.files_in_root*32/disk->BytesPerCluster); - // Increment by clusters in offset - cluster += Offset / disk->BytesPerCluster; + + // Do Cluster Skip + skip = Offset / disk->BytesPerCluster; + LOG("skip = %i", skip); + // Skip previous clusters + for(; skip-- ; ) + { + if(Cluster) *Cluster = cluster; + cluster = FAT_int_GetFatValue(disk, cluster); + // Check for end of cluster chain + if(cluster == GETFATVALUE_EOC) { LEAVE('i', 1); return 1; } } + if(Cluster) *Cluster = cluster; -// LOG("cluster = 0x%07x", cluster); + LOG("cluster = 0x%07x", cluster); // Bounds Checking (Used to spot corruption) if(cluster > disk->ClusterCount + 2) @@ -361,15 +375,8 @@ int FAT_int_GetAddress(tVFS_Node *Node, Uint64 Offset, Uint64 *Addr, Uint32 *Clu } // Compute Offsets - // - Pre FAT32 cluster base (in sectors) - if( base_cluster == disk->rootOffset && disk->type != FAT32 ) { - addr = disk->bootsect.resvSectCount * disk->bootsect.bps; - addr += cluster * disk->BytesPerCluster; - } - else { - addr = disk->firstDataSect * disk->bootsect.bps; - addr += (cluster - 2) * disk->BytesPerCluster; - } + addr = disk->firstDataSect * disk->bootsect.bps; + addr += (cluster - 2) * disk->BytesPerCluster; // In-cluster offset addr += Offset % disk->BytesPerCluster; @@ -386,7 +393,7 @@ int FAT_int_GetAddress(tVFS_Node *Node, Uint64 Offset, Uint64 *Addr, Uint32 *Clu /** * \brief Reads data from a specified file */ -size_t FAT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer) +size_t FAT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags) { int preSkip, count; Uint64 final_bytes; @@ -428,6 +435,8 @@ size_t FAT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer) } } + // TODO: Handle (Flags & VFS_IOFLAG_NOBLOCK) + // Reading from within one cluster if((int)Offset + (int)Length <= bpc) { @@ -505,7 +514,7 @@ size_t FAT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer) * \param Length Size of data to write * \param Buffer Data source */ -size_t FAT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer) +size_t FAT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags) { tFAT_VolInfo *disk = Node->ImplPtr; char tmpBuf[disk->BytesPerCluster]; @@ -515,6 +524,7 @@ size_t FAT_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffe off_t original_offset = Offset; if(Offset > Node->Size) return 0; + // TODO: Handle (Flags & VFS_IOFLAG_NOBLOCK) ENTER("pNode Xoffset xlength pbuffer", Node, Offset, Length, Buffer);