X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fvfs%2Fio.c;h=271e920de7919d49ab8b6964aa597e6799d9a20f;hb=3c3c26b58055f511af5b7f0c3ab22e83961c775f;hp=e7a2a0684370171cbbe3d1ec1889887cfd2ce2bc;hpb=51ab5f489bc356940c95cc936fd0508e8f07ea97;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/vfs/io.c b/KernelLand/Kernel/vfs/io.c index e7a2a068..271e920d 100644 --- a/KernelLand/Kernel/vfs/io.c +++ b/KernelLand/Kernel/vfs/io.c @@ -1,37 +1,62 @@ /* - * AcessMicro VFS - * - File IO Passthru's + * Acess2 Kernel + * - By John Hodge (thePowersGang) + * + * vfs/io.c + * - VFS IO Handling (Read/Write) + * + * TODO: VFS-level caching to support non-blocking IO? */ #define DEBUG 0 #include -#include "vfs.h" -#include "vfs_int.h" +#include +#include +#include // === CODE === /** * \fn Uint64 VFS_Read(int FD, Uint64 Length, void *Buffer) * \brief Read data from a node (file) */ -Uint64 VFS_Read(int FD, Uint64 Length, void *Buffer) +size_t VFS_Read(int FD, size_t Length, void *Buffer) { tVFS_Handle *h; - Uint64 ret; - - ENTER("iFD XLength pBuffer", FD, Length, Buffer); + size_t ret; h = VFS_GetHandle(FD); - if(!h) LEAVE_RET('i', -1); + if(!h) { + LOG("FD%i is a bad Handle", FD); + return -1; + } - if( !(h->Mode & VFS_OPENFLAG_READ) || h->Node->Flags & VFS_FFLAG_DIRECTORY ) - LEAVE_RET('i', -1); + if( !(h->Mode & VFS_OPENFLAG_READ) ) { + LOG("FD%i not open for reading", FD); + return -1; + } + if( (h->Node->Flags & VFS_FFLAG_DIRECTORY) ) { + LOG("FD%i is a directory", FD); + return -1; + } - if(!h->Node->Type || !h->Node->Type->Read) LEAVE_RET('i', 0); + if(!h->Node->Type || !h->Node->Type->Read) { + LOG("FD%i has no read method", FD); + return -1; + } + + if( !MM_GetPhysAddr(h->Node->Type->Read) ) { + Log_Error("VFS", "Node type %p(%s) read method is junk %p", + h->Node->Type, h->Node, h->Node->Type->TypeName, + h->Node->Type->Read); + return -1; + } - ret = h->Node->Type->Read(h->Node, h->Position, Length, Buffer); - if(ret == -1) LEAVE_RET('i', -1); + Uint flags = 0; + flags |= (h->Mode & VFS_OPENFLAG_NONBLOCK) ? VFS_IOFLAG_NOBLOCK : 0; + ret = h->Node->Type->Read(h->Node, h->Position, Length, Buffer, flags); + if(ret != Length) LOG("%i/%i read", ret, Length); + if(ret == (size_t)-1) return -1; h->Position += ret; - LEAVE('X', ret); return ret; } @@ -39,10 +64,10 @@ Uint64 VFS_Read(int FD, Uint64 Length, void *Buffer) * \fn Uint64 VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer) * \brief Read data from a given offset (atomic) */ -Uint64 VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer) +size_t VFS_ReadAt(int FD, Uint64 Offset, size_t Length, void *Buffer) { tVFS_Handle *h; - Uint64 ret; + size_t ret; h = VFS_GetHandle(FD); if(!h) return -1; @@ -54,8 +79,18 @@ Uint64 VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer) Warning("VFS_ReadAt - Node %p, does not have a read method", h->Node); return 0; } - ret = h->Node->Type->Read(h->Node, Offset, Length, Buffer); - if(ret == -1) return -1; + + if( !MM_GetPhysAddr(h->Node->Type->Read) ) { + Log_Error("VFS", "Node type %p(%s) read method is junk %p", + h->Node->Type, h->Node->Type->TypeName, + h->Node->Type->Read); + } + + Uint flags = 0; + flags |= (h->Mode & VFS_OPENFLAG_NONBLOCK) ? VFS_IOFLAG_NOBLOCK : 0; + ret = h->Node->Type->Read(h->Node, Offset, Length, Buffer, flags); + if(ret != Length) LOG("%i/%i read", ret, Length); + if(ret == (size_t)-1) return -1; return ret; } @@ -63,21 +98,48 @@ Uint64 VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer) * \fn Uint64 VFS_Write(int FD, Uint64 Length, const void *Buffer) * \brief Read data from a node (file) */ -Uint64 VFS_Write(int FD, Uint64 Length, const void *Buffer) +size_t VFS_Write(int FD, size_t Length, const void *Buffer) { tVFS_Handle *h; - Uint64 ret; + size_t ret; h = VFS_GetHandle(FD); - if(!h) return -1; + if(!h) { + LOG("FD%i is not open", FD); + errno = EBADF; + return -1; + } - if( !(h->Mode & VFS_OPENFLAG_WRITE) ) return -1; - if( h->Node->Flags & VFS_FFLAG_DIRECTORY ) return -1; + if( !(h->Mode & VFS_OPENFLAG_WRITE) ) { + LOG("FD%i not opened for writing", FD); + errno = EBADF; + return -1; + } + if( h->Node->Flags & VFS_FFLAG_DIRECTORY ) { + LOG("FD%i is a directory", FD); + errno = EISDIR; + return -1; + } + + if( !h->Node->Type || !h->Node->Type->Write ) { + LOG("FD%i has no write method", FD); + errno = EINTERNAL; + return 0; + } - if( !h->Node->Type || !h->Node->Type->Write ) return 0; + if( !MM_GetPhysAddr(h->Node->Type->Write) ) { + Log_Error("VFS", "Node type %p(%s) write method is junk %p", + h->Node->Type, h->Node->Type->TypeName, + h->Node->Type->Write); + errno = EINTERNAL; + return -1; + } - ret = h->Node->Type->Write(h->Node, h->Position, Length, Buffer); - if(ret == -1) return -1; + Uint flags = 0; + flags |= (h->Mode & VFS_OPENFLAG_NONBLOCK) ? VFS_IOFLAG_NOBLOCK : 0; + ret = h->Node->Type->Write(h->Node, h->Position, Length, Buffer, flags); + if(ret != Length) LOG("%i/%i written", ret, Length); + if(ret == (size_t)-1) return -1; h->Position += ret; return ret; @@ -87,10 +149,10 @@ Uint64 VFS_Write(int FD, Uint64 Length, const void *Buffer) * \fn Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, const void *Buffer) * \brief Write data to a file at a given offset */ -Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, const void *Buffer) +size_t VFS_WriteAt(int FD, Uint64 Offset, size_t Length, const void *Buffer) { tVFS_Handle *h; - Uint64 ret; + size_t ret; h = VFS_GetHandle(FD); if(!h) return -1; @@ -99,9 +161,17 @@ Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, const void *Buffer) if( h->Node->Flags & VFS_FFLAG_DIRECTORY ) return -1; if(!h->Node->Type || !h->Node->Type->Write) return 0; - ret = h->Node->Type->Write(h->Node, Offset, Length, Buffer); - if(ret == -1) return -1; + if( !MM_GetPhysAddr(h->Node->Type->Write) ) { + Log_Error("VFS", "Node type %p(%s) write method is junk %p", + h->Node->Type, h->Node->Type->TypeName, + h->Node->Type->Write); + return -1; + } + Uint flags = 0; + flags |= (h->Mode & VFS_OPENFLAG_NONBLOCK) ? VFS_IOFLAG_NOBLOCK : 0; + ret = h->Node->Type->Write(h->Node, Offset, Length, Buffer, flags); + if(ret == (size_t)-1) return -1; return ret; } @@ -133,24 +203,24 @@ int VFS_Seek(int FD, Sint64 Offset, int Whence) h = VFS_GetHandle(FD); if(!h) return -1; - //Log_Debug("VFS", "VFS_Seek: (fd=0x%x, Offset=0x%llx, Whence=%i)", - // FD, Offset, Whence); - // Set relative to current position if(Whence == 0) { + LOG("(FD%x)->Position += %lli", FD, Offset); h->Position += Offset; return 0; } // Set relative to end of file if(Whence < 0) { - if( h->Node->Size == -1 ) return -1; + if( h->Node->Size == (Uint64)-1 ) return -1; + LOG("(FD%x)->Position = %llx - %llx", FD, h->Node->Size, Offset); h->Position = h->Node->Size - Offset; return 0; } // Set relative to start of file + LOG("(FD%x)->Position = %llx", FD, Offset); h->Position = Offset; return 0; } @@ -164,9 +234,17 @@ int VFS_IOCtl(int FD, int ID, void *Buffer) tVFS_Handle *h; h = VFS_GetHandle(FD); - if(!h) return -1; + if(!h) { + LOG("FD%i is invalid", FD); + errno = EINVAL; + return -1; + } - if(!h->Node->Type || !h->Node->Type->IOCtl) return -1; + if(!h->Node->Type || !h->Node->Type->IOCtl) { + LOG("FD%i does not have an IOCtl method"); + errno = EINVAL; + return -1; + } return h->Node->Type->IOCtl(h->Node, ID, Buffer); }