Kernel/VFS - Truncate support, mmap fixes
authorJohn Hodge <[email protected]>
Sun, 22 Jun 2014 15:16:49 +0000 (23:16 +0800)
committerJohn Hodge <[email protected]>
Sun, 22 Jun 2014 15:16:49 +0000 (23:16 +0800)
17 files changed:
KernelLand/Kernel/arch/x86/proc.c
KernelLand/Kernel/drv/dgram_pipe.c
KernelLand/Kernel/drv/pty.c
KernelLand/Kernel/drv/zero-one.c
KernelLand/Kernel/include/syscalls.h
KernelLand/Kernel/include/syscalls.inc.asm
KernelLand/Kernel/include/vfs.h
KernelLand/Kernel/include/vfs_ext.h
KernelLand/Kernel/syscalls.c
KernelLand/Kernel/syscalls.lst
KernelLand/Kernel/vfs/io.c
KernelLand/Kernel/vfs/mmap.c
KernelLand/Modules/Display/VESA/main.c
KernelLand/Modules/IPStack/tcp.c
KernelLand/Modules/IPStack/udp.c
Usermode/Libraries/ld-acess.so_src/arch/syscalls.s.h
Usermode/Libraries/ld-acess.so_src/include_exp/acess/sys.h

index 460c920..999ac67 100644 (file)
@@ -481,7 +481,6 @@ tPID Proc_Clone(Uint Flags)
        tThread *cur = Proc_GetCurThread();
        Uint    eip;
 
-       Log_Warning("Proc", "Proc_Clone is deprecated");
        // Sanity, please
        if( !(Flags & CLONE_VM) ) {
                Log_Error("Proc", "Proc_Clone: Don't leave CLONE_VM unset, use Proc_NewKThread instead");
index 9e0c52d..667190e 100644 (file)
@@ -86,6 +86,7 @@ tVFS_NodeType gIPCPipe_ServerNodeType = {
 };
 tVFS_NodeType  gIPCPipe_ChannelNodeType = {
        .TypeName = "IPC Pipe - Channel",
+       .Flags = VFS_NODETYPEFLAG_STREAM,
        .Read = IPCPipe_Client_Read,
        .Write = IPCPipe_Client_Write,
        .Close = IPCPipe_Client_Close
@@ -211,8 +212,10 @@ tVFS_Node *IPCPipe_Root_FindDir(tVFS_Node *Node, const char *Name, Uint Flags)
        new_client->Server = srv;
        new_client->ClientEP.Node.Type = &gIPCPipe_ChannelNodeType;
        new_client->ClientEP.Node.ImplPtr = new_client;
+       new_client->ClientEP.Node.Size = -1;
        new_client->ServerEP.Node.Type = &gIPCPipe_ChannelNodeType;
        new_client->ServerEP.Node.ImplPtr = new_client;
+       new_client->ServerEP.Node.Size = -1;
 
        // Append to server list
        RWLock_AcquireWrite(&srv->lChannelList);
index d6713f9..2e79323 100644 (file)
@@ -85,6 +85,7 @@ tVFS_NodeType gPTY_NodeType_Root = {
 };
 tVFS_NodeType  gPTY_NodeType_Client = {
        .TypeName = "PTY-Client",
+       .Flags = VFS_NODETYPEFLAG_STREAM,
        .Read = PTY_ReadClient,
        .Write = PTY_WriteClient,
        .IOCtl = PTY_IOCtl,
@@ -93,6 +94,7 @@ tVFS_NodeType gPTY_NodeType_Client = {
 };
 tVFS_NodeType  gPTY_NodeType_Server = {
        .TypeName = "PTY-Server",
+       .Flags = VFS_NODETYPEFLAG_STREAM,
        .Read = PTY_ReadServer,
        .Write = PTY_WriteServer,
        .IOCtl = PTY_IOCtl,
@@ -235,6 +237,7 @@ tPTY *PTY_Create(const char *Name, void *Handle, tPTY_OutputFcn Output, tPTY_Req
        if( InitialMode )
                ret->Mode = *InitialMode;
        // - Client node
+       ret->ClientNode.Size = -1;
        ret->ClientNode.ImplPtr = ret;
        ret->ClientNode.Type = &gPTY_NodeType_Client;
        ret->ClientNode.UID = Threads_GetUID();
index fa2b502..b21d1ef 100644 (file)
@@ -23,33 +23,38 @@ size_t      CoreDevs_Read_GRandom(tVFS_Node *Node, off_t Offset, size_t Length, void
 MODULE_DEFINE(0, 0x0100, CoreDevs, CoreDevs_Install, NULL, NULL);
 tVFS_NodeType  gCoreDevs_NT_Null = {
        .TypeName = "CoreDevs-null",
+       .Flags = VFS_NODETYPEFLAG_STREAM,
        .Read  = CoreDevs_Read_Null,
        .Write = CoreDevs_Write
 };
 tVFS_NodeType  gCoreDevs_NT_Zero = {
        .TypeName = "CoreDevs-zero",
+       .Flags = VFS_NODETYPEFLAG_STREAM,
        .Read  = CoreDevs_Read_Zero,
        .Write = CoreDevs_Write
 };
 tVFS_NodeType  gCoreDevs_NT_One = {
        .TypeName = "CoreDevs-one",
+       .Flags = VFS_NODETYPEFLAG_STREAM,
        .Read  = CoreDevs_Read_One,
        .Write = CoreDevs_Write
 };
 tVFS_NodeType  gCoreDevs_NT_FRandom = {
        .TypeName = "CoreDevs-frandom",
+       .Flags = VFS_NODETYPEFLAG_STREAM,
        .Read  = CoreDevs_Read_FRandom,
        .Write = CoreDevs_Write
 };
 tVFS_NodeType  gCoreDevs_NT_GRandom = {
        .TypeName = "CoreDevs-grandom",
+       .Flags = VFS_NODETYPEFLAG_STREAM,
        .Read  = CoreDevs_Read_GRandom,
        .Write = CoreDevs_Write
 };
 tDevFS_Driver  gCoreDevs_Null = {
        NULL, "null",
        {
-       .Size = 0, .NumACLs = 1,
+       .Size = -1, .NumACLs = 1,
        .ACLs = &gVFS_ACL_EveryoneRW,
        .Type = &gCoreDevs_NT_Null
        }
@@ -57,7 +62,7 @@ tDevFS_Driver gCoreDevs_Null = {
 tDevFS_Driver  gCoreDevs_Zero = {
        NULL, "zero",
        {
-       .Size = 0, .NumACLs = 1,
+       .Size = -1, .NumACLs = 1,
        .ACLs = &gVFS_ACL_EveryoneRW,
        .Type = &gCoreDevs_NT_Zero
        }
@@ -65,7 +70,7 @@ tDevFS_Driver gCoreDevs_Zero = {
 tDevFS_Driver  gCoreDevs_One = {
        NULL, "one",
        {
-       .Size = 0, .NumACLs = 1,
+       .Size = -1, .NumACLs = 1,
        .ACLs = &gVFS_ACL_EveryoneRW,
        .Type = &gCoreDevs_NT_One
        }
@@ -73,7 +78,7 @@ tDevFS_Driver gCoreDevs_One = {
 tDevFS_Driver  gCoreDevs_FRandom = {
        NULL, "frandom",
        {
-       .Size = 0, .NumACLs = 1,
+       .Size = -1, .NumACLs = 1,
        .ACLs = &gVFS_ACL_EveryoneRW,
        .Type = &gCoreDevs_NT_FRandom,
        .DataAvaliable = 1
@@ -82,7 +87,7 @@ tDevFS_Driver gCoreDevs_FRandom = {
 tDevFS_Driver  gCoreDevs_GRandom = {
        NULL, "grandom",
        {
-       .Size = 0, .NumACLs = 1,
+       .Size = -1, .NumACLs = 1,
        .ACLs = &gVFS_ACL_EveryoneRW,
        .Type = &gCoreDevs_NT_GRandom,
        .DataAvaliable = 1
index 2a880f6..0ad4413 100644 (file)
 #define SYS_READAT     72      // Read from an open file (with offset)
 #define SYS_WRITE      73      // Write to an open file
 #define SYS_WRITEAT    74      // Write to an open file (with offset)
-#define SYS_IOCTL      75      // Perform an IOCtl Call
-#define SYS_SEEK       76      // Seek to a new position in the file
-#define SYS_READDIR    77      // Read from an open directory
-#define SYS_GETACL     78      // Get an ACL Value
-#define SYS_SETACL     79      // Set an ACL Value
-#define SYS_FINFO      80      // Get file information
-#define SYS_MKDIR      81      // Create a new directory
-#define SYS_LINK       82      // Create a new link to a file
-#define SYS_SYMLINK    83      // Create a symbolic link
-#define SYS_UNLINK     84      // Delete a file
-#define SYS_TELL       85      // Return the current file position
-#define SYS_CHDIR      86      // Change current directory
-#define SYS_GETCWD     87      // Get current directory
-#define SYS_MOUNT      88      // Mount a filesystem
-#define SYS_SELECT     89      // Wait for file handles
-#define SYS_MARSHALFD  90      // Create a reference to a FD suitable for handing to another process
-#define SYS_UNMARSHALFD        91      // Accept a marshaled FD
+#define SYS_TRUNCATE   75      // Change the size of an open file
+#define SYS_IOCTL      76      // Perform an IOCtl Call
+#define SYS_SEEK       77      // Seek to a new position in the file
+#define SYS_READDIR    78      // Read from an open directory
+#define SYS_GETACL     79      // Get an ACL Value
+#define SYS_SETACL     80      // Set an ACL Value
+#define SYS_FINFO      81      // Get file information
+#define SYS_MKDIR      82      // Create a new directory
+#define SYS_LINK       83      // Create a new link to a file
+#define SYS_SYMLINK    84      // Create a symbolic link
+#define SYS_UNLINK     85      // Delete a file
+#define SYS_TELL       86      // Return the current file position
+#define SYS_CHDIR      87      // Change current directory
+#define SYS_GETCWD     88      // Get current directory
+#define SYS_MOUNT      89      // Mount a filesystem
+#define SYS_SELECT     90      // Wait for file handles
+#define SYS_MMAP       91      // Map a file into this address space
+#define SYS_MUNMAP     92      // Unmap a file
+#define SYS_MARSHALFD  93      // Create a reference to a FD suitable for handing to another process
+#define SYS_UNMARSHALFD        94      // Accept a marshaled FD
 
-#define NUM_SYSCALLS   92
+#define NUM_SYSCALLS   95
 #define SYS_DEBUG      0x100
 #define SYS_DEBUGHEX   0x101
 
@@ -155,6 +158,7 @@ static const char *cSYSCALL_NAMES[] = {
        "SYS_READAT",
        "SYS_WRITE",
        "SYS_WRITEAT",
+       "SYS_TRUNCATE",
        "SYS_IOCTL",
        "SYS_SEEK",
        "SYS_READDIR",
@@ -170,6 +174,8 @@ static const char *cSYSCALL_NAMES[] = {
        "SYS_GETCWD",
        "SYS_MOUNT",
        "SYS_SELECT",
+       "SYS_MMAP",
+       "SYS_MUNMAP",
        "SYS_MARSHALFD",
        "SYS_UNMARSHALFD",
 
index 656526c..35743b1 100644 (file)
 %define SYS_READAT     72       ;Read from an open file (with offset)
 %define SYS_WRITE      73       ;Write to an open file
 %define SYS_WRITEAT    74       ;Write to an open file (with offset)
-%define SYS_IOCTL      75       ;Perform an IOCtl Call
-%define SYS_SEEK       76       ;Seek to a new position in the file
-%define SYS_READDIR    77       ;Read from an open directory
-%define SYS_GETACL     78       ;Get an ACL Value
-%define SYS_SETACL     79       ;Set an ACL Value
-%define SYS_FINFO      80       ;Get file information
-%define SYS_MKDIR      81       ;Create a new directory
-%define SYS_LINK       82       ;Create a new link to a file
-%define SYS_SYMLINK    83       ;Create a symbolic link
-%define SYS_UNLINK     84       ;Delete a file
-%define SYS_TELL       85       ;Return the current file position
-%define SYS_CHDIR      86       ;Change current directory
-%define SYS_GETCWD     87       ;Get current directory
-%define SYS_MOUNT      88       ;Mount a filesystem
-%define SYS_SELECT     89       ;Wait for file handles
-%define SYS_MARSHALFD  90       ;Create a reference to a FD suitable for handing to another process
-%define SYS_UNMARSHALFD        91       ;Accept a marshaled FD
+%define SYS_TRUNCATE   75       ;Change the size of an open file
+%define SYS_IOCTL      76       ;Perform an IOCtl Call
+%define SYS_SEEK       77       ;Seek to a new position in the file
+%define SYS_READDIR    78       ;Read from an open directory
+%define SYS_GETACL     79       ;Get an ACL Value
+%define SYS_SETACL     80       ;Set an ACL Value
+%define SYS_FINFO      81       ;Get file information
+%define SYS_MKDIR      82       ;Create a new directory
+%define SYS_LINK       83       ;Create a new link to a file
+%define SYS_SYMLINK    84       ;Create a symbolic link
+%define SYS_UNLINK     85       ;Delete a file
+%define SYS_TELL       86       ;Return the current file position
+%define SYS_CHDIR      87       ;Change current directory
+%define SYS_GETCWD     88       ;Get current directory
+%define SYS_MOUNT      89       ;Mount a filesystem
+%define SYS_SELECT     90       ;Wait for file handles
+%define SYS_MMAP       91       ;Map a file into this address space
+%define SYS_MUNMAP     92       ;Unmap a file
+%define SYS_MARSHALFD  93       ;Create a reference to a FD suitable for handing to another process
+%define SYS_UNMARSHALFD        94       ;Accept a marshaled FD
index 4be24c3..72c6cbd 100644 (file)
@@ -216,6 +216,21 @@ typedef struct sVFS_Node
  * \}
  */
 
+/**
+ * \name tVFS_NodeType.Type flags
+ * \brief Flags for node types
+ * \{
+ */
+//\! Calls to VFS_Write should not generate calls to .Trunctate
+//\! 
+//\! If this flag is set, writing over the end of the file will not call .Truncate automatically
+#define VFS_NODETYPEFLAG_NOAUTOEXPAND  0x001
+//\! Node type describes a stream (offset ignored, seeking disallowed)
+#define VFS_NODETYPEFLAG_STREAM        0x002
+/**
+ * \}
+ */
+
 /**
  * \brief Functions for a specific node type
  */
@@ -226,6 +241,11 @@ struct sVFS_NodeType
         */
        const char      *TypeName;
 
+       /**
+        * \brief Flags describing operational quirks
+        */
+       unsigned int    Flags;
+
        /**
         * \name Common Functions
         * \brief Functions that are used no matter the value of .Flags
@@ -295,6 +315,17 @@ struct sVFS_NodeType
         */
         int    (*MMap)(struct sVFS_Node *Node, off_t Offset, int Length, void *Dest);
        
+       /**
+        * \brief Resize a file
+        * \param Node  Pointer to this node
+        * \param NewSize       New file size
+        * \return Actual new file size
+        * \note If NULL, \a Write may be called with Offset + Length > Size
+        *
+        * Called to increase/decrease the size of a file. If the 
+        */
+       off_t   (*Truncate)(struct sVFS_Node *Node, off_t NewSize);
+       
        /**
         * \}
         */
index 99a64e3..42d9865 100644 (file)
@@ -328,6 +328,16 @@ extern size_t      VFS_ReadAt(int FD, Uint64 Offset, size_t Length, void *Buffer);
  */
 extern size_t  VFS_WriteAt(int FD, Uint64 Offset, size_t Length, const void *Buffer);
 
+/**
+ * \brief Set the valid size of a file
+ * \param FD   File descriptor
+ * \param Size New file size
+ * \return Actual new file size (-1 if error occurred)
+ *
+ * \note Not all files support this call (will return ENOTIMPL)
+ */
+extern off_t   VFS_Truncate(int FD, off_t Size);
+
 /**
  * \brief Sends an IOCtl request to the driver
  * \param FD   File handle returned by ::VFS_Open
index 75ed874..5f52e0e 100644 (file)
@@ -293,6 +293,17 @@ void SyscallHandler(tSyscallRegs *Regs)
                #endif
                break;
        
+       case SYS_TRUNCATE:
+               ret = VFS_Truncate(
+                       Regs->Arg1,
+                       #if BITS == 32
+                       ARG64(2,3)
+                       #else
+                       Regs->Arg2
+                       #endif
+                       );
+               break;
+       
        case SYS_FINFO:
                CHECK_NUM_NONULL( (void*)Regs->Arg2, sizeof(tFInfo) + Regs->Arg3*sizeof(tVFS_ACL) );
                // FP, Dest, MaxACLs
@@ -394,6 +405,21 @@ void SyscallHandler(tSyscallRegs *Regs)
                        );
                break;
 
+       case SYS_MMAP:
+               ret = (tVAddr)VFS_MMap(
+                       (void*)Regs->Arg1, Regs->Arg2,
+                       Regs->Arg3&0xFFFF, Regs->Arg3>>16,
+                       Regs->Arg4,
+                       #if BITS == 32
+                       ARG64(5,6)
+                       #else
+                       Regs->Arg5
+                       #endif
+                       );
+               break;
+       case SYS_MUNMAP:
+               ret = VFS_MUnmap( (void*)Regs->Arg1, Regs->Arg2 );
+               break;
        
        // Create a directory
        case SYS_MKDIR:
index d3b4557..bea821b 100644 (file)
@@ -56,6 +56,7 @@ SYS_READ      Read from an open file
 SYS_READAT     Read from an open file (with offset)
 SYS_WRITE      Write to an open file
 SYS_WRITEAT    Write to an open file (with offset)
+SYS_TRUNCATE   Change the size of an open file
 SYS_IOCTL      Perform an IOCtl Call
 SYS_SEEK       Seek to a new position in the file
 SYS_READDIR    Read from an open directory
@@ -71,7 +72,8 @@ SYS_CHDIR     Change current directory
 SYS_GETCWD     Get current directory
 SYS_MOUNT      Mount a filesystem
 SYS_SELECT     Wait for file handles
-
+SYS_MMAP       Map a file into this address space
+SYS_MUNMAP     Unmap a file
 SYS_MARSHALFD  Create a reference to a FD suitable for handing to another process
 SYS_UNMARSHALFD        Accept a marshaled FD
 
index 271e920..cb0140a 100644 (file)
@@ -100,16 +100,32 @@ size_t VFS_ReadAt(int FD, Uint64 Offset, size_t Length, void *Buffer)
  */
 size_t VFS_Write(int FD, size_t Length, const void *Buffer)
 {
-       tVFS_Handle     *h;
-       size_t  ret;
-       
-       h = VFS_GetHandle(FD);
+       tVFS_Handle     *h = VFS_GetHandle(FD);
        if(!h) {
                LOG("FD%i is not open", FD);
                errno = EBADF;
                return -1;
        }
        
+       size_t ret = VFS_WriteAt(FD, h->Position, Length, Buffer);
+       if(ret == (size_t)-1)   return -1;
+
+       if( !(h->Node->Type->Flags & VFS_NODETYPEFLAG_STREAM) )
+               h->Position += ret;
+       return ret;
+}
+
+/**
+ * \fn Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, const void *Buffer)
+ * \brief Write data to a file at a given offset
+ */
+size_t VFS_WriteAt(int FD, Uint64 Offset, size_t Length, const void *Buffer)
+{
+       LOG("FD=%i,Offset=%lli,Length=%i,Buffer=%p",
+               FD, Offset, Length, Buffer);
+       tVFS_Handle     *h = VFS_GetHandle(FD);
+       if(!h)  return -1;
+       
        if( !(h->Mode & VFS_OPENFLAG_WRITE) ) {
                LOG("FD%i not opened for writing", FD);
                errno = EBADF;
@@ -121,57 +137,63 @@ size_t VFS_Write(int FD, size_t Length, const void *Buffer)
                return -1;
        }
 
-       if( !h->Node->Type || !h->Node->Type->Write ) {
+       const tVFS_NodeType*    nodetype = h->Node->Type;
+       if(!nodetype || !nodetype->Write) {
                LOG("FD%i has no write method", FD);
                errno = EINTERNAL;
                return 0;
        }
-
-       if( !MM_GetPhysAddr(h->Node->Type->Write) ) {
+       
+       if( !MM_GetPhysAddr(nodetype->Write) ) {
                Log_Error("VFS", "Node type %p(%s) write method is junk %p",
-                       h->Node->Type, h->Node->Type->TypeName,
-                       h->Node->Type->Write);
+                       nodetype, nodetype->TypeName, nodetype->Write);
                errno = EINTERNAL;
                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;
-}
-
-/**
- * \fn Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, const void *Buffer)
- * \brief Write data to a file at a given offset
- */
-size_t VFS_WriteAt(int FD, Uint64 Offset, size_t Length, const void *Buffer)
-{
-       tVFS_Handle     *h;
-       size_t  ret;
-       
-       h = VFS_GetHandle(FD);
-       if(!h)  return -1;
-       
-       if( !(h->Mode & VFS_OPENFLAG_WRITE) )   return -1;
-       if( h->Node->Flags & VFS_FFLAG_DIRECTORY )      return -1;
-
-       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);
-               return -1;
+       // Bounds checks
+       if( h->Node->Size != (Uint64)-1 && Offset > h->Node->Size ) {
+               Log_Notice("VFS", "Write starting past EOF of FD%x (%lli > %lli)",
+                       FD, Offset, h->Node->Size);
+               //errno = ESPIPE;
+               return 0;
+       }
+       if( Offset + Length > h->Node->Size )
+       {
+               // Going OOB
+               if( !nodetype->Truncate )
+               {
+                       LOG("No .Truncate method, emiting write past EOF");
+               }
+               else if( nodetype->Flags & VFS_NODETYPEFLAG_NOAUTOEXPAND )
+               {
+                       LOG("NOAUTOEXPAND set, truncating length from %i to %i",
+                               Length, h->Node->Size - Offset);
+                       Length = h->Node->Size - Offset;
+               }
+               else if( nodetype->Truncate(h->Node, Offset + Length) != Offset + Length )
+               {
+                       // oh... fail? Truncate to current size
+                       LOG(".Truncate failed, truncating length from %i to %i",
+                               Length, h->Node->Size - Offset);
+                       Length = h->Node->Size - Offset;
+               }
+               else
+               {
+                       // Expansion, node size should now fit
+                       LOG("Expanded file");
+               }
        }
+       
+       // Create flag set
        Uint flags = 0;
        flags |= (h->Mode & VFS_OPENFLAG_NONBLOCK) ? VFS_IOFLAG_NOBLOCK : 0;
-       ret = h->Node->Type->Write(h->Node, Offset, Length, Buffer, flags);
+       
+       // Dispatch the read!
+       size_t ret = nodetype->Write(h->Node, Offset, Length, Buffer, flags);
        if(ret == (size_t)-1)   return -1;
+       if(ret != Length)       LOG("%i/%i written", ret, Length);
+
        return ret;
 }
 
@@ -198,11 +220,14 @@ Uint64 VFS_Tell(int FD)
  */
 int VFS_Seek(int FD, Sint64 Offset, int Whence)
 {
-       tVFS_Handle     *h;
-       
-       h = VFS_GetHandle(FD);
+       tVFS_Handle     *h = VFS_GetHandle(FD);
        if(!h)  return -1;
        
+       if( (h->Node->Type->Flags & VFS_NODETYPEFLAG_STREAM) ) {
+               LOG("Seeking in stream");
+               return -1;
+       }
+       
        // Set relative to current position
        if(Whence == 0) {
                LOG("(FD%x)->Position += %lli", FD, Offset);
@@ -225,15 +250,33 @@ int VFS_Seek(int FD, Sint64 Offset, int Whence)
        return 0;
 }
 
+/*
+ * Truncate/Expand a file's allocation
+ */
+off_t VFS_Truncate(int FD, off_t Size)
+{
+       tVFS_Handle     *h = VFS_GetHandle(FD);
+       if(!h) {
+               errno = EBADF;
+               return -1;
+       }
+       
+       if( !h->Node->Type->Truncate)
+       {
+               errno = ENOTIMPL;
+               return -1;      
+       }
+       
+       return h->Node->Type->Truncate(h->Node, Size);
+}
+
 /**
  * \fn int VFS_IOCtl(int FD, int ID, void *Buffer)
  * \brief Call an IO Control on a file
  */
 int VFS_IOCtl(int FD, int ID, void *Buffer)
 {
-       tVFS_Handle     *h;
-       
-       h = VFS_GetHandle(FD);
+       tVFS_Handle     *h = VFS_GetHandle(FD);
        if(!h) {
                LOG("FD%i is invalid", FD);
                errno = EINVAL;
index b6d5c2d..9a7fa44 100644 (file)
@@ -25,32 +25,40 @@ struct sVFS_MMapPageBlock
 // === PROTOTYPES ===
 //void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD, Uint64 Offset);
 void   *VFS_MMap_Anon(void *Destination, size_t Length, Uint FlagsSet, Uint FlagsMask);
+int    VFS_MMap_MapPage(tVFS_Node *Node, unsigned int PageNum, tVFS_MMapPageBlock *pb, void *mapping_dest, unsigned int Protection);
 //int  VFS_MUnmap(void *Addr, size_t Length);
 
 // === CODE ===
 void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD, Uint64 Offset)
 {
-       tVAddr  mapping_base;
-        int    npages, pagenum;
-       tVFS_MMapPageBlock      *pb, *prev;
-
        ENTER("pDestHint iLength xProtection xFlags xFD XOffset", DestHint, Length, Protection, Flags, FD, Offset);
 
        if( Flags & MMAP_MAP_ANONYMOUS )
                Offset = (tVAddr)DestHint & 0xFFF;
        
-       npages = ((Offset & (PAGE_SIZE-1)) + Length + (PAGE_SIZE - 1)) / PAGE_SIZE;
-       pagenum = Offset / PAGE_SIZE;
+       unsigned int npages = ((Offset & (PAGE_SIZE-1)) + Length + (PAGE_SIZE - 1)) / PAGE_SIZE;
+       unsigned int pagenum = Offset / PAGE_SIZE;
 
-       mapping_base = (tVAddr)DestHint;
-       tPage   *mapping_dest = (void*)(mapping_base & ~(PAGE_SIZE-1));
+       tVAddr mapping_base = (tVAddr)DestHint;
 
-       if( DestHint == NULL )
+       if( Flags & MMAP_MAP_FIXED )
+       {
+               ASSERT( (Flags & MMAP_MAP_FIXED) && DestHint != NULL );
+               // Keep and use the hint
+               // - TODO: Validate that the region pointed to by the hint is correct
+       }
+       else
        {
-               // TODO: Locate space for the allocation
-               LEAVE('n');
-               return NULL;
+               Log_Warning("VFS", "MMap: TODO Handle non-fixed mappings");
+               if( DestHint == NULL )
+               {
+                       // TODO: Locate space for the allocation
+                       Log_Warning("VFS", "Mmap: Handle NULL destination hint");
+                       LEAVE('n');
+                       return NULL;
+               }
        }
+       tPage   *mapping_dest = (void*)(mapping_base & ~(PAGE_SIZE-1));
 
        // Handle anonymous mappings
        if( Flags & MMAP_MAP_ANONYMOUS )
@@ -67,14 +75,14 @@ void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD,
        
        Mutex_Acquire( &h->Node->Lock );
 
+       tVFS_MMapPageBlock      *pb, **pb_pnp = (tVFS_MMapPageBlock**)&h->Node->MMapInfo;
        // Search for existing mapping for each page
        // - Sorted list of 16 page blocks
-       for(
-               pb = h->Node->MMapInfo, prev = NULL;
-               pb && pb->BaseOffset + MMAP_PAGES_PER_BLOCK <= pagenum;
-               prev = pb, pb = pb->Next
-               )
-               ;
+       for( pb = h->Node->MMapInfo; pb; pb_pnp = &pb->Next, pb = pb->Next )
+       {
+               if( pb->BaseOffset + MMAP_PAGES_PER_BLOCK <= pagenum )
+                       break;
+       }
 
        LOG("pb = %p, pb->BaseOffset = %X", pb, pb ? pb->BaseOffset : 0);
 
@@ -89,74 +97,22 @@ void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD,
                }
                pb->Next = old_pb;
                pb->BaseOffset = pagenum - pagenum % MMAP_PAGES_PER_BLOCK;
-               if(prev)
-                       prev->Next = pb;
-               else
-                       h->Node->MMapInfo = pb;
+               *pb_pnp = pb;
        }
 
        // - Map (and allocate) pages
        while( npages -- )
        {
-               assert( pagenum >= pb->BaseOffset );
-               assert( pagenum - pb->BaseOffset < MMAP_PAGES_PER_BLOCK );
+               ASSERTC( pagenum, >=, pb->BaseOffset );
+               ASSERTC( pagenum - pb->BaseOffset, <, MMAP_PAGES_PER_BLOCK );
                if( MM_GetPhysAddr( mapping_dest ) == 0 )
                {
-                       if( pb->PhysAddrs[pagenum - pb->BaseOffset] == 0 )
-                       {
-                               tVFS_NodeType   *nt = h->Node->Type;
-                               if( !nt ) 
-                               {
-                                       // TODO: error
-                               }
-                               else if( nt->MMap )
-                                       nt->MMap(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE, mapping_dest);
-                               else
-                               {
-                                        int    read_len;
-                                       // Allocate pages and read data
-                                       if( MM_Allocate(mapping_dest) == 0 ) {
-                                               // TODO: Unwrap
-                                               Mutex_Release( &h->Node->Lock );
-                                               LEAVE('n');
-                                               return NULL;
-                                       }
-                                       // TODO: Clip read length
-                                       read_len = nt->Read(h->Node, pagenum*PAGE_SIZE, PAGE_SIZE,
-                                               mapping_dest, 0);
-                                       // TODO: This was commented out, why?
-                                       if( read_len != PAGE_SIZE ) {
-                                               memset( (char*)mapping_dest + read_len, 0, PAGE_SIZE-read_len );
-                                       }
-                               }
-                               pb->PhysAddrs[pagenum - pb->BaseOffset] = MM_GetPhysAddr( mapping_dest );
-                               MM_SetPageNode( pb->PhysAddrs[pagenum - pb->BaseOffset], h->Node );
-                               MM_RefPhys( pb->PhysAddrs[pagenum - pb->BaseOffset] );
-                               LOG("Read and map %X to %p (%P)", pagenum*PAGE_SIZE, mapping_dest,
-                                       pb->PhysAddrs[pagenum - pb->BaseOffset]);
-                       }
-                       else
+                       LOG("Map page to %p", mapping_dest);
+                       if( VFS_MMap_MapPage(h->Node, pagenum, pb, mapping_dest, Protection) )
                        {
-                               MM_Map( mapping_dest, pb->PhysAddrs[pagenum - pb->BaseOffset] );
-                               MM_RefPhys( pb->PhysAddrs[pagenum - pb->BaseOffset] );
-                               LOG("Cached map %X to %p (%P)", pagenum*PAGE_SIZE, mapping_dest,
-                                       pb->PhysAddrs[pagenum - pb->BaseOffset]);
-                       }
-                       h->Node->ReferenceCount ++;
-               
-                       // Set flags
-                       if( !(Protection & MMAP_PROT_WRITE) ) {
-                               MM_SetFlags(mapping_dest, MM_PFLAG_RO, MM_PFLAG_RO);
-                       }
-                       else {
-                               MM_SetFlags(mapping_dest, 0, MM_PFLAG_RO);
-                       }
-                       
-                       if( Protection & MMAP_PROT_EXEC ) {
-                               MM_SetFlags(mapping_dest, MM_PFLAG_EXEC, MM_PFLAG_EXEC);
-                       }
-                       else {
-                               MM_SetFlags(mapping_dest, 0, MM_PFLAG_EXEC);
+                               Mutex_Release( &h->Node->Lock );
+                               LEAVE('n');
+                               return NULL;
                        }
                }
                else
@@ -167,25 +123,27 @@ void *VFS_MMap(void *DestHint, size_t Length, int Protection, int Flags, int FD,
                                MM_SetFlags(mapping_dest, 0, MM_PFLAG_RO);
                        }
                }
-               if( Flags & MMAP_MAP_PRIVATE )
+               if( Flags & MMAP_MAP_PRIVATE ) {
+                       // TODO: Don't allow the page to change underneath either
                        MM_SetFlags(mapping_dest, MM_PFLAG_COW, MM_PFLAG_COW);
+               }
                pagenum ++;
                mapping_dest ++;
 
                // Roll on to next block if needed
                if(pagenum - pb->BaseOffset == MMAP_PAGES_PER_BLOCK)
                {
-                       if( pb->Next && pb->Next->BaseOffset == pagenum )
-                               pb = pb->Next;
-                       else
+                       if( !pb->Next || pb->Next->BaseOffset != pagenum )
                        {
-                               tVFS_MMapPageBlock      *oldpb = pb;
-                               pb = malloc( sizeof(tVFS_MMapPageBlock) );
-                               pb->Next = oldpb->Next;
-                               pb->BaseOffset = pagenum;
-                               memset(pb->PhysAddrs, 0, sizeof(pb->PhysAddrs));
-                               oldpb->Next = pb;
+                               if( pb->Next )  ASSERTC(pb->Next->BaseOffset % MMAP_PAGES_PER_BLOCK, ==, 0);
+                               tVFS_MMapPageBlock      *newpb = malloc( sizeof(tVFS_MMapPageBlock) );
+                               newpb->Next = pb->Next;
+                               newpb->BaseOffset = pagenum;
+                               memset(newpb->PhysAddrs, 0, sizeof(newpb->PhysAddrs));
+                               pb->Next = newpb;
                        }
+       
+                       pb = pb->Next;
                }
        }
        
@@ -263,6 +221,66 @@ void *VFS_MMap_Anon(void *Destination, size_t Length, Uint FlagsSet, Uint FlagsM
        return Destination;
 }
 
+int VFS_MMap_MapPage(tVFS_Node *Node, unsigned int pagenum, tVFS_MMapPageBlock *pb, void *mapping_dest, unsigned int Protection)
+{
+       if( pb->PhysAddrs[pagenum - pb->BaseOffset] != 0 )
+       {
+               MM_Map( mapping_dest, pb->PhysAddrs[pagenum - pb->BaseOffset] );
+               MM_RefPhys( pb->PhysAddrs[pagenum - pb->BaseOffset] );
+               LOG("Cached map %X to %p (%P)", pagenum*PAGE_SIZE, mapping_dest,
+                       pb->PhysAddrs[pagenum - pb->BaseOffset]);
+       }
+       else
+       {
+               tVFS_NodeType   *nt = Node->Type;
+               if( !nt ) 
+               {
+                       // TODO: error
+               }
+               else if( nt->MMap )
+                       nt->MMap(Node, pagenum*PAGE_SIZE, PAGE_SIZE, mapping_dest);
+               else
+               {
+                        int    read_len;
+                       // Allocate pages and read data
+                       if( MM_Allocate(mapping_dest) == 0 ) {
+                               // TODO: Unwrap
+                               return 1;
+                       }
+                       // TODO: Clip read length
+                       read_len = nt->Read(Node, pagenum*PAGE_SIZE, PAGE_SIZE, mapping_dest, 0);
+                       // TODO: This was commented out, why?
+                       if( read_len != PAGE_SIZE ) {
+                               memset( (char*)mapping_dest + read_len, 0, PAGE_SIZE-read_len );
+                       }
+               }
+               pb->PhysAddrs[pagenum - pb->BaseOffset] = MM_GetPhysAddr( mapping_dest );
+               MM_SetPageNode( pb->PhysAddrs[pagenum - pb->BaseOffset], Node );
+               MM_RefPhys( pb->PhysAddrs[pagenum - pb->BaseOffset] );
+               LOG("Read and map %X to %p (%P)", pagenum*PAGE_SIZE, mapping_dest,
+                       pb->PhysAddrs[pagenum - pb->BaseOffset]);
+       }
+       // TODO: Huh?
+       Node->ReferenceCount ++;
+
+       // Set flags
+       if( !(Protection & MMAP_PROT_WRITE) ) {
+               MM_SetFlags(mapping_dest, MM_PFLAG_RO, MM_PFLAG_RO);
+       }
+       else {
+               MM_SetFlags(mapping_dest, 0, MM_PFLAG_RO);
+       }
+       
+       if( Protection & MMAP_PROT_EXEC ) {
+               MM_SetFlags(mapping_dest, MM_PFLAG_EXEC, MM_PFLAG_EXEC);
+       }
+       else {
+               MM_SetFlags(mapping_dest, 0, MM_PFLAG_EXEC);
+       }
+       
+       return 0;
+}
+
 int VFS_MUnmap(void *Addr, size_t Length)
 {
        return 0;
index 0af86cb..62fb25a 100644 (file)
@@ -461,9 +461,9 @@ int Vesa_Int_SetMode(int mode)
        \r
        Mutex_Release( &glVesa_Lock );\r
 \r
-       // TODO: Disableable backbuffer\r
-       gVesa_BufInfo.BackBuffer  = realloc(gVesa_BufInfo.BackBuffer,\r
-               modeptr->height * modeptr->pitch);\r
+       // TODO: Allow disabling of back-buffer\r
+       gVesa_DriverStruct.RootNode.Size = modeptr->height * modeptr->pitch;\r
+       gVesa_BufInfo.BackBuffer  = realloc(gVesa_BufInfo.BackBuffer, modeptr->height * modeptr->pitch);\r
        gVesa_BufInfo.Framebuffer = gpVesa_Framebuffer;\r
        gVesa_BufInfo.Pitch = modeptr->pitch;\r
        gVesa_BufInfo.Width = modeptr->width;\r
index b7890ad..fcfdaaa 100644 (file)
@@ -67,6 +67,7 @@ tVFS_NodeType gTCP_ServerNodeType = {
        };
 tVFS_NodeType  gTCP_ClientNodeType = {
        .TypeName = "TCP Client/Connection",
+       .Flags = VFS_NODETYPEFLAG_STREAM,
        .Read  = TCP_Client_Read,
        .Write = TCP_Client_Write,
        .IOCtl = TCP_Client_IOCtl,
index 325a09e..67f6056 100644 (file)
@@ -33,6 +33,8 @@ Uint16        UDP_int_FinaliseChecksum(Uint16 Value);
 
 // === GLOBALS ===
 tVFS_NodeType  gUDP_NodeType = {
+       .TypeName = "UDP",
+       .Flags = VFS_NODETYPEFLAG_STREAM,
        .Read = UDP_Channel_Read,
        .Write = UDP_Channel_Write,
        .IOCtl = UDP_Channel_IOCtl,
@@ -189,6 +191,7 @@ tVFS_Node *UDP_Channel_Init(tInterface *Interface)
        tUDPChannel     *new;
        new = calloc( sizeof(tUDPChannel), 1 );
        new->Interface = Interface;
+       new->Node.Size = -1;
        new->Node.ImplPtr = new;
        new->Node.NumACLs = 1;
        new->Node.ACLs = &gVFS_ACL_EveryoneRW;
index 4dc545d..c783a9b 100644 (file)
@@ -55,6 +55,7 @@ SYSCALL3(_SysRead, SYS_READ)  // int, uint, void*
 SYSCALL5(_SysReadAt, SYS_READAT)       // int, uint, uint64, void*
 SYSCALL3(_SysWrite, SYS_WRITE) // int, uint, void*
 SYSCALL5(_SysWriteAt, SYS_WRITEAT)     // int, uint, uint64, void*
+SYSCALL3(_SysTruncate, SYS_TRUNCATE)   // int, uint64
 SYSCALL4(_SysSeek, SYS_SEEK)   // int, uint64_t, int
 SYSCALL1(_SysTell, SYS_TELL)   // int
 SYSCALL3(_SysFInfo, SYS_FINFO) // int, void*, int
@@ -68,3 +69,9 @@ SYSCALL6(_SysSelect, SYS_SELECT)      // int, fd_set*, fd_set*, fd_set*, tTime*, uint
 SYSCALL1(_SysMkDir, SYS_MKDIR) // const char*
 SYSCALL1(_SysUnlink, SYS_UNLINK)       // const char*
 
+SYSCALL6(_SysMMap, SYS_MMAP)
+SYSCALL2(_SysMUnMap, SYS_MUNMAP)
+
+SYSCALL1(_SysMarshalFD, SYS_MARSHALFD)
+SYSCALL2(_SysUnMarshalFD, SYS_UNMARSHALFD)
+
index 31d74c4..0643ba4 100644 (file)
@@ -40,6 +40,14 @@ extern "C" {
 #define FILEFLAG_SYMLINK       0x20
 #define CLONE_VM       0x10
 
+#define MMAP_PROT_READ 0x001   //!< Readable memory
+#define MMAP_PROT_WRITE        0x002   //!< Writable memory
+#define MMAP_PROT_EXEC 0x004   //!< Executable memory
+#define MMAP_MAP_SHARED        0x001   //!< Shared with all other users of the FD
+#define MMAP_MAP_PRIVATE       0x002   //!< Local (COW) copy
+#define MMAP_MAP_FIXED         0x004   //!< Load to a fixed address
+#define MMAP_MAP_ANONYMOUS     0x008   //!< Not associated with a FD
+
 #ifdef ARCHDIR_is_native
 # include "_native_syscallmod.h"
 #endif
@@ -90,6 +98,7 @@ extern int    _SysCopyFD(int srcfd, int dstfd);
 extern int     _SysFDFlags(int fd, int mask, int newflags);
 extern size_t  _SysRead(int fd, void *buffer, size_t length);
 extern size_t  _SysReadAt(int fd, uint64_t offset, size_t length, void *buffer);
+extern uint64_t        _SysTruncate(int fd, uint64_t size);
 extern int     _SysClose(int fd);
 extern int     _SysFDCtl(int fd, int option, ...);
 extern size_t  _SysWrite(int fd, const void *buffer, size_t length);
@@ -105,6 +114,11 @@ extern int _SysSelect(int nfds, fd_set *read, fd_set *write, fd_set *err, int64_
 //#define select(nfs, rdfds, wrfds, erfds, timeout)    _SysSelect(nfs, rdfds, wrfds, erfds, timeout, 0)
 extern int     _SysMkDir(const char *dirname);
 extern int     _SysUnlink(const char *pathname);
+extern void*   _SysMMap(void *addr, size_t length, unsigned int _flags, int fd, uint64_t offset);
+#define _SysMMap(addr,length,flags,prot,fd,offset)     _SysMMap(addr,length,(flags|(prot<<16)), fd, offset)
+extern int     _SysMUnMap(void *addr, size_t length);
+extern uint64_t        _SysMarshalFD(int FD);
+extern int     _SysUnMarshalFD(uint64_t Handle);
 
 // --- IPC ---
 extern int     _SysSendMessage(int dest, size_t length, const void *Data);

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