Merge branch 'master' of git://git.ucc.asn.au/tpg/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 // === PROTOTYPES ===
15 Uint64          Ext2_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);
16
17 // === CODE ===
18 /**
19  * \fn Uint64 Ext2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
20  * \brief Read from a file
21  */
22 Uint64 Ext2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
23 {
24         tExt2_Disk      *disk = Node->ImplPtr;
25         tExt2_Inode     inode;
26         Uint64  base;
27         Uint    block;
28         Uint64  remLen;
29         
30         ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
31         
32         // Get Inode
33         Ext2_int_ReadInode(disk, Node->Inode, &inode);
34         
35         // Sanity Checks
36         if(Offset >= inode.i_size) {
37                 LEAVE('i', 0);
38                 return 0;
39         }
40         if(Offset + Length > inode.i_size)
41                 Length = inode.i_size - Offset;
42         
43         block = Offset / disk->BlockSize;
44         Offset = Offset / disk->BlockSize;
45         base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
46         if(base == 0) {
47                 Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode);
48                 LEAVE('i', 0);
49                 return 0;
50         }
51         
52         // Read only block
53         if(Length <= disk->BlockSize - Offset)
54         {
55                 VFS_ReadAt( disk->FD, base+Offset, Length, Buffer);
56                 LEAVE('X', Length);
57                 return Length;
58         }
59         
60         // Read first block
61         remLen = Length;
62         VFS_ReadAt( disk->FD, base + Offset, disk->BlockSize - Offset, Buffer);
63         remLen -= disk->BlockSize - Offset;
64         Buffer += disk->BlockSize - Offset;
65         block ++;
66         
67         // Read middle blocks
68         while(remLen > disk->BlockSize)
69         {
70                 base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
71                 if(base == 0) {
72                         Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode);
73                         LEAVE('i', 0);
74                         return 0;
75                 }
76                 VFS_ReadAt( disk->FD, base, disk->BlockSize, Buffer);
77                 Buffer += disk->BlockSize;
78                 remLen -= disk->BlockSize;
79                 block ++;
80         }
81         
82         // Read last block
83         base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
84         VFS_ReadAt( disk->FD, base, remLen, Buffer);
85         
86         LEAVE('X', Length);
87         return Length;
88 }

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