Usermode/libc++ - Implement map::insert and map::erase
[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   0
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, Uint Flags)
19 {
20         tExt2_Disk      *disk = Node->ImplPtr;
21         tExt2_Inode     *inode = (void*)(Node+1);
22         Uint64  base;
23         Uint    block;
24         Uint64  remLen;
25         
26         ENTER("pNode XOffset xLength pBuffer", Node, Offset, Length, Buffer);
27         
28         // Sanity Checks
29         if(Offset >= inode->i_size) {
30                 LEAVE('i', 0);
31                 return 0;
32         }
33         if(Offset + Length > inode->i_size)
34                 Length = inode->i_size - Offset;
35         
36         block = Offset / disk->BlockSize;
37         Offset = Offset % disk->BlockSize;
38         base = Ext2_int_GetBlockAddr(disk, inode->i_block, block);
39         if(base == 0) {
40                 Log_Warning("EXT2", "NULL Block Detected in INode 0x%llx (Block %i)", Node->Inode, block);
41                 LEAVE('i', 0);
42                 return 0;
43         }
44         
45         // Read only block
46         if(Length <= disk->BlockSize - Offset)
47         {
48                 VFS_ReadAt( disk->FD, base+Offset, Length, Buffer);
49                 LEAVE('X', Length);
50                 return Length;
51         }
52         
53         // Read first block
54         // TODO: If (Flags & VFS_IOFLAG_NOBLOCK) trigger read and return EWOULDBLOCK?
55         remLen = Length;
56         VFS_ReadAt( disk->FD, base + Offset, disk->BlockSize - Offset, Buffer);
57         remLen -= disk->BlockSize - Offset;
58         Buffer += disk->BlockSize - Offset;
59         block ++;
60         
61         // Read middle blocks
62         while(remLen > disk->BlockSize)
63         {
64                 base = Ext2_int_GetBlockAddr(disk, inode->i_block, block);
65                 if(base == 0) {
66                         Log_Warning("EXT2", "NULL Block Detected in INode 0x%llx", Node->Inode);
67                         LEAVE('i', 0);
68                         return 0;
69                 }
70                 VFS_ReadAt( disk->FD, base, disk->BlockSize, Buffer);
71                 Buffer += disk->BlockSize;
72                 remLen -= disk->BlockSize;
73                 block ++;
74         }
75         
76         // Read last block
77         base = Ext2_int_GetBlockAddr(disk, inode->i_block, block);
78         VFS_ReadAt( disk->FD, base, remLen, Buffer);
79         
80         LEAVE('X', Length);
81         return Length;
82 }

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