Misc code cleanup
[tpg/acess2.git] / KernelLand / Kernel / vfs / io.c
1 /*
2  * AcessMicro VFS
3  * - File IO Passthru's
4  */
5 #define DEBUG   0
6 #include <acess.h>
7 #include <vfs.h>
8 #include <vfs_ext.h>
9 #include <vfs_int.h>
10
11 // === CODE ===
12 /**
13  * \fn Uint64 VFS_Read(int FD, Uint64 Length, void *Buffer)
14  * \brief Read data from a node (file)
15  */
16 size_t VFS_Read(int FD, size_t Length, void *Buffer)
17 {
18         tVFS_Handle     *h;
19         size_t  ret;
20         
21         ENTER("iFD XLength pBuffer", FD, Length, Buffer);
22         
23         h = VFS_GetHandle(FD);
24         if(!h) {
25                 LOG("Bad Handle");
26                 LEAVE_RET('i', -1);
27         }
28         
29         if( !(h->Mode & VFS_OPENFLAG_READ) ) {
30                 LOG("Bad mode");
31                 LEAVE_RET('i', -1);
32         }
33         if( (h->Node->Flags & VFS_FFLAG_DIRECTORY) ) {
34                 LOG("Reading directory");
35                 LEAVE_RET('i', -1);
36         }
37
38         if(!h->Node->Type || !h->Node->Type->Read) {
39                 LOG("No read method");
40                 LEAVE_RET('i', -1);
41         }
42
43         if( !MM_GetPhysAddr(h->Node->Type->Read) ) {
44                 Log_Error("VFS", "Node type %p(%s) read method is junk %p", h->Node->Type, h->Node, h->Node->Type->TypeName,
45                         h->Node->Type->Read);
46                 LEAVE_RET('i', -1);
47         }
48         
49         ret = h->Node->Type->Read(h->Node, h->Position, Length, Buffer);
50         if(ret == (size_t)-1)   LEAVE_RET('i', -1);
51         
52         h->Position += ret;
53         LEAVE('X', ret);
54         return ret;
55 }
56
57 /**
58  * \fn Uint64 VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer)
59  * \brief Read data from a given offset (atomic)
60  */
61 size_t VFS_ReadAt(int FD, Uint64 Offset, size_t Length, void *Buffer)
62 {
63         tVFS_Handle     *h;
64         size_t  ret;
65         
66         h = VFS_GetHandle(FD);
67         if(!h)  return -1;
68         
69         if( !(h->Mode & VFS_OPENFLAG_READ) )    return -1;
70         if( h->Node->Flags & VFS_FFLAG_DIRECTORY )      return -1;
71
72         if( !h->Node->Type || !h->Node->Type->Read) {
73                 Warning("VFS_ReadAt - Node %p, does not have a read method", h->Node);
74                 return 0;
75         }
76
77         if( !MM_GetPhysAddr(h->Node->Type->Read) ) {
78                 Log_Error("VFS", "Node type %p(%s) read method is junk %p", h->Node->Type, h->Node, h->Node->Type->TypeName,
79                         h->Node->Type->Read);
80                 LEAVE_RET('i', -1);
81         }
82         
83         ret = h->Node->Type->Read(h->Node, Offset, Length, Buffer);
84         if(ret == (size_t)-1)   return -1;
85         return ret;
86 }
87
88 /**
89  * \fn Uint64 VFS_Write(int FD, Uint64 Length, const void *Buffer)
90  * \brief Read data from a node (file)
91  */
92 size_t VFS_Write(int FD, size_t Length, const void *Buffer)
93 {
94         tVFS_Handle     *h;
95         size_t  ret;
96         
97         h = VFS_GetHandle(FD);
98         if(!h)  return -1;
99         
100         if( !(h->Mode & VFS_OPENFLAG_WRITE) )   return -1;
101         if( h->Node->Flags & VFS_FFLAG_DIRECTORY )      return -1;
102
103         if( !h->Node->Type || !h->Node->Type->Write )   return 0;
104
105         if( !MM_GetPhysAddr(h->Node->Type->Write) ) {
106                 Log_Error("VFS", "Node type %p(%s) write method is junk %p", h->Node->Type, h->Node, h->Node->Type->TypeName,
107                         h->Node->Type->Write);
108                 return -1;
109         }
110         
111         ret = h->Node->Type->Write(h->Node, h->Position, Length, Buffer);
112         if(ret == (size_t)-1)   return -1;
113
114         h->Position += ret;
115         return ret;
116 }
117
118 /**
119  * \fn Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, const void *Buffer)
120  * \brief Write data to a file at a given offset
121  */
122 size_t VFS_WriteAt(int FD, Uint64 Offset, size_t Length, const void *Buffer)
123 {
124         tVFS_Handle     *h;
125         size_t  ret;
126         
127         h = VFS_GetHandle(FD);
128         if(!h)  return -1;
129         
130         if( !(h->Mode & VFS_OPENFLAG_WRITE) )   return -1;
131         if( h->Node->Flags & VFS_FFLAG_DIRECTORY )      return -1;
132
133         if(!h->Node->Type || !h->Node->Type->Write)     return 0;
134
135         if( !MM_GetPhysAddr(h->Node->Type->Write) ) {
136                 Log_Error("VFS", "Node type %p(%s) write method is junk %p", h->Node->Type, h->Node, h->Node->Type->TypeName,
137                         h->Node->Type->Write);
138                 return -1;
139         }
140         ret = h->Node->Type->Write(h->Node, Offset, Length, Buffer);
141         if(ret == (size_t)-1)   return -1;
142         return ret;
143 }
144
145 /**
146  * \fn Uint64 VFS_Tell(int FD)
147  * \brief Returns the current file position
148  */
149 Uint64 VFS_Tell(int FD)
150 {
151         tVFS_Handle     *h;
152         
153         h = VFS_GetHandle(FD);
154         if(!h)  return -1;
155         
156         return h->Position;
157 }
158
159 /**
160  * \fn int VFS_Seek(int FD, Sint64 Offset, int Whence)
161  * \brief Seek to a new location
162  * \param FD    File descriptor
163  * \param Offset        Where to go
164  * \param Whence        From where
165  */
166 int VFS_Seek(int FD, Sint64 Offset, int Whence)
167 {
168         tVFS_Handle     *h;
169         
170         h = VFS_GetHandle(FD);
171         if(!h)  return -1;
172         
173         //Log_Debug("VFS", "VFS_Seek: (fd=0x%x, Offset=0x%llx, Whence=%i)",
174         //      FD, Offset, Whence);
175         
176         // Set relative to current position
177         if(Whence == 0) {
178                 h->Position += Offset;
179                 return 0;
180         }
181         
182         // Set relative to end of file
183         if(Whence < 0) {
184                 if( h->Node->Size == (Uint64)-1 )       return -1;
185
186                 h->Position = h->Node->Size - Offset;
187                 return 0;
188         }
189         
190         // Set relative to start of file
191         h->Position = Offset;
192         return 0;
193 }
194
195 /**
196  * \fn int VFS_IOCtl(int FD, int ID, void *Buffer)
197  * \brief Call an IO Control on a file
198  */
199 int VFS_IOCtl(int FD, int ID, void *Buffer)
200 {
201         tVFS_Handle     *h;
202         
203         h = VFS_GetHandle(FD);
204         if(!h)  return -1;
205
206         if(!h->Node->Type || !h->Node->Type->IOCtl)     return -1;
207         return h->Node->Type->IOCtl(h->Node, ID, Buffer);
208 }
209
210 /**
211  * \fn int VFS_FInfo(int FD, tFInfo *Dest, int MaxACLs)
212  * \brief Retrieve file information
213  * \return Number of ACLs stored
214  */
215 int VFS_FInfo(int FD, tFInfo *Dest, int MaxACLs)
216 {
217         tVFS_Handle     *h;
218          int    max;
219         
220         h = VFS_GetHandle(FD);
221         if(!h)  return -1;
222
223         if( h->Mount )
224                 Dest->mount = h->Mount->Identifier;
225         else
226                 Dest->mount = 0;
227         Dest->inode = h->Node->Inode;   
228         Dest->uid = h->Node->UID;
229         Dest->gid = h->Node->GID;
230         Dest->size = h->Node->Size;
231         Dest->atime = h->Node->ATime;
232         Dest->ctime = h->Node->MTime;
233         Dest->mtime = h->Node->CTime;
234         Dest->numacls = h->Node->NumACLs;
235         
236         Dest->flags = 0;
237         if(h->Node->Flags & VFS_FFLAG_DIRECTORY)        Dest->flags |= 0x10;
238         if(h->Node->Flags & VFS_FFLAG_SYMLINK)  Dest->flags |= 0x20;
239         
240         max = (MaxACLs < h->Node->NumACLs) ? MaxACLs : h->Node->NumACLs;
241         memcpy(&Dest->acls, h->Node->ACLs, max*sizeof(tVFS_ACL));
242         
243         return max;
244 }
245
246 // === EXPORTS ===
247 EXPORT(VFS_Read);
248 EXPORT(VFS_Write);
249 EXPORT(VFS_ReadAt);
250 EXPORT(VFS_WriteAt);
251 EXPORT(VFS_IOCtl);
252 EXPORT(VFS_Seek);
253 EXPORT(VFS_Tell);

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