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

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