Kernel - Added 'Flags' param to VFS Read/Write/FindDir
[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, Uint Flags)
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         // TODO: If (Flags & VFS_IOFLAG_NOBLOCK) trigger read and return EWOULDBLOCK?
58         remLen = Length;
59         VFS_ReadAt( disk->FD, base + Offset, disk->BlockSize - Offset, Buffer);
60         remLen -= disk->BlockSize - Offset;
61         Buffer += disk->BlockSize - Offset;
62         block ++;
63         
64         // Read middle blocks
65         while(remLen > disk->BlockSize)
66         {
67                 base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
68                 if(base == 0) {
69                         Log_Warning("EXT2", "NULL Block Detected in INode 0x%llx", Node->Inode);
70                         LEAVE('i', 0);
71                         return 0;
72                 }
73                 VFS_ReadAt( disk->FD, base, disk->BlockSize, Buffer);
74                 Buffer += disk->BlockSize;
75                 remLen -= disk->BlockSize;
76                 block ++;
77         }
78         
79         // Read last block
80         base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
81         VFS_ReadAt( disk->FD, base, remLen, Buffer);
82         
83         LEAVE('X', Length);
84         return Length;
85 }

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