Various changes, most of them involving the FAT and Ext2 Drivers, adding write support
[tpg/acess2.git] / Modules / Filesystems / Ext2 / read.c
diff --git a/Modules/Filesystems/Ext2/read.c b/Modules/Filesystems/Ext2/read.c
new file mode 100644 (file)
index 0000000..81f5ee6
--- /dev/null
@@ -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;
+}

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