X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FFilesystems%2FExt2%2Fread.c;fp=Modules%2FFilesystems%2FExt2%2Fread.c;h=81f5ee64fec7cc3ef3cefbf3601d154965929b87;hb=923a9dc473851ec2bb1c94021bbf139724e7e8a5;hp=0000000000000000000000000000000000000000;hpb=f4646f2b6d64e42d1eec1d97877ae23eac6863f6;p=tpg%2Facess2.git diff --git a/Modules/Filesystems/Ext2/read.c b/Modules/Filesystems/Ext2/read.c new file mode 100644 index 00000000..81f5ee64 --- /dev/null +++ b/Modules/Filesystems/Ext2/read.c @@ -0,0 +1,88 @@ +/* + * Acess OS + * Ext2 Driver Version 1 + */ +/** + * \file read.c + * \brief Second Extended Filesystem Driver + * \todo Implement file full write support + */ +#define DEBUG 1 +#define VERBOSE 0 +#include "ext2_common.h" + +// === PROTOTYPES === +Uint64 Ext2_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer); + +// === CODE === +/** + * \fn Uint64 Ext2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) + * \brief Read from a file + */ +Uint64 Ext2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +{ + tExt2_Disk *disk = Node->ImplPtr; + tExt2_Inode inode; + Uint64 base; + Uint block; + Uint64 remLen; + + ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); + + // Get Inode + Ext2_int_ReadInode(disk, Node->Inode, &inode); + + // Sanity Checks + if(Offset >= inode.i_size) { + LEAVE('i', 0); + return 0; + } + if(Offset + Length > inode.i_size) + Length = inode.i_size - Offset; + + block = Offset / disk->BlockSize; + Offset = Offset / disk->BlockSize; + base = Ext2_int_GetBlockAddr(disk, inode.i_block, block); + if(base == 0) { + Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode); + LEAVE('i', 0); + return 0; + } + + // Read only block + if(Length <= disk->BlockSize - Offset) + { + VFS_ReadAt( disk->FD, base+Offset, Length, Buffer); + LEAVE('X', Length); + return Length; + } + + // Read first block + remLen = Length; + VFS_ReadAt( disk->FD, base + Offset, disk->BlockSize - Offset, Buffer); + remLen -= disk->BlockSize - Offset; + Buffer += disk->BlockSize - Offset; + block ++; + + // Read middle blocks + while(remLen > disk->BlockSize) + { + base = Ext2_int_GetBlockAddr(disk, inode.i_block, block); + if(base == 0) { + Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode); + LEAVE('i', 0); + return 0; + } + VFS_ReadAt( disk->FD, base, disk->BlockSize, Buffer); + Buffer += disk->BlockSize; + remLen -= disk->BlockSize; + block ++; + } + + // Read last block + base = Ext2_int_GetBlockAddr(disk, inode.i_block, block); + VFS_ReadAt( disk->FD, base, remLen, Buffer); + + LEAVE('X', Length); + return Length; +}