Merge branch 'master' of ted.mutabah.net:acess2
[tpg/acess2.git] / KernelLand / Modules / Filesystems / Ext2 / read.c
1 /*
2  * Acess OS
3  * Ext2 Driver Version 1
4  */
5 /**
6  * \file read.c
7  * \brief Second Extended Filesystem Driver
8  * \todo Implement file full write support
9  */
10 #define DEBUG   1
11 #define VERBOSE 0
12 #include "ext2_common.h"
13
14 // === CODE ===
15 /**
16  * \brief Read from a file
17  */
18 size_t Ext2_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
19 {
20         tExt2_Disk      *disk = Node->ImplPtr;
21         tExt2_Inode     inode;
22         Uint64  base;
23         Uint    block;
24         Uint64  remLen;
25         
26         ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
27         
28         // Get Inode
29         Ext2_int_ReadInode(disk, Node->Inode, &inode);
30         
31         // Sanity Checks
32         if(Offset >= inode.i_size) {
33                 LEAVE('i', 0);
34                 return 0;
35         }
36         if(Offset + Length > inode.i_size)
37                 Length = inode.i_size - Offset;
38         
39         block = Offset / disk->BlockSize;
40         Offset = Offset / disk->BlockSize;
41         base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
42         if(base == 0) {
43                 Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode);
44                 LEAVE('i', 0);
45                 return 0;
46         }
47         
48         // Read only block
49         if(Length <= disk->BlockSize - Offset)
50         {
51                 VFS_ReadAt( disk->FD, base+Offset, Length, Buffer);
52                 LEAVE('X', Length);
53                 return Length;
54         }
55         
56         // Read first block
57         remLen = Length;
58         VFS_ReadAt( disk->FD, base + Offset, disk->BlockSize - Offset, Buffer);
59         remLen -= disk->BlockSize - Offset;
60         Buffer += disk->BlockSize - Offset;
61         block ++;
62         
63         // Read middle blocks
64         while(remLen > disk->BlockSize)
65         {
66                 base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
67                 if(base == 0) {
68                         Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode);
69                         LEAVE('i', 0);
70                         return 0;
71                 }
72                 VFS_ReadAt( disk->FD, base, disk->BlockSize, Buffer);
73                 Buffer += disk->BlockSize;
74                 remLen -= disk->BlockSize;
75                 block ++;
76         }
77         
78         // Read last block
79         base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
80         VFS_ReadAt( disk->FD, base, remLen, Buffer);
81         
82         LEAVE('X', Length);
83         return Length;
84 }

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