Merge branch 'master' of git://localhost/acess2
authorJohn Hodge <[email protected]>
Wed, 22 Aug 2012 05:03:41 +0000 (13:03 +0800)
committerJohn Hodge <[email protected]>
Wed, 22 Aug 2012 05:03:41 +0000 (13:03 +0800)
52 files changed:
AcessNative/acesskernel_src/nativefs.c
KernelLand/Kernel/drv/fifo.c
KernelLand/Kernel/drv/pci.c
KernelLand/Kernel/drv/proc.c
KernelLand/Kernel/drv/vterm.c
KernelLand/Kernel/drvutil_disk.c
KernelLand/Kernel/include/acess.h
KernelLand/Kernel/include/api_drv_disk.h
KernelLand/Kernel/include/errno.h
KernelLand/Kernel/include/vfs.h
KernelLand/Kernel/include/vfs_ext.h
KernelLand/Kernel/lib.c
KernelLand/Kernel/libc.c
KernelLand/Kernel/vfs/dir.c
KernelLand/Kernel/vfs/fs/devfs.c
KernelLand/Kernel/vfs/fs/root.c
KernelLand/Kernel/vfs/io.c
KernelLand/Kernel/vfs/main.c
KernelLand/Kernel/vfs/open.c
KernelLand/Modules/Filesystems/Ext2/dir.c
KernelLand/Modules/Filesystems/Ext2/ext2.c
KernelLand/Modules/Filesystems/Ext2/ext2_common.h
KernelLand/Modules/Filesystems/Ext2/ext2fs.h
KernelLand/Modules/Filesystems/Ext2/write.c
KernelLand/Modules/Filesystems/FAT/common.h
KernelLand/Modules/Filesystems/FAT/dir.c
KernelLand/Modules/Filesystems/InitRD/initrd.h
KernelLand/Modules/Filesystems/InitRD/main.c
KernelLand/Modules/Filesystems/NTFS/common.h
KernelLand/Modules/Filesystems/NTFS/dir.c
KernelLand/Modules/Filesystems/NTFS/main.c
KernelLand/Modules/Filesystems/RAMDisk/ramdisk.c
KernelLand/Modules/IPStack/adapters.c
KernelLand/Modules/IPStack/init.h [new file with mode: 0644]
KernelLand/Modules/IPStack/interface.c
KernelLand/Modules/IPStack/interface.h [new file with mode: 0644]
KernelLand/Modules/IPStack/main.c
KernelLand/Modules/IPStack/routing.c
KernelLand/Modules/IPStack/tcp.c
KernelLand/Modules/Input/Mouse/main.c
KernelLand/Modules/Storage/ATA/common.h
KernelLand/Modules/Storage/ATA/io.c
KernelLand/Modules/Storage/ATA/main.c
KernelLand/Modules/Storage/FDDv2/main.c
KernelLand/Modules/Storage/LVM/main.c
KernelLand/Modules/Storage/LVM/mbr.c
KernelLand/Modules/USB/Core/main.c
TODO.txt
Tools/DiskTool/src/actions.c
Tools/DiskTool/src/include/disktool_common.h
Tools/DiskTool/src/main.c
Usermode/Applications/mount_src/main.c

index 7c20b69..0e791b8 100644 (file)
@@ -31,7 +31,7 @@ typedef struct
 tVFS_Node      *NativeFS_Mount(const char *Device, const char **Arguments);\r
 void   NativeFS_Unmount(tVFS_Node *Node);\r
 tVFS_Node      *NativeFS_FindDir(tVFS_Node *Node, const char *Name);\r
-char   *NativeFS_ReadDir(tVFS_Node *Node, int Position);\r
+ int   NativeFS_ReadDir(tVFS_Node *Node, int Position, char Dest[FILENAME_MAX]);\r
 size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void *Buffer);\r
 size_t NativeFS_Write(tVFS_Node *Node, _acess_off_t Offset, size_t Length, const void *Buffer);\r
 void   NativeFS_Close(tVFS_Node *Node);\r
@@ -168,11 +168,10 @@ tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name)
        return Inode_CacheNode(info->InodeHandle, &baseRet);\r
 }\r
 \r
-char *NativeFS_ReadDir(tVFS_Node *Node, int Position)\r
+int NativeFS_ReadDir(tVFS_Node *Node, int Position, char Dest[FILENAME_MAX])\r
 {\r
        struct dirent   *ent;\r
        DIR     *dp = (void*)(tVAddr)Node->Inode;\r
-       char    *ret;\r
 \r
        ENTER("pNode iPosition", Node, Position);\r
 \r
@@ -184,16 +183,16 @@ char *NativeFS_ReadDir(tVFS_Node *Node, int Position)
        } while(Position-- && ent);\r
 \r
        if( !ent ) {\r
-               LEAVE('n');\r
-               return NULL;\r
+               LEAVE('i', -ENOENT);\r
+               return -ENOENT;\r
        }\r
        \r
-       ret = strdup(ent->d_name);\r
+       strncpy(Dest, ent->d_name, FILENAME_MAX);\r
 \r
        // TODO: Unlock node    \r
 \r
-       LEAVE('s', ret);\r
-       return ret;\r
+       LEAVE('i', 0);\r
+       return 0;\r
 }\r
 \r
 size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void *Buffer)\r
index cb62193..2adaec7 100644 (file)
@@ -26,9 +26,9 @@ typedef struct sPipe {
 // === PROTOTYPES ===
  int   FIFO_Install(char **Arguments);
  int   FIFO_IOCtl(tVFS_Node *Node, int Id, void *Data);
-char   *FIFO_ReadDir(tVFS_Node *Node, int Id);
+ int   FIFO_ReadDir(tVFS_Node *Node, int Id, char Dest[FILENAME_MAX]);
 tVFS_Node      *FIFO_FindDir(tVFS_Node *Node, const char *Filename);
- int   FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node      *FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
 void   FIFO_Reference(tVFS_Node *Node);
 void   FIFO_Close(tVFS_Node *Node);
  int   FIFO_Unlink(tVFS_Node *Node, const char *OldName);
@@ -92,19 +92,24 @@ int FIFO_IOCtl(tVFS_Node *Node, int Id, void *Data)
  * \fn char *FIFO_ReadDir(tVFS_Node *Node, int Id)
  * \brief Reads from the FIFO root
  */
-char *FIFO_ReadDir(tVFS_Node *Node, int Id)
+int FIFO_ReadDir(tVFS_Node *Node, int Id, char Dest[FILENAME_MAX])
 {
        tPipe   *tmp = gFIFO_NamedPipes;
        
        // Entry 0 is Anon Pipes
-       if(Id == 0)     return strdup("anon");
+       if(Id == 0) {
+               strcpy(Dest, "anon");
+               return 0;
+       }
        
        // Find the id'th node
        while(--Id && tmp)      tmp = tmp->Next;
-       // If node found, return it
-       if(tmp) return strdup(tmp->Name);
-       // else error return
-       return NULL;
+       // If the list ended, error return
+       if(!tmp)
+               return -EINVAL;
+       // Return good
+       strncpy(Dest, tmp->Name, FILENAME_MAX);
+       return 0;
 }
 
 /**
@@ -142,7 +147,7 @@ tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename)
 /**
  * \fn int FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
  */
-int FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
+tVFS_Node *FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
 {
        return 0;
 }
index f09389b..702c9cc 100644 (file)
@@ -33,7 +33,7 @@ typedef struct sPCIDevice
  int   PCI_Install(char **Arguments);\r
  int   PCI_ScanBus(int ID, int bFill);\r
  \r
-char   *PCI_int_ReadDirRoot(tVFS_Node *node, int pos);\r
+ int   PCI_int_ReadDirRoot(tVFS_Node *node, int pos, char Dest[FILENAME_MAX]);\r
 tVFS_Node      *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename);\r
 Uint32 PCI_int_GetBusAddr(Uint16 Bus, Uint16 Slot, Uint16 Fcn, Uint8 Offset);\r
 size_t PCI_int_ReadDevice(tVFS_Node *node, off_t Offset, size_t Length, void *buffer);\r
@@ -197,16 +197,16 @@ int PCI_ScanBus(int BusID, int bFill)
 /**\r
  * \brief Read from Root of PCI Driver\r
 */\r
-char *PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos)\r
+int PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])\r
 {\r
        ENTER("pNode iPos", Node, Pos);\r
        if(Pos < 0 || Pos >= giPCI_DeviceCount) {\r
-               LEAVE('n');\r
-               return NULL;\r
+               LEAVE_RET('i', -EINVAL);\r
        }\r
        \r
-       LEAVE('s', gPCI_Devices[Pos].Name);\r
-       return strdup( gPCI_Devices[Pos].Name );\r
+       LOG("Name = %s", gPCI_Devices[Pos].Name);\r
+       strncpy(Dest, gPCI_Devices[Pos].Name, FILENAME_MAX);\r
+       LEAVE_RET('i', 0);\r
 }\r
 /**\r
  */\r
index b4483b0..1e0c6bd 100644 (file)
@@ -31,7 +31,7 @@ typedef struct sSysFS_Ent
  int   SysFS_RemoveFile(int ID);
 #endif
 
-char   *SysFS_Comm_ReadDir(tVFS_Node *Node, int Id);
+ int   SysFS_Comm_ReadDir(tVFS_Node *Node, int Id, char Dest[FILENAME_MAX]);
 tVFS_Node      *SysFS_Comm_FindDir(tVFS_Node *Node, const char *Filename);
 size_t SysFS_Comm_ReadFile(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
 void   SysFS_Comm_CloseFile(tVFS_Node *Node);
@@ -250,8 +250,9 @@ int SysFS_UpdateFile(int ID, const char *Data, int Length)
        for( ent = gSysFS_FileList; ent; ent = ent->Next )
        {
                // It's a reverse sorted list
-               if(ent->Node.Inode < ID)        return 0;
-               if(ent->Node.Inode == ID)
+               if(ent->Node.Inode < (Uint64)ID)
+                       return 0;
+               if(ent->Node.Inode == (Uint64)ID)
                {
                        ent->Node.ImplPtr = (void*)Data;
                        ent->Node.Size = Length;
@@ -278,8 +279,8 @@ int SysFS_RemoveFile(int ID)
        for( ent = gSysFS_FileList; ent; prev = ent, ent = ent->Next )
        {
                // It's a reverse sorted list
-               if(ent->Node.Inode < ID)        return 0;
-               if(ent->Node.Inode == ID)       break;
+               if(ent->Node.Inode < (Uint64)ID)        return 0;
+               if(ent->Node.Inode == (Uint64)ID)       break;
        }
        
        if(!ent)        return 0;
@@ -323,16 +324,20 @@ int SysFS_RemoveFile(int ID)
  * \fn char *SysFS_Comm_ReadDir(tVFS_Node *Node, int Pos)
  * \brief Reads from a SysFS directory
  */
-char *SysFS_Comm_ReadDir(tVFS_Node *Node, int Pos)
+int SysFS_Comm_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tSysFS_Ent      *child = (tSysFS_Ent*)Node->ImplPtr;
-       if(Pos < 0 || Pos >= Node->Size)        return NULL;
+       if(Pos < 0 || (Uint64)Pos >= Node->Size)
+               return -EINVAL;
        
        for( ; child; child = child->Next, Pos-- )
        {
-               if( Pos == 0 )  return strdup(child->Name);
+               if( Pos == 0 ) {
+                       strncpy(Dest, child->Name, FILENAME_MAX);
+                       return 0;
+               }
        }
-       return NULL;
+       return -ENOENT;
 }
 
 /**
index 63db01e..fc6dea2 100644 (file)
@@ -34,7 +34,7 @@ extern void   Debug_SetKTerminal(const char *File);
 
 // === PROTOTYPES ===
  int   VT_Install(char **Arguments);
-char   *VT_ReadDir(tVFS_Node *Node, int Pos);
+ int   VT_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *VT_FindDir(tVFS_Node *Node, const char *Name);
  int   VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data);
 size_t VT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
@@ -268,11 +268,12 @@ void VT_SetResolution(int Width, int Height)
  * \fn char *VT_ReadDir(tVFS_Node *Node, int Pos)
  * \brief Read from the VTerm Directory
  */
-char *VT_ReadDir(tVFS_Node *Node, int Pos)
+int VT_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
-       if(Pos < 0)     return NULL;
-       if(Pos >= NUM_VTS)      return NULL;
-       return strdup( gVT_Terminals[Pos].Name );
+       if(Pos < 0)     return -EINVAL;
+       if(Pos >= NUM_VTS)      return -EINVAL;
+       strncpy(Dest, gVT_Terminals[Pos].Name, FILENAME_MAX);
+       return 0;
 }
 
 /**
index 49dc7b2..a57917d 100644 (file)
 #include <api_drv_disk.h>
 
 // --- Disk Driver Helpers ---
-Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer,
-       tDrvUtil_Read_Callback ReadBlocks, Uint64 BlockSize, void *Argument)
+size_t DrvUtil_ReadBlock(Uint64 Start, size_t Length, void *Buffer,
+       tDrvUtil_Read_Callback ReadBlocks, size_t BlockSize, void *Argument)
 {
        Uint8   tmp[BlockSize]; // C99
        Uint64  block = Start / BlockSize;
         int    offset = Start - block * BlockSize;
-        int    leading = BlockSize - offset;
+       size_t  leading = BlockSize - offset;
        Uint64  num;
         int    tailings;
-       Uint64  ret;
+       size_t  ret;
        
        ENTER("XStart XLength pBuffer pReadBlocks XBlockSize pArgument",
                Start, Length, Buffer, ReadBlocks, BlockSize, Argument);
@@ -82,17 +82,17 @@ Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer,
        return Length;
 }
 
-Uint64 DrvUtil_WriteBlock(Uint64 Start, Uint64 Length, const void *Buffer,
+size_t DrvUtil_WriteBlock(Uint64 Start, size_t Length, const void *Buffer,
        tDrvUtil_Read_Callback ReadBlocks, tDrvUtil_Write_Callback WriteBlocks,
-       Uint64 BlockSize, void *Argument)
+       size_t BlockSize, void *Argument)
 {
        Uint8   tmp[BlockSize]; // C99
        Uint64  block = Start / BlockSize;
-        int    offset = Start - block * BlockSize;
-        int    leading = BlockSize - offset;
+       size_t  offset = Start - block * BlockSize;
+       size_t  leading = BlockSize - offset;
        Uint64  num;
         int    tailings;
-       Uint64  ret;
+       size_t  ret;
        
        ENTER("XStart XLength pBuffer pReadBlocks pWriteBlocks XBlockSize pArgument",
                Start, Length, Buffer, ReadBlocks, WriteBlocks, BlockSize, Argument);
index 51ae771..1d062a5 100644 (file)
@@ -426,6 +426,7 @@ extern int  strucmp(const char *Str1, const char *Str2);
 extern char    *_strdup(const char *File, int Line, const char *Str);
 extern char    **str_split(const char *__str, char __ch);
 extern char    *strchr(const char *__s, int __c);
+extern char    *strrchr(const char *__s, int __c);
 extern int     strpos(const char *Str, char Ch);
 extern int     strpos8(const char *str, Uint32 search);
 extern void    itoa(char *buf, Uint64 num, int base, int minLength, char pad);
index c37dfec..bde78ab 100644 (file)
@@ -161,8 +161,8 @@ typedef Uint        (*tDrvUtil_Write_Callback)(Uint64 Address, Uint Count, const void *
  * \param Argument     An argument to pass to \a ReadBlocks\r
  * \return Number of bytes read\r
  */\r
-extern Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer,\r
-       tDrvUtil_Read_Callback ReadBlocks, Uint64 BlockSize, void *Argument);\r
+extern size_t DrvUtil_ReadBlock(Uint64 Start, size_t Length, void *Buffer,\r
+       tDrvUtil_Read_Callback ReadBlocks, size_t BlockSize, void *Argument);\r
 /**\r
  * \brief Writes a range to a block device using aligned writes\r
  * \param Start        Base byte offset\r
@@ -174,9 +174,9 @@ extern Uint64 DrvUtil_ReadBlock(Uint64 Start, Uint64 Length, void *Buffer,
  * \param Argument     An argument to pass to \a ReadBlocks and \a WriteBlocks\r
  * \return Number of bytes written\r
  */\r
-extern Uint64 DrvUtil_WriteBlock(Uint64 Start, Uint64 Length, const void *Buffer,\r
+extern size_t DrvUtil_WriteBlock(Uint64 Start, size_t Length, const void *Buffer,\r
        tDrvUtil_Read_Callback ReadBlocks, tDrvUtil_Write_Callback WriteBlocks,\r
-       Uint64 BlockSize, void *Argument);\r
+       size_t BlockSize, void *Argument);\r
 \r
 /**\r
  * \}\r
index 7c2e97a..a327cc0 100644 (file)
@@ -21,6 +21,7 @@ enum eErrorNums
        EEXIST, // Already exists
        ENFILE, // Too many open files
        ENOTDIR,        // Not a directory
+       EIO,    // IO Error
        
        EALREADY,       // Operation was a NOP
        EINTERNAL,      // Internal Error
index 98bc027..59824e2 100644 (file)
@@ -295,22 +295,19 @@ struct sVFS_NodeType
         * \brief Read from a directory
         * \param Node  Pointer to this node
         * \param Pos   Offset in the directory
-        * \return Pointer to the name of the item on the heap (will be freed
-        *         by the caller). If the directory end has been reached, NULL
-        *         will be returned.
-        *         If an item is required to be skipped either &::NULLNode,
-        *         ::VFS_SKIP or ::VFS_SKIPN(0...1023) will be returned.
+        * \param Dest  Destination for filename
+        * \return Zero on success, negative on error or +ve for ignore entry
         */
-       char    *(*ReadDir)(struct sVFS_Node *Node, int Pos);
+        int    (*ReadDir)(struct sVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
        
        /**
         * \brief Create a node in a directory
         * \param Node  Pointer to this node
         * \param Name  Name of the new child
         * \param Flags Flags to apply to the new child (directory or symlink)
-        * \return Zero on Success, non-zero on error (see errno.h)
+        * \return Created node or NULL on error
         */
-        int    (*MkNod)(struct sVFS_Node *Node, const char *Name, Uint Flags);
+       tVFS_Node       *(*MkNod)(struct sVFS_Node *Node, const char *Name, Uint Flags);
        
        /**
         * \brief Relink (Rename/Remove) a file/directory
index 8cabfa1..44c70f8 100644 (file)
@@ -13,6 +13,7 @@ typedef Uint64        tInode;
 typedef Uint32 tMount;
 
 // === CONSTANTS ===
+#define FILENAME_MAX   256
 //! Maximum size of a Memory Path generated by VFS_GetMemPath
 #define        VFS_MEMPATH_SIZE        (3 + (BITS/4)*2)
 /**
@@ -276,7 +277,7 @@ extern Uint64       VFS_Tell(int FD);
  * \param Buffer       Destination of read data
  * \return Number of read bytes
  */
-extern Uint64  VFS_Read(int FD, Uint64 Length, void *Buffer);
+extern size_t  VFS_Read(int FD, size_t Length, void *Buffer);
 /**
  * \brief Writes data to a file
  * \param FD   File handle returned by ::VFS_Open
@@ -284,7 +285,7 @@ extern Uint64       VFS_Read(int FD, Uint64 Length, void *Buffer);
  * \param Buffer       Source of written data
  * \return Number of bytes written
  */
-extern Uint64  VFS_Write(int FD, Uint64 Length, const void *Buffer);
+extern size_t  VFS_Write(int FD, size_t Length, const void *Buffer);
 
 /**
  * \brief Reads from a specific offset in the file
@@ -294,7 +295,7 @@ extern Uint64       VFS_Write(int FD, Uint64 Length, const void *Buffer);
  * \param Buffer       Source of read data
  * \return Number of bytes read
  */
-extern Uint64  VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer);
+extern size_t  VFS_ReadAt(int FD, Uint64 Offset, size_t Length, void *Buffer);
 /**
  * \brief Writes to a specific offset in the file
  * \param FD   File handle returned by ::VFS_Open
@@ -303,7 +304,7 @@ extern Uint64       VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer);
  * \param Buffer       Source of written data
  * \return Number of bytes written
  */
-extern Uint64  VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, const void *Buffer);
+extern size_t  VFS_WriteAt(int FD, Uint64 Offset, size_t Length, const void *Buffer);
 
 /**
  * \brief Sends an IOCtl request to the driver
@@ -368,10 +369,10 @@ extern int        VFS_Symlink(const char *Name, const char *Link);
 /**
  * \brief Read from a directory
  * \param FD   File handle returned by ::VFS_Open
- * \param Dest Destination array for the file name (max 255 bytes)
+ * \param Dest Destination array for the file name (max FILENAME_MAX bytes)
  * \return Boolean Success
  */
-extern int     VFS_ReadDir(int FD, char *Dest);
+extern int     VFS_ReadDir(int FD, char Dest[FILENAME_MAX]);
 /**
  * \brief Wait for an aciton on a file descriptor
  * \param MaxHandle    Maximum set handle in \a *Handles
index 68d2032..36b877c 100644 (file)
@@ -124,7 +124,7 @@ int strpos8(const char *str, Uint32 Search)
        {
                // ASCII Range
                if(Search < 128) {
-                       if(str[pos] == Search)  return pos;
+                       if(str[pos] == (char)Search)    return pos;
                        continue;
                }
                if(*(Uint8*)(str+pos) < 128)    continue;
@@ -387,7 +387,7 @@ int ModUtil_SetIdent(char *Dest, const char *Value)
 
 int Hex(char *Dest, size_t Size, const Uint8 *SourceData)
 {
-        int    i;
+       size_t  i;
        for( i = 0; i < Size; i ++ )
        {
                sprintf(Dest + i*2, "%02x", SourceData[i]);
@@ -400,8 +400,7 @@ int Hex(char *Dest, size_t Size, const Uint8 *SourceData)
  */
 int UnHex(Uint8 *Dest, size_t DestSize, const char *SourceString)
 {
-        int    i;
-       
+       size_t  i;
        for( i = 0; i < DestSize*2; i += 2 )
        {
                Uint8   val = 0;
index 08ebc62..ef94426 100644 (file)
@@ -49,6 +49,7 @@ EXPORT(tolower);
 
 EXPORT(strucmp);
 EXPORT(strchr);
+EXPORT(strrchr);
 EXPORT(strpos);
 EXPORT(strlen);
 EXPORT(strcpy);
@@ -529,6 +530,15 @@ char *strchr(const char *__s, int __c)
        return NULL;
 }
 
+char *strrchr(const char *__s, int __c)
+{
+       size_t ofs = strlen(__s);
+       while(--ofs && __s[ofs] != __c);
+       if( __s[ofs] == __c )
+               return (char*)__s + ofs;
+       return NULL;
+}
+
 /**
  * \fn int strpos(const char *Str, char Ch)
  * \brief Search a string for an ascii character
index 26f6f0f..fab9d56 100644 (file)
@@ -41,7 +41,7 @@ int VFS_MkNod(const char *Path, Uint Flags)
         int    pos = 0, oldpos = 0;
         int    next = 0;
        tVFS_Node       *parent;
-        int    ret;
+       tVFS_Node       *ret;
        
        ENTER("sPath xFlags", Path, Flags);
        
@@ -92,6 +92,7 @@ int VFS_MkNod(const char *Path, Uint Flags)
        
        // Create node
        ret = parent->Type->MkNod(parent, name, Flags);
+       _CloseNode(ret);
        
        // Free allocated string
        free(absPath);
@@ -101,8 +102,8 @@ int VFS_MkNod(const char *Path, Uint Flags)
        _CloseNode(parent);
 
        // Return whatever the driver said      
-       LEAVE('i', ret);
-       return ret;
+       LEAVE('i', ret==NULL);
+       return ret==NULL;
 }
 
 /**
@@ -154,7 +155,7 @@ int VFS_Symlink(const char *Name, const char *Link)
 int VFS_ReadDir(int FD, char *Dest)
 {
        tVFS_Handle     *h = VFS_GetHandle(FD);
-       char    *tmp;
+        int    rv;
        
        //ENTER("ph pDest", h, Dest);
        
@@ -163,29 +164,24 @@ int VFS_ReadDir(int FD, char *Dest)
                return 0;
        }
        
-       if(h->Node->Size != -1 && h->Position >= h->Node->Size) {
+       if(h->Node->Size != (Uint64)-1 && h->Position >= h->Node->Size) {
                //LEAVE('i', 0);
                return 0;
        }
        
        do {
-               tmp = h->Node->Type->ReadDir(h->Node, h->Position);
-               if((Uint)tmp < (Uint)VFS_MAXSKIP)
-                       h->Position += (Uint)tmp;
+               rv = h->Node->Type->ReadDir(h->Node, h->Position, Dest);
+               if(rv > 0)
+                       h->Position += rv;
                else
                        h->Position ++;
-       } while(tmp != NULL && (Uint)tmp < (Uint)VFS_MAXSKIP);
+       } while(rv > 0);
        
-       //LOG("tmp = '%s'", tmp);
-       
-       if(!tmp) {
+       if(rv < 0) {
                //LEAVE('i', 0);
                return 0;
        }
        
-       strcpy(Dest, tmp);
-       free(tmp);
-       
        //LEAVE('i', 1);
        return 1;
 }
index 9ab2b7b..9389822 100644 (file)
@@ -15,7 +15,7 @@ void  DevFS_DelDevice(tDevFS_Driver *Device);
 #endif
 tVFS_Node      *DevFS_InitDevice(const char *Device, const char **Options);
 void   DevFS_Unmount(tVFS_Node *RootNode);
-char   *DevFS_ReadDir(tVFS_Node *Node, int Pos);
+ int   DevFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *DevFS_FindDir(tVFS_Node *Node, const char *Name);
 
 // === GLOBALS ===
@@ -128,21 +128,24 @@ void DevFS_Unmount(tVFS_Node *RootNode)
 /**
  * \fn char *DevFS_ReadDir(tVFS_Node *Node, int Pos)
  */
-char *DevFS_ReadDir(tVFS_Node *Node, int Pos)
+int DevFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tDevFS_Driver   *dev;
        
-       if(Pos < 0)     return NULL;
+       if(Pos < 0)     return -EINVAL;
        
        for(dev = gDevFS_Drivers;
                dev && Pos--;
                dev = dev->Next
                );
        
-       if(dev)
-               return strdup(dev->Name);
-       else
-               return NULL;
+       if(dev) {
+               strncpy(Dest, dev->Name, FILENAME_MAX);
+               return 0;
+       }
+       else {
+               return -ENOENT;
+       }
 }
 
 /**
index abe5945..5685861 100644 (file)
@@ -13,9 +13,9 @@
 
 // === PROTOTYPES ===
 tVFS_Node      *Root_InitDevice(const char *Device, const char **Options);
- int   Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node      *Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
 tVFS_Node      *Root_FindDir(tVFS_Node *Node, const char *Name);
-char   *Root_ReadDir(tVFS_Node *Node, int Pos);
+ int   Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 size_t Root_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
 size_t Root_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);
 tRamFS_File    *Root_int_AllocFile(void);
@@ -82,7 +82,7 @@ tVFS_Node *Root_InitDevice(const char *Device, const char **Options)
  * \fn int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
  * \brief Create an entry in the root directory
  */
-int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
+tVFS_Node *Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
 {
        tRamFS_File     *parent = Node->ImplPtr;
        tRamFS_File     *child;
@@ -91,16 +91,18 @@ int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
        ENTER("pNode sName xFlags", Node, Name, Flags);
        
        LOG("Sanity check name length - %i > %i", strlen(Name)+1, sizeof(child->Name));
-       if(strlen(Name) + 1 > sizeof(child->Name))
-               LEAVE_RET('i', EINVAL);
+       if(strlen(Name) + 1 > sizeof(child->Name)) {
+               errno = EINVAL;
+               LEAVE_RET('n', NULL);
+       }
        
        // Find last child, while we're at it, check for duplication
        for( child = parent->Data.FirstChild; child; prev = child, child = child->Next )
        {
                if(strcmp(child->Name, Name) == 0) {
                        LOG("Duplicate");
-                       LEAVE('i', EEXIST);
-                       return EEXIST;
+                       errno = EEXIST;
+                       LEAVE_RET('n', NULL);
                }
        }
        
@@ -139,8 +141,8 @@ int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
        
        parent->Node.Size ++;
        
-       LEAVE('i', EOK);
-       return EOK;
+       LEAVE('n', &child->Node);
+       return &child->Node;
 }
 
 /**
@@ -172,16 +174,19 @@ tVFS_Node *Root_FindDir(tVFS_Node *Node, const char *Name)
  * \fn char *Root_ReadDir(tVFS_Node *Node, int Pos)
  * \brief Get an entry from the filesystem
  */
-char *Root_ReadDir(tVFS_Node *Node, int Pos)
+int Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tRamFS_File     *parent = Node->ImplPtr;
        tRamFS_File     *child = parent->Data.FirstChild;
        
        for( ; child && Pos--; child = child->Next ) ;
        
-       if(child)       return strdup(child->Name);
+       if(child) {
+               strncpy(Dest, child->Name, FILENAME_MAX);
+               return 0;
+       }
        
-       return NULL;
+       return -ENOENT;
 }
 
 /**
index 7379e3d..dc55fe2 100644 (file)
@@ -4,18 +4,19 @@
  */
 #define DEBUG  0
 #include <acess.h>
-#include "vfs.h"
-#include "vfs_int.h"
+#include <vfs.h>
+#include <vfs_ext.h>
+#include <vfs_int.h>
 
 // === 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;
+       size_t  ret;
        
        ENTER("iFD XLength pBuffer", FD, Length, Buffer);
        
@@ -46,7 +47,7 @@ Uint64 VFS_Read(int FD, Uint64 Length, void *Buffer)
        }
        
        ret = h->Node->Type->Read(h->Node, h->Position, Length, Buffer);
-       if(ret == -1)   LEAVE_RET('i', -1);
+       if(ret == (size_t)-1)   LEAVE_RET('i', -1);
        
        h->Position += ret;
        LEAVE('X', ret);
@@ -57,10 +58,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;
@@ -80,7 +81,7 @@ Uint64 VFS_ReadAt(int FD, Uint64 Offset, Uint64 Length, void *Buffer)
        }
        
        ret = h->Node->Type->Read(h->Node, Offset, Length, Buffer);
-       if(ret == -1)   return -1;
+       if(ret == (size_t)-1)   return -1;
        return ret;
 }
 
@@ -88,10 +89,10 @@ 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;
@@ -108,7 +109,7 @@ Uint64 VFS_Write(int FD, Uint64 Length, const void *Buffer)
        }
        
        ret = h->Node->Type->Write(h->Node, h->Position, Length, Buffer);
-       if(ret == -1)   return -1;
+       if(ret == (size_t)-1)   return -1;
 
        h->Position += ret;
        return ret;
@@ -118,10 +119,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;
@@ -137,7 +138,7 @@ Uint64 VFS_WriteAt(int FD, Uint64 Offset, Uint64 Length, const void *Buffer)
                return -1;
        }
        ret = h->Node->Type->Write(h->Node, Offset, Length, Buffer);
-       if(ret == -1)   return -1;
+       if(ret == (size_t)-1)   return -1;
        return ret;
 }
 
@@ -180,7 +181,7 @@ int VFS_Seek(int FD, Sint64 Offset, int Whence)
        
        // Set relative to end of file
        if(Whence < 0) {
-               if( h->Node->Size == -1 )       return -1;
+               if( h->Node->Size == (Uint64)-1 )       return -1;
 
                h->Position = h->Node->Size - Offset;
                return 0;
index 5ff0e7c..38f7c80 100644 (file)
@@ -27,7 +27,7 @@ void  VFS_UpdateDriverFile(void);
 EXPORT(VFS_AddDriver);
 
 // === GLOBALS ===
-tVFS_Node      NULLNode = {0};
+tVFS_Node      NULLNode = {.Type=NULL};
 tShortSpinlock slDriverListLock;
 tVFS_Driver    *gVFS_Drivers = NULL;
 char   *gsVFS_DriverFile = NULL;
index 983a2b2..5ea67c1 100644 (file)
@@ -292,7 +292,7 @@ restart_parse:
                }
                if( !curNode->Type->FindDir )
                {
-                       LOG("Finddir failure on '%s' - No FindDir method in %s", Path, curNode->Type->Name);
+                       LOG("Finddir failure on '%s' - No FindDir method in %s", Path, curNode->Type->TypeName);
                        goto _error;
                }
                LOG("FindDir{=%p}(%p, '%s')", curNode->Type->FindDir, curNode, pathEle);
@@ -338,6 +338,7 @@ restart_parse:
                                path_buffer[ curNode->Size ] = '\0';
                                LOG("path_buffer = '%s'", path_buffer);
                                strcat(path_buffer, Path + ofs+nextSlash);
+                               // TODO: Pass to VFS_GetAbsPath to handle ../. in the symlink
                                
                                Path = path_buffer;
 //                             Log_Debug("VFS", "VFS_ParsePath: Symlink translated to '%s'", Path);
@@ -390,7 +391,7 @@ restart_parse:
        LOG("tmpNode = %p", tmpNode);
        // Check if file was found
        if(!tmpNode) {
-               LOG("Node '%s' not found in dir '%s'", &Path[ofs], Path);
+               LOG("Node '%s' not found in dir '%.*s'", &Path[ofs], ofs, Path);
                goto _error;
        }
        _CloseNode( curNode );
@@ -503,12 +504,44 @@ int VFS_OpenEx(const char *Path, Uint Flags, Uint Mode)
        if( !node && (Flags & VFS_OPENFLAG_CREATE) )
        {
                // TODO: Translate `Mode` into ACL and node flags
-               // Get parent, create node
-               if( VFS_MkNod(absPath, 0) ) {
+               Uint    new_flags = 0;
+               
+               // Split path at final separator
+               char *file = strrchr(absPath, '/');
+               *file = '\0';
+               file ++;
+
+               // Get parent node
+               tVFS_Mount      *pmnt;
+               tVFS_Node *pnode = VFS_ParsePath(absPath, NULL, &pmnt);
+               if(!pnode) {
+                       LOG("Unable to open parent '%s'", absPath);
+                       free(absPath);
+                       errno = ENOENT;
+                       LEAVE_RET('i', -1);
+               }
+
+               // TODO: Check ACLs on the parent
+               if( !VFS_CheckACL(pnode, VFS_PERM_EXECUTE|VFS_PERM_WRITE) ) {
+                       _CloseNode(pnode);
+                       pmnt->OpenHandleCount --;
                        free(absPath);
+                       LEAVE('i', -1);
                        return -1;
                }
-               node = VFS_ParsePath(absPath, NULL, &mnt);
+
+               // Check that there's a MkNod method
+               if( !pnode->Type || !pnode->Type->MkNod ) {
+                       Log_Warning("VFS", "VFS_Open - Directory has no MkNod method");
+                       errno = EINVAL;
+                       LEAVE_RET('i', -1);
+               }
+               
+               node = pnode->Type->MkNod(pnode, file, new_flags);
+               // Fall through on error check
+               
+               _CloseNode(pnode);
+               pmnt->OpenHandleCount --;
        }
        
        // Free generated path
index 4039a7c..de0b30a 100644 (file)
@@ -5,17 +5,17 @@
  * dir.c
  * - Directory Handling
  */
-#define DEBUG  0
+#define DEBUG  1
 #define VERBOSE        0
 #include "ext2_common.h"
 
 // === MACROS ===
-#define BLOCK_DIR_OFS(_data, _block)   ((Uint16*)(_data)[(_block)])
+#define BLOCK_DIR_OFS(_data, _block)   (((Uint16*)(_data))[(_block)])
 
 // === PROTOTYPES ===
-char   *Ext2_ReadDir(tVFS_Node *Node, int Pos);
+ int   Ext2_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *Ext2_FindDir(tVFS_Node *Node, const char *FileName);
- int   Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node      *Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
  int   Ext2_Unlink(tVFS_Node *Node, const char *OldName);
  int   Ext2_Link(tVFS_Node *Parent, const char *Name, tVFS_Node *Node);
 // --- Helpers ---
@@ -44,7 +44,7 @@ tVFS_NodeType gExt2_FileType = {
  * \param Node Directory node
  * \param Pos  Position of desired element
  */
-char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
+int Ext2_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tExt2_Inode     inode;
        tExt2_DirEnt    dirent;
@@ -92,8 +92,8 @@ char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
        
        // Check for the end of the list
        if(size <= 0 || size > inode.i_size) {
-               LEAVE('n');
-               return NULL;
+               LEAVE('i', -ENOENT);
+               return -ENOENT;
        }
        
        // Read Entry
@@ -103,20 +103,21 @@ char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
        dirent.name[ dirent.name_len ] = '\0';  // Cap off string
        
        if( dirent.name_len == 0 ) {
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;
+               LEAVE('i', 1);
+               return 1;
        }
        
        // Ignore . and .. (these are done in the VFS)
        if( (dirent.name[0] == '.' && dirent.name[1] == '\0')
        ||  (dirent.name[0] == '.' && dirent.name[1] == '.' && dirent.name[2]=='\0')) {
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;        // Skip
+               LEAVE('i', 1);
+               return 1;       // Skip
        }
        
-       LEAVE('s', dirent.name);
-       // Create new node
-       return strdup(dirent.name);
+       LOG("Name '%s'", dirent.name);
+       strncpy(Dest, dirent.name, FILENAME_MAX);
+       LEAVE('i', 0);
+       return 0;
 }
 
 /**
@@ -177,18 +178,20 @@ tVFS_Node *Ext2_FindDir(tVFS_Node *Node, const char *Filename)
  * \fn int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
  * \brief Create a new node
  */
-int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
+tVFS_Node *Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
 {
        ENTER("pParent sName xFlags", Parent, Name, Flags);
        
        Uint64 inodeNum = Ext2_int_AllocateInode(Parent->ImplPtr, Parent->Inode);
        if( inodeNum == 0 ) {
-               return -1;
+               LOG("Inode allocation failed");
+               LEAVE_RET('n', NULL);
        }
        tVFS_Node *child = Ext2_int_CreateNode(Parent->ImplPtr, inodeNum);
        if( !child ) {
                Ext2_int_DereferenceInode(Parent->ImplPtr, inodeNum);
-               return -1;
+               Log_Warning("Ext2", "Ext2_MkNod - Node creation failed");
+               LEAVE_RET('n', NULL);
        }
 
        child->Flags = Flags & (VFS_FFLAG_DIRECTORY|VFS_FFLAG_SYMLINK|VFS_FFLAG_READONLY);
@@ -202,9 +205,11 @@ int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
        // TODO: Set up ACLs
 
        int rv = Ext2_Link(Parent, Name, child);
-       child->Type->Close(child);
-       LEAVE('i', rv);
-       return rv;
+       if( rv ) {
+               Ext2_CloseFile(child);
+               return NULL;
+       }
+       LEAVE_RET('p', child);
 }
 
 /**
@@ -216,6 +221,7 @@ int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
  */
 int Ext2_Unlink(tVFS_Node *Node, const char *OldName)
 {
+       Log_Warning("Ext2", "TODO: Impliment Ext2_Unlink");
        return 1;
 }
 
@@ -228,17 +234,21 @@ int Ext2_Unlink(tVFS_Node *Node, const char *OldName)
  */
 int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child)
 {      
-       #if 0
+       #if 1
        tExt2_Disk      *disk = Node->ImplPtr;
        tExt2_Inode     inode;
-       tExt2_DirEnt    dirent;
+       tExt2_DirEnt    *dirent;
        tExt2_DirEnt    newEntry;
-       Uint64  Base;   // Block's Base Address
+       Uint64  base;   // Block's Base Address
         int    block = 0, ofs = 0;
        Uint    size;
        void    *blockData;
-        int    bestMatch = -1, bestSize, bestBlock, bestOfs;
+        int    bestMatch = -1;
+        int    bestSize=0, bestBlock=0, bestOfs=0, bestNeedsSplit=0;
         int    nEntries;
+
+       ENTER("pNode sName pChild",
+               Node, Name, Child);
        
        blockData = malloc(disk->BlockSize);
        
@@ -248,7 +258,7 @@ int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child)
        // Create a stub entry
        newEntry.inode = Child->Inode;
        newEntry.name_len = strlen(Name);
-       newEntry.rec_len = (newEntry.name_len+3+8)&~3;
+       newEntry.rec_len = ((newEntry.name_len+3)&~3) + EXT2_DIRENT_SIZE;
        newEntry.type = inode.i_mode >> 12;
        memcpy(newEntry.name, Name, newEntry.name_len);
        
@@ -257,13 +267,18 @@ int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child)
        size = inode.i_size;
        
        // Get a lock on the inode
-       Ext2_int_LockInode(disk, Node->Inode);
-       
+       //Ext2_int_LockInode(disk, Node->Inode);
+       Mutex_Acquire(&Node->Lock);
+
+//     if( !Node->Data ) {
+//     }
+
        // Get First Block
        // - Do this ourselves as it is a simple operation
        base = inode.i_block[0] * disk->BlockSize;
        VFS_ReadAt( disk->FD, base, disk->BlockSize, blockData );
        block = 0;
+       nEntries = 0;
        // Find File
        while(size > 0)
        {
@@ -274,10 +289,12 @@ int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child)
                                "Directory entry %i of inode 0x%x extends over a block boundary",
                                nEntries, (Uint)Node->Inode);
                }
-               else {
-               
+               else
+               {
+                       LOG("Entry %i: %x %i bytes", nEntries, dirent->type, dirent->rec_len);
                        // Free entry
-                       if(dirent->type == 0) {
+                       if(dirent->type == 0)
+                       {
                                if( dirent->rec_len >= newEntry.rec_len
                                 && (bestMatch == -1 || bestSize > dirent->rec_len) )
                                {
@@ -285,23 +302,40 @@ int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child)
                                        bestSize = dirent->rec_len;
                                        bestBlock = block;
                                        bestOfs = ofs;
+                                       bestNeedsSplit = 0;
                                }
                        }
                        // Non free - check name to avoid duplicates
-                       else {
+                       else
+                       {
+                               LOG(" name='%.*s'", dirent->name_len, dirent->name);
                                if(strncmp(Name, dirent->name, dirent->name_len) == 0) {
-                                       Ext2_int_UnlockInode(disk, Node->Inode);
+                                       //Ext2_int_UnlockInode(disk, Node->Inode);
+                                       Mutex_Release(&Node->Lock);
+                                       LEAVE('i', 1);
                                        return 1;       // ERR_???
                                }
+                               
+                                int    spare_space = dirent->rec_len - (dirent->name_len + EXT2_DIRENT_SIZE);
+                               if( spare_space > newEntry.rec_len
+                                && (bestMatch == -1 || bestSize > spare_space) )
+                               {
+                                       bestMatch = nEntries;
+                                       bestSize = spare_space;
+                                       bestBlock = block;
+                                       bestOfs = ofs;
+                                       bestNeedsSplit = 1;
+                               }
                        }
                }
                
                // Increment the pointer
                nEntries ++;
                ofs += dirent->rec_len;
-               if( ofs >= disk->BlockSize ) {
+               size -= dirent->rec_len;
+               if( size > 0 && ofs >= disk->BlockSize ) {
                        // Read the next block if needed
-                       BLOCK_DIR_OFS(Node->Data, block) = nEntries;
+               //      BLOCK_DIR_OFS(Node->Data, block) = nEntries;
                        block ++;
                        ofs = 0;
                        base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
@@ -309,26 +343,66 @@ int Ext2_Link(tVFS_Node *Node, const char *Name, tVFS_Node *Child)
                }
        }
        
+       LOG("bestMatch = %i", bestMatch);
+       // If EOF was reached with no space, check if we can fit one on the end
+       if( bestMatch < 0 && ofs + newEntry.rec_len < disk->BlockSize ) {
+               Node->Size += newEntry.rec_len;
+               Node->Flags |= VFS_FFLAG_DIRTY;
+               bestBlock = block;
+               bestOfs = ofs;
+               bestSize = newEntry.rec_len;
+               bestNeedsSplit = 0;
+       }
        // Check if a free slot was found
-       if( bestMatch >= 0 ) {
+       if( bestMatch >= 0 )
+       {
                // Read-Modify-Write
-               bestBlock = Ext2_int_GetBlockAddr(disk, inode.i_block, bestBlock);
-               if( block > 0 )
-                       bestMatch = BLOCK_DIR_OFS(Node->Data, bestBlock);
+               base = Ext2_int_GetBlockAddr(disk, inode.i_block, bestBlock);
                VFS_ReadAt( disk->FD, base, disk->BlockSize, blockData );
                dirent = blockData + bestOfs;
-               memcpy(dirent, newEntry, newEntry.rec_len);
+               // Shorten a pre-existing entry
+               if(bestNeedsSplit)
+               {
+                       dirent->rec_len = EXT2_DIRENT_SIZE + dirent->name_len;
+                       bestOfs += dirent->rec_len;
+                       //bestSize -= dirent->rec_len; // (not needed, bestSize is the spare space after)
+                       dirent = blockData + bestOfs;
+               }
+               // Insert new file entry
+               memcpy(dirent, &newEntry, newEntry.rec_len);
+               // Create a new blank entry
+               if( bestSize != newEntry.rec_len )
+               {
+                       bestOfs += newEntry.rec_len;
+                       dirent = blockData + bestOfs;
+
+                       dirent->rec_len = bestSize - newEntry.rec_len;                  
+                       dirent->type = 0;
+               }
+               // Save changes
                VFS_WriteAt( disk->FD, base, disk->BlockSize, blockData );
        }
        else {
                // Allocate block, Write
-               block = Ext2_int_AllocateBlock(Disk, block);
-               Log_Warning("EXT2", "");
+               Uint32 newblock = Ext2_int_AllocateBlock(disk, base / disk->BlockSize);
+               Ext2_int_AppendBlock(disk, &inode, newblock);
+               base = newblock * disk->BlockSize;
+               Node->Size += newEntry.rec_len;
+               Node->Flags |= VFS_FFLAG_DIRTY;
+               memcpy(blockData, &newEntry, newEntry.rec_len);
+               memset(blockData + newEntry.rec_len, 0, disk->BlockSize - newEntry.rec_len);
+               VFS_WriteAt( disk->FD, base, disk->BlockSize, blockData );
        }
 
-       Ext2_int_UnlockInode(disk, Node->Inode);
+       Child->ImplInt ++;
+       Child->Flags |= VFS_FFLAG_DIRTY;
+
+       //Ext2_int_UnlockInode(disk, Node->Inode);
+       Mutex_Release(&Node->Lock);
+       LEAVE('i', 0);
        return 0;
        #else
+       Log_Warning("Ext2", "TODO: Impliment Ext2_Link");
        return 1;
        #endif
 }
@@ -355,6 +429,7 @@ tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)
        // Set identifiers
        retNode.Inode = InodeID;
        retNode.ImplPtr = Disk;
+       retNode.ImplInt = inode.i_links_count;
        
        // Set file length
        retNode.Size = inode.i_size;
@@ -399,3 +474,10 @@ tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)
        // Save in node cache and return saved node
        return Inode_CacheNode(Disk->CacheID, &retNode);
 }
+
+int Ext2_int_WritebackNode(tExt2_Disk *Disk, tVFS_Node *Node)
+{
+       Log_Warning("Ext2","TODO: Impliment Ext2_int_WritebackNode");
+       return 0;
+}
+
index 5c9f97a..adf9163 100644 (file)
@@ -10,6 +10,9 @@
 #include "ext2_common.h"\r
 #include <modules.h>\r
 \r
+#define MIN_BLOCKS_PER_GROUP   2\r
+#define MAX_BLOCK_LOG_SIZE     10      // 1024 << 10 = 1MiB\r
+\r
 // === IMPORTS ===\r
 extern tVFS_NodeType   gExt2_DirType;\r
 \r
@@ -92,7 +95,7 @@ int Ext2_Detect(int FD)
 */\r
 tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options)\r
 {\r
-       tExt2_Disk      *disk;\r
+       tExt2_Disk      *disk = NULL;\r
         int    fd;\r
         int    groupCount;\r
        tExt2_SuperBlock        sb;\r
@@ -115,11 +118,15 @@ tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options)
        if(sb.s_magic != 0xEF53) {\r
                Log_Warning("EXT2", "Volume '%s' is not an EXT2 volume (0x%x != 0xEF53)",\r
                        Device, sb.s_magic);\r
-               VFS_Close(fd);\r
-               LEAVE('n');\r
-               return NULL;\r
+               goto _error;\r
        }\r
-       \r
+\r
+       if( sb.s_blocks_per_group < MIN_BLOCKS_PER_GROUP ) {\r
+               Log_Warning("Ext2", "Blocks per group is too small (%i < %i)",\r
+                       sb.s_blocks_per_group, MIN_BLOCKS_PER_GROUP);\r
+               goto _error;\r
+       }       \r
+\r
        // Get Group count\r
        groupCount = DivUp(sb.s_blocks_count, sb.s_blocks_per_group);\r
        LOG("groupCount = %i", groupCount);\r
@@ -128,9 +135,7 @@ tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options)
        disk = malloc(sizeof(tExt2_Disk) + sizeof(tExt2_Group)*groupCount);\r
        if(!disk) {\r
                Log_Warning("EXT2", "Unable to allocate disk structure");\r
-               VFS_Close(fd);\r
-               LEAVE('n');\r
-               return NULL;\r
+               goto _error;\r
        }\r
        disk->FD = fd;\r
        memcpy(&disk->SuperBlock, &sb, 1024);\r
@@ -140,6 +145,11 @@ tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options)
        disk->CacheID = Inode_GetHandle();\r
        \r
        // Get Block Size\r
+       if( sb.s_log_block_size > MAX_BLOCK_LOG_SIZE ) {\r
+               Log_Warning("Ext2", "Block size (log2) too large (%i > %i)",\r
+                       sb.s_log_block_size, MAX_BLOCK_LOG_SIZE);\r
+               goto _error;\r
+       }\r
        disk->BlockSize = 1024 << sb.s_log_block_size;\r
        LOG("Disk->BlockSie = 0x%x (1024 << %i)", disk->BlockSize, sb.s_log_block_size);\r
        \r
@@ -186,6 +196,12 @@ tVFS_Node *Ext2_InitDevice(const char *Device, const char **Options)
        \r
        LEAVE('p', &disk->RootNode);\r
        return &disk->RootNode;\r
+_error:\r
+       if( disk )\r
+               free(disk);\r
+       VFS_Close(fd);\r
+       LEAVE('n');\r
+       return NULL;\r
 }\r
 \r
 /**\r
@@ -209,29 +225,40 @@ void Ext2_Unmount(tVFS_Node *Node)
 void Ext2_CloseFile(tVFS_Node *Node)\r
 {\r
        tExt2_Disk      *disk = Node->ImplPtr;\r
+       ENTER("pNode", Node);\r
 \r
        if( Mutex_Acquire(&Node->Lock) != 0 )\r
        {\r
+               LEAVE('-');\r
                return ;\r
        }\r
 \r
        if( Node->Flags & VFS_FFLAG_DIRTY )\r
        {\r
                // Commit changes\r
+               Log_Warning("Ext2", "TODO: Commit node changes");\r
        }\r
 \r
        int was_not_referenced = (Node->ImplInt == 0);\r
        tVFS_ACL        *acls = Node->ACLs;\r
-       if( Inode_UncacheNode(disk->CacheID, Node->Inode) )\r
+       if( Inode_UncacheNode(disk->CacheID, Node->Inode) == 1 )\r
        {\r
                if( was_not_referenced )\r
                {\r
+                       LOG("Removng inode");\r
                        // Remove inode\r
+                       Log_Warning("Ext2", "TODO: Remove inode when not referenced");\r
                }\r
                if( acls != &gVFS_ACL_EveryoneRW ) {\r
                        free(acls);\r
                }\r
+               LOG("Node cleaned");\r
+       }\r
+       else {\r
+               LOG("Still referenced, releasing lock");\r
+               Mutex_Release(&Node->Lock);\r
        }\r
+       LEAVE('-');\r
        return ;\r
 }\r
 \r
@@ -355,8 +382,67 @@ Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)
  */\r
 Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)\r
 {\r
-//     Uint    block = (Parent - 1) / Disk->SuperBlock.s_inodes_per_group;\r
-       Log_Warning("EXT2", "Ext2_int_AllocateInode is unimplemented");\r
+       Uint    start_group = (Parent - 1) / Disk->SuperBlock.s_inodes_per_group;\r
+       Uint    group = start_group;\r
+\r
+       if( Disk->SuperBlock.s_free_inodes_count == 0 ) \r
+       {\r
+               Log_Notice("Ext2", "Ext2_int_AllocateInode - Out of inodes on %p", Disk);\r
+               return 0;\r
+       }\r
+\r
+       while( group < Disk->GroupCount && Disk->Groups[group].bg_free_inodes_count == 0 )\r
+               group ++;\r
+       if( group == Disk->GroupCount )\r
+       {\r
+               group = 0;\r
+               while( group < start_group && Disk->Groups[group].bg_free_inodes_count == 0 )\r
+                       group ++;\r
+       }\r
+       \r
+       if( Disk->Groups[group].bg_free_inodes_count == 0 )\r
+       {\r
+               Log_Notice("Ext2", "Ext2_int_AllocateInode - Out of inodes on %p, but superblock says some free", Disk);\r
+               return 0;\r
+       }\r
+\r
+       // Load bitmap for group\r
+       //  (s_inodes_per_group / 8) bytes worth\r
+       // - Allocate a buffer the size of a sector/block\r
+       // - Read in part of the bitmap\r
+       // - Search for a free inode\r
+       tExt2_Group     *bg = &Disk->Groups[group];\r
+        int    ofs = 0;\r
+       do {\r
+               const int sector_size = 512;\r
+               Uint8 buf[sector_size];\r
+               VFS_ReadAt(Disk->FD, Disk->BlockSize*bg->bg_inode_bitmap+ofs, sector_size, buf);\r
+\r
+               int byte, bit;\r
+               for( byte = 0; byte < sector_size && buf[byte] != 0xFF; byte ++ )\r
+                       ;\r
+               if( byte < sector_size )\r
+               {\r
+                       for( bit = 0; bit < 8 && buf[byte] & (1 << bit); bit ++)\r
+                               ;\r
+                       ASSERT(bit != 8);\r
+                       buf[byte] |= 1 << bit;\r
+                       VFS_WriteAt(Disk->FD, Disk->BlockSize*bg->bg_inode_bitmap+ofs, sector_size, buf);\r
+\r
+                       bg->bg_free_inodes_count --;\r
+                       Disk->SuperBlock.s_free_inodes_count --;\r
+\r
+                       Uint32  ret = group * Disk->SuperBlock.s_inodes_per_group + byte * 8 + bit + 1;\r
+                       Log_Debug("Ext2", "Ext2_int_AllocateInode - Allocated 0x%x", ret);\r
+                       return ret;\r
+               }\r
+\r
+               ofs += sector_size;\r
+       } while(ofs < Disk->SuperBlock.s_inodes_per_group / 8);\r
+\r
+       Log_Notice("Ext2", "Ext2_int_AllocateInode - Out of inodes in group %p:%i but header reported free",\r
+               Disk, group);\r
+\r
        return 0;\r
 }\r
 \r
@@ -365,7 +451,7 @@ Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)
  */\r
 void Ext2_int_DereferenceInode(tExt2_Disk *Disk, Uint32 Inode)\r
 {\r
-       \r
+       Log_Warning("Ext2", "TODO: Impliment Ext2_int_DereferenceInode");\r
 }\r
 \r
 /**\r
index 1d994dd..5515429 100644 (file)
@@ -2,10 +2,6 @@
  * Acess OS
  * Ext2 Driver Version 1
  */
-/**
- * \file ext2_common.h
- * \brief Second Extended Filesystem Driver
- */
 #ifndef _EXT2_COMMON_H
 #define _EXT2_COMMON_H
 #include <acess.h>
@@ -37,13 +33,16 @@ extern void Ext2_int_DereferenceInode(tExt2_Disk *Disk, Uint32 Inode);
 extern int     Ext2_int_ReadInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode);
 extern int     Ext2_int_WriteInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode);
 // --- Dir ---
-extern char    *Ext2_ReadDir(tVFS_Node *Node, int Pos);
+extern int     Ext2_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 extern tVFS_Node       *Ext2_FindDir(tVFS_Node *Node, const char *FileName);
-extern int     Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+extern tVFS_Node       *Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
 extern int     Ext2_Link(tVFS_Node *Parent, const char *Name, tVFS_Node *Node);
 // --- Read ---
 extern size_t  Ext2_Read(tVFS_Node *node, off_t offset, size_t length, void *buffer);
 // --- Write ---
 extern size_t  Ext2_Write(tVFS_Node *node, off_t offset, size_t length, const void *buffer);
+extern Uint32  Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 LastBlock);
+extern void    Ext2_int_DeallocateBlock(tExt2_Disk *Disk, Uint32 Block);
+extern int     Ext2_int_AppendBlock(tExt2_Disk *Disk, tExt2_Inode *Inode, Uint32 Block);
 
 #endif
index a3aa301..4f9210e 100644 (file)
@@ -157,6 +157,6 @@ struct ext2_dir_entry_s {
        Uint8   type;           //!< File Type (Duplicate of ext2_inode_s.i_mode)\r
        char    name[EXT2_NAME_LEN+1];          //!< File name\r
 };\r
-#define EXT2_DIRENT_SIZE       (sizeof(struct ext2_dir_entry_s)-EXT2_NAME_LEN+1)\r
+#define EXT2_DIRENT_SIZE       (sizeof(struct ext2_dir_entry_s)-(EXT2_NAME_LEN+1))\r
 \r
 #endif\r
index 22e256b..766a0e6 100644 (file)
@@ -98,7 +98,9 @@ addBlocks:
                block = Ext2_int_AllocateBlock(disk, base/disk->BlockSize);
                if(!block)      return Length - retLen;
                // Add it to this inode
-               if( !Ext2_int_AppendBlock(disk, &inode, block) ) {
+               if( Ext2_int_AppendBlock(disk, &inode, block) ) {
+                       Log_Warning("Ext2", "Appending %x to inode %p:%X failed",
+                               block, disk, Node->Inode);
                        Ext2_int_DeallocateBlock(disk, block);
                        goto ret;
                }
@@ -113,7 +115,9 @@ addBlocks:
        // Last block :D
        block = Ext2_int_AllocateBlock(disk, base/disk->BlockSize);
        if(!block)      goto ret;
-       if( !Ext2_int_AppendBlock(disk, &inode, block) ) {
+       if( Ext2_int_AppendBlock(disk, &inode, block) ) {
+               Log_Warning("Ext2", "Appending %x to inode %p:%X failed",
+                       block, disk, Node->Inode);
                Ext2_int_DeallocateBlock(disk, block);
                goto ret;
        }
@@ -141,80 +145,96 @@ ret:      // Makes sure the changes to the inode are committed
 Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock)
 {
         int    bpg = Disk->SuperBlock.s_blocks_per_group;
-       Uint    blockgroup = PrevBlock / bpg;
-       Uint    bitmap[Disk->BlockSize/sizeof(Uint)];
-       Uint    bitsperblock = 8*Disk->BlockSize;
-        int    i, j = 0;
-       Uint    block;
-       
+       Uint    firstgroup = PrevBlock / bpg;
+       Uint    blockgroup = firstgroup;
+       tExt2_Group     *bg;
+
+       // TODO: Need to do locking on the bitmaps      
+
        // Are there any free blocks?
-       if(Disk->SuperBlock.s_free_blocks_count == 0)   return 0;
-       
-       if(Disk->Groups[blockgroup].bg_free_blocks_count > 0)
+       if(Disk->SuperBlock.s_free_blocks_count == 0)
+               return 0;
+
+       // First: Check the next block after \a PrevBlock
+       if( (PrevBlock + 1) % Disk->SuperBlock.s_blocks_per_group != 0
+        && Disk->Groups[blockgroup].bg_free_blocks_count > 0 )
        {
-               // Search block group's bitmap
-               for(i = 0; i < bpg; i++)
+               bg = &Disk->Groups[blockgroup];
+               const int sector_size = 512;
+               Uint8 buf[sector_size];
+                int    iblock = (PrevBlock + 1) % Disk->SuperBlock.s_blocks_per_group;
+                int    byte = iblock / 8;
+                int    ofs = byte / sector_size * sector_size;
+               byte %= sector_size;
+               VFS_ReadAt(Disk->FD, Disk->BlockSize*bg->bg_block_bitmap+ofs, sector_size, buf);
+               
+               if( (buf[byte] & (1 << (iblock%8))) == 0 )
                {
-                       // Get the block in the bitmap block
-                       j = i & (bitsperblock-1);
-                       
-                       // Read in if needed
-                       if(j == 0) {
-                               VFS_ReadAt(
-                                       Disk->FD,
-                                       (Uint64)Disk->Groups[blockgroup].bg_block_bitmap + i / bitsperblock,
-                                       Disk->BlockSize,
-                                       bitmap
-                                       );
-                       }
-                       
-                       // Fast Check
-                       if( bitmap[j/32] == 0xFFFFFFFF ) {
-                               j = (j + 31) & ~31;
-                               continue;
-                       }
-                       
-                       // Is the bit set?
-                       if( bitmap[j/32] & (1 << (j%32)) )
-                               continue;
-                       
-                       // Ooh! We found one
-                       break;
-               }
-               if( i < bpg ) {
-                       Warning("[EXT2 ] Inconsistency detected, Group Free Block count is non-zero when no free blocks exist");
-                       goto    checkAll;       // Search the entire filesystem for a free block
-                       // Goto needed for neatness
+                       // Free block - nice and contig allocation
+                       buf[byte] |= (1 << (iblock%8));
+                       VFS_WriteAt(Disk->FD, Disk->BlockSize*bg->bg_block_bitmap+ofs, sector_size, buf);
+
+                       bg->bg_free_blocks_count --;
+                       Disk->SuperBlock.s_free_blocks_count --;
+                       #if EXT2_UPDATE_WRITEBACK
+                       Ext2_int_UpdateSuperblock(Disk);
+                       #endif
+                       return PrevBlock + 1;
                }
-               
-               // Mark as used
-               bitmap[j/32] |= (1 << (j%32));
-               VFS_WriteAt(
-                       Disk->FD,
-                       (Uint64)Disk->Groups[blockgroup].bg_block_bitmap + i / bitsperblock,
-                       Disk->BlockSize,
-                       bitmap
-                       );
-               block = i;
-               Disk->Groups[blockgroup].bg_free_blocks_count --;
-               #if EXT2_UPDATE_WRITEBACK
-               //Ext2_int_UpdateBlockGroup(Disk, blockgroup);
-               #endif
+               // Used... darnit
+               // Fall through and search further
        }
-       else
+
+       // Second: Search for a group with free blocks
+       while( blockgroup < Disk->GroupCount && Disk->Groups[blockgroup].bg_free_blocks_count == 0 )
+               blockgroup ++;
+       if( Disk->Groups[blockgroup].bg_free_blocks_count == 0 )
        {
-       checkAll:
-               Log_Warning("EXT2", "TODO - Implement using blocks outside the current block group");
+               blockgroup = 0;
+               while( blockgroup < firstgroup && Disk->Groups[blockgroup].bg_free_blocks_count == 0 )
+                       blockgroup ++;
+       }
+       if( Disk->Groups[blockgroup].bg_free_blocks_count == 0 ) {
+               Log_Notice("Ext2", "Ext2_int_AllocateBlock - Out of blockss on %p, but superblock says some free",
+                       Disk);
                return 0;
        }
+
+       // Search the bitmap for a free block
+       bg = &Disk->Groups[blockgroup]; 
+        int    ofs = 0;
+       do {
+               const int sector_size = 512;
+               Uint8 buf[sector_size];
+               VFS_ReadAt(Disk->FD, Disk->BlockSize*bg->bg_block_bitmap+ofs, sector_size, buf);
+
+               int byte, bit;
+               for( byte = 0; byte < sector_size && buf[byte] != 0xFF; byte ++ )
+                       ;
+               if( byte < sector_size )
+               {
+                       for( bit = 0; bit < 8 && buf[byte] & (1 << bit); bit ++)
+                               ;
+                       ASSERT(bit != 8);
+                       buf[byte] |= 1 << bit;
+                       VFS_WriteAt(Disk->FD, Disk->BlockSize*bg->bg_block_bitmap+ofs, sector_size, buf);
+
+                       bg->bg_free_blocks_count --;
+                       Disk->SuperBlock.s_free_blocks_count --;
+
+                       #if EXT2_UPDATE_WRITEBACK
+                       Ext2_int_UpdateSuperblock(Disk);
+                       #endif
+
+                       Uint32  ret = blockgroup * Disk->SuperBlock.s_blocks_per_group + byte * 8 + bit;
+                       Log_Debug("Ext2", "Ext2_int_AllocateBlock - Allocated 0x%x", ret);
+                       return ret;
+               }
+       } while(ofs < Disk->SuperBlock.s_blocks_per_group / 8);
        
-       // Reduce global count
-       Disk->SuperBlock.s_free_blocks_count --;
-       #if EXT2_UPDATE_WRITEBACK
-       Ext2_int_UpdateSuperblock(Disk);
-       #endif
-       
-       return block;
+       Log_Notice("Ext2", "Ext2_int_AllocateBlock - Out of block in group %p:%i but header reported free",
+               Disk, blockgroup);
+       return 0;
 }
 
 /**
@@ -222,6 +242,7 @@ Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock)
  */
 void Ext2_int_DeallocateBlock(tExt2_Disk *Disk, Uint32 Block)
 {
+       Log_Warning("Ext2", "TODO: Impliment Ext2_int_DeallocateBlock");
 }
 
 /**
@@ -253,6 +274,7 @@ int Ext2_int_AppendBlock(tExt2_Disk *Disk, tExt2_Inode *Inode, Uint32 Block)
                if( nBlocks == 0 ) {
                        Inode->i_block[12] = Ext2_int_AllocateBlock(Disk, Inode->i_block[0]);
                        if( !Inode->i_block[12] ) {
+                               Log_Warning("Ext2", "Allocating indirect block failed");
                                free(blocks);
                                return 1;
                        }
@@ -276,6 +298,7 @@ int Ext2_int_AppendBlock(tExt2_Disk *Disk, tExt2_Inode *Inode, Uint32 Block)
                if( nBlocks == 0 ) {
                        Inode->i_block[13] = Ext2_int_AllocateBlock(Disk, Inode->i_block[0]);
                        if( !Inode->i_block[13] ) {
+                               Log_Warning("Ext2", "Allocating double indirect block failed");
                                free(blocks);
                                return 1;
                        }
@@ -289,6 +312,7 @@ int Ext2_int_AppendBlock(tExt2_Disk *Disk, tExt2_Inode *Inode, Uint32 Block)
                        id1 = Ext2_int_AllocateBlock(Disk, Inode->i_block[0]);
                        if( !id1 ) {
                                free(blocks);
+                               Log_Warning("Ext2", "Allocating double indirect block (l2) failed");
                                return 1;
                        }
                        blocks[nBlocks/dwPerBlock] = id1;
@@ -316,6 +340,7 @@ int Ext2_int_AppendBlock(tExt2_Disk *Disk, tExt2_Inode *Inode, Uint32 Block)
                if( nBlocks == 0 ) {
                        Inode->i_block[14] = Ext2_int_AllocateBlock(Disk, Inode->i_block[0]);
                        if( !Inode->i_block[14] ) {
+                               Log_Warning("Ext2", "Allocating triple indirect block failed");
                                free(blocks);
                                return 1;
                        }
@@ -329,6 +354,7 @@ int Ext2_int_AppendBlock(tExt2_Disk *Disk, tExt2_Inode *Inode, Uint32 Block)
                {
                        id1 = Ext2_int_AllocateBlock(Disk, Inode->i_block[0]);
                        if( !id1 ) {
+                               Log_Warning("Ext2", "Allocating triple indirect block (l2) failed");
                                free(blocks);
                                return 1;
                        }
@@ -346,6 +372,7 @@ int Ext2_int_AppendBlock(tExt2_Disk *Disk, tExt2_Inode *Inode, Uint32 Block)
                if( nBlocks % dwPerBlock == 0 ) {
                        id2 = Ext2_int_AllocateBlock(Disk, id1);
                        if( !id2 ) {
+                               Log_Warning("Ext2", "Allocating triple indirect block (l3) failed");
                                free(blocks);
                                return 1;
                        }
@@ -366,7 +393,7 @@ int Ext2_int_AppendBlock(tExt2_Disk *Disk, tExt2_Inode *Inode, Uint32 Block)
                return 0;
        }
        
-       Warning("[EXT2 ] Inode %i cannot have a block appended to it, all indirects used");
+       Log_Warning("Ext2", "Inode ?? cannot have a block appended to it, all indirects used");
        free(blocks);
        return 1;
 }
index 79513a9..9402830 100644 (file)
@@ -46,7 +46,7 @@ struct sFAT_VolInfo
        Uint32  ClusterCount;   //!< Total Cluster Count
        fat_bootsect    bootsect;       //!< Boot Sector
        tVFS_Node       rootNode;       //!< Root Node
-        int    BytesPerCluster;
+       size_t  BytesPerCluster;
        
        tMutex  lNodeCache;
        tFAT_CachedNode *NodeCache;
@@ -106,13 +106,13 @@ extern void       FAT_int_ReadCluster(tFAT_VolInfo *Disk, Uint32 Cluster, int Length,
 extern void    FAT_int_WriteCluster(tFAT_VolInfo *Disk, Uint32 Cluster, const void *Buffer);
 
 // --- Directory Access ---
-extern char    *FAT_ReadDir(tVFS_Node *Node, int ID);
+extern int     FAT_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
 extern tVFS_Node       *FAT_FindDir(tVFS_Node *Node, const char *Name);
 extern tVFS_Node       *FAT_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode);
 extern int     FAT_int_GetEntryByCluster(tVFS_Node *DirNode, Uint32 Cluster, fat_filetable *Entry);
 #if SUPPORT_WRITE
 extern int     FAT_int_WriteDirEntry(tVFS_Node *Node, int ID, fat_filetable *Entry);
-extern int     FAT_Mknod(tVFS_Node *Node, const char *Name, Uint Flags);
+extern tVFS_Node       *FAT_Mknod(tVFS_Node *Node, const char *Name, Uint Flags);
 extern int     FAT_Link(tVFS_Node *DirNode, const char *NewName, tVFS_Node *Node);
 extern int     FAT_Unlink(tVFS_Node *DirNode, const char *OldName);
 #endif
index 8a690a1..b74b31f 100644 (file)
@@ -12,7 +12,7 @@
 
 // === PROTOTYPES ===
 void   FAT_int_ProperFilename(char *dest, const char *src);
-char   *FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName);
+ int   FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName, char *Dest);
  int   FAT_int_ConvertUTF16_to_UTF8(Uint8 *Dest, const Uint16 *Source);
  int   FAT_int_ConvertUTF8_to_UTF16(Uint16 *Dest, const Uint8 *Source);
 
@@ -26,11 +26,11 @@ char        *FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName);
 Uint16 *FAT_int_GetLFN(tVFS_Node *Node, int ID);
 void   FAT_int_DelLFN(tVFS_Node *Node, int ID);
 #endif
-char   *FAT_ReadDir(tVFS_Node *Node, int ID);
+ int   FAT_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
 tVFS_Node      *FAT_FindDir(tVFS_Node *Node, const char *Name);
 tVFS_Node      *FAT_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode);
 #if SUPPORT_WRITE
- int   FAT_Mknod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node      *FAT_Mknod(tVFS_Node *Node, const char *Name, Uint Flags);
  int   FAT_int_IsValid83Filename(const char *Name);
  int   FAT_Link(tVFS_Node *DirNode, const char *NewName, tVFS_Node *Node);
  int   FAT_Relink(tVFS_Node *node, const char *OldName, const char *NewName);
@@ -75,32 +75,26 @@ void FAT_int_ProperFilename(char *dest, const char *src)
  * \param LongFileName Long file name pointer
  * \return Filename as a heap string
  */
-char *FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName)
+int FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName, char *Dest)
 {
-       char    *ret;
        ENTER("pft sLongFileName", ft, LongFileName);
-       //Log_Debug("FAT", "FAT_int_CreateName(ft=%p, LongFileName=%p'%s')", ft, LongFileName);
        #if USE_LFN
        if(LongFileName && LongFileName[0] != 0)
        {
                 int    len = FAT_int_ConvertUTF16_to_UTF8(NULL, LongFileName);
-               ret = malloc( len + 1 );
-               FAT_int_ConvertUTF16_to_UTF8((Uint8*)ret, LongFileName);
+               if( len > FILENAME_MAX ) {
+                       return -1;
+               }
+               FAT_int_ConvertUTF16_to_UTF8((Uint8*)Dest, LongFileName);
        }
        else
        {
        #endif
-               ret = (char*) malloc(13);
-               if( !ret ) {
-                       Log_Warning("FAT", "FAT_int_CreateName: malloc(13) failed");
-                       return NULL;
-               }
-               FAT_int_ProperFilename(ret, ft->name);
+               FAT_int_ProperFilename(Dest, ft->name);
        #if USE_LFN
        }
        #endif
-       LEAVE('s', ret);
-       return ret;
+       return 0;
 }
 
 #if USE_LFN
@@ -537,11 +531,10 @@ void FAT_int_DelLFN(tVFS_Node *Node, int ID)
  * \param ID   Directory position
  * \return Filename as a heap string, NULL or VFS_SKIP
  */
-char *FAT_ReadDir(tVFS_Node *Node, int ID)
+int FAT_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
 {
        fat_filetable   fileinfo[16];   // sizeof(fat_filetable)=32, so 16 per sector
         int    a;
-       char    *ret;
        #if USE_LFN
        Uint16  *lfn = NULL;
        #endif
@@ -551,8 +544,8 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
        if(FAT_int_ReadDirSector(Node, ID/16, fileinfo))
        {
                LOG("End of chain, end of dir");
-               LEAVE('n');
-               return NULL;
+               LEAVE('i', -EIO);
+               return -EIO;
        }
        
        // Offset in sector
@@ -564,20 +557,14 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
        if( fileinfo[a].name[0] == '\0' ) {
                Node->Size = ID;
                LOG("End of list");
-               LEAVE('n');
-               return NULL;    // break
+               LEAVE('i', -ENOENT);
+               return -ENOENT; // break
        }
        
        // Check for empty entry
        if( (Uint8)fileinfo[a].name[0] == 0xE5 ) {
                LOG("Empty Entry");
-               #if 0   // Stop on empty entry?
-               LEAVE('n');
-               return NULL;    // Stop
-               #else
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;        // Skip
-               #endif
+               LEAVE_RET('i', 1);      // Skip
        }
        
        #if USE_LFN
@@ -595,31 +582,24 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
                a = FAT_int_ParseLFN(&fileinfo[a], lfn);
                if( a < 0 ) {
                        LOG("Invalid LFN, error");
-                       LEAVE('n');
-                       return NULL;
+                       LEAVE_RET('i', -EIO);
                }
 
-//             LOG("lfn = '%s'", lfn);
-               //Log_Debug("FAT", "lfn = '%s'", lfn);
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;
+               LEAVE_RET('i', 1);      // Skip
        }
        #endif
        
        // Check if it is a volume entry
        if(fileinfo[a].attrib & 0x08) {
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;
+               LEAVE_RET('i', 1);      // Skip
        }
        // Ignore .
        if(fileinfo[a].name[0] == '.' && fileinfo[a].name[1] == ' ') {
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;
+               LEAVE_RET('i', 1);      // Skip
        }
        // and ..
        if(fileinfo[a].name[0] == '.' && fileinfo[a].name[1] == '.' && fileinfo[a].name[2] == ' ') {
-               LEAVE('p', VFS_SKIP);
-               return VFS_SKIP;
+               LEAVE_RET('i', 1);      // Skip
        }
        
        LOG("name='%c%c%c%c%c%c%c%c.%c%c%c'",
@@ -630,13 +610,13 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
        #if USE_LFN
        lfn = FAT_int_GetLFN(Node, ID);
        //Log_Debug("FAT", "lfn = %p'%s'", lfn, lfn);
-       ret = FAT_int_CreateName(&fileinfo[a], lfn);
+       FAT_int_CreateName(&fileinfo[a], lfn, Dest);
        #else
-       ret = FAT_int_CreateName(&fileinfo[a], NULL);
+       FAT_int_CreateName(&fileinfo[a], NULL, Dest);
        #endif
        
-       LEAVE('s', ret);
-       return ret;
+       LEAVE('i', 0);
+       return 0;
 }
 
 /**
@@ -705,7 +685,7 @@ tVFS_Node *FAT_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode)
 /**
  * \brief Create a new node
  */
-int FAT_Mknod(tVFS_Node *DirNode, const char *Name, Uint Flags)
+tVFS_Node *FAT_Mknod(tVFS_Node *DirNode, const char *Name, Uint Flags)
 {
        tFAT_VolInfo    *disk = DirNode->ImplPtr;
         int    rv;
@@ -729,7 +709,8 @@ int FAT_Mknod(tVFS_Node *DirNode, const char *Name, Uint Flags)
        
        tVFS_Node *newnode = FAT_int_CreateNode(DirNode, &ft);
        if( !newnode ) {
-               return -1;
+               errno = -EINTERNAL;
+               return NULL;
        }
        LOG("newnode = %p", newnode);
 
@@ -737,9 +718,8 @@ int FAT_Mknod(tVFS_Node *DirNode, const char *Name, Uint Flags)
        if( (rv = FAT_Link(DirNode, Name, newnode)) ) {
                newnode->ImplInt |= FAT_FLAG_DELETE;
        }
-       FAT_CloseFile(newnode);
-       LEAVE('i', rv);
-       return rv;
+       LEAVE('p', newnode);
+       return newnode;
 }
 
 /**
index 92af114..1848613 100644 (file)
@@ -14,9 +14,9 @@ typedef struct sInitRD_File
 
 
 // === Functions ===
-extern size_t  InitRD_ReadFile(tVFS_Node *Node, off_t Offset, size_t Size, void *Buffer);
-extern char    *InitRD_ReadDir(tVFS_Node *Node, int ID);
-extern tVFS_Node       *InitRD_FindDir(tVFS_Node *Node, const char *Name);
+//extern size_t        InitRD_ReadFile(tVFS_Node *Node, off_t Offset, size_t Size, void *Buffer);
+//extern int   InitRD_ReadDir(tVFS_Node *Node, int ID);
+//extern tVFS_Node     *InitRD_FindDir(tVFS_Node *Node, const char *Name);
 
 // === Globals ===
 tVFS_NodeType  gInitRD_DirType;
index 863a24a..96f783e 100644 (file)
@@ -18,7 +18,7 @@ tVFS_Node     *InitRD_InitDevice(const char *Device, const char **Arguments);
 void   InitRD_Unmount(tVFS_Node *Node);
 tVFS_Node      *InitRD_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode);
 size_t InitRD_ReadFile(tVFS_Node *Node, off_t Offset, size_t Size, void *Buffer);
-char   *InitRD_ReadDir(tVFS_Node *Node, int ID);
+ int   InitRD_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
 tVFS_Node      *InitRD_FindDir(tVFS_Node *Node, const char *Name);
 void   InitRD_DumpDir(tVFS_Node *Node, int Indent);
 
@@ -92,14 +92,15 @@ size_t InitRD_ReadFile(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffe
 /**
  * \brief Read from a directory
  */
-char *InitRD_ReadDir(tVFS_Node *Node, int ID)
+int InitRD_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
 {
        tInitRD_File    *dir = Node->ImplPtr;
        
        if(ID >= Node->Size)
-               return NULL;
+               return -EINVAL;
        
-       return strdup(dir[ID].Name);
+       strncpy(Dest, dir[ID].Name, FILENAME_MAX);
+       return 0;
 }
 
 /**
index 598120d..312bee7 100644 (file)
@@ -150,4 +150,7 @@ typedef struct sNTFS_FILE_Attrib
        };
 } PACKED       tNTFS_FILE_Attrib;
 
+extern int     NTFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
+extern tVFS_Node       *NTFS_FindDir(tVFS_Node *Node, const char *Name);
+
 #endif
index 37661e8..11cd241 100644 (file)
@@ -10,7 +10,7 @@
 #include "index.h"
 
 // === PROTOTYPES ===
-char   *NTFS_ReadDir(tVFS_Node *Node, int Pos);
+ int   NTFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *NTFS_FindDir(tVFS_Node *Node, const char *Name);
 Uint64 NTFS_int_IndexLookup(Uint64 Inode, const char *IndexName, const char *Str);
 
@@ -18,9 +18,9 @@ Uint64        NTFS_int_IndexLookup(Uint64 Inode, const char *IndexName, const char *Str
 /**
  * \brief Get the name of an indexed directory entry
  */
-char *NTFS_ReadDir(tVFS_Node *Node, int Pos)
+int NTFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
-       return NULL;
+       return -ENOTIMPL;
 }
 
 /**
index 87f2a09..b9c4b8d 100644 (file)
 #include "common.h"
 #include <modules.h>
 
-// === IMPORTS ===
-extern char    *NTFS_ReadDir(tVFS_Node *Node, int Pos);
-extern tVFS_Node       *NTFS_FindDir(tVFS_Node *Node, const char *Name);
-
 // === PROTOTYPES ===
  int   NTFS_Install(char **Arguments);
 tVFS_Node      *NTFS_InitDevice(const char *Devices, const char **Options);
index defa50b..eeef8f6 100644 (file)
@@ -21,9 +21,9 @@
 tVFS_Node      *RAMFS_InitDevice(const char *Device, const char **Options);
 void   RAMFS_Unmount(tVFS_Node *Node);
 // --- Directories ---
-char   *RAMFS_ReadDir(tVFS_Node *Node, int Index);
+ int   RAMFS_ReadDir(tVFS_Node *Node, int Index, char Dest[256]);
 tVFS_Node      *RAMFS_FindDir(tVFS_Node *Node, const char *Name);
- int   RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node      *RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
  int   RAMFS_Link(tVFS_Node *DirNode, const char *Name, tVFS_Node *Node);
  int   RAMFS_Unlink(tVFS_Node *Node, const char *Name);
 // --- Files ---
@@ -136,18 +136,19 @@ void RAMFS_Unmount(tVFS_Node *Node)
 }
 
 // --- Directories ---
-char *RAMFS_ReadDir(tVFS_Node *Node, int Index)
+int RAMFS_ReadDir(tVFS_Node *Node, int Index, char Dest[FILENAME_MAX])
 {
        tRAMFS_Dir      *dir = Node->ImplPtr;
        for( tRAMFS_DirEnt *d = dir->FirstEnt; d; d = d->Next )
        {
                if( Index -- == 0 ) {
                        LOG("Return %s", d->Name);
-                       return strdup(d->Name);
+                       strncpy(Dest, d->Name, FILENAME_MAX);
+                       return 0;
                }
        }
-       LOG("Return NULL");
-       return NULL;
+       LOG("Return -ENOENT");
+       return -ENOENT;
 }
 
 tVFS_Node *RAMFS_FindDir(tVFS_Node *Node, const char *Name)
@@ -166,11 +167,11 @@ tVFS_Node *RAMFS_FindDir(tVFS_Node *Node, const char *Name)
        return NULL;
 }
 
-int RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
+tVFS_Node *RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
 {
        tRAMFS_Dir      *dir = Node->ImplPtr;
        if( RAMFS_FindDir(Node, Name) != NULL )
-               return -1;
+               return NULL;
        
        tRAMFS_DirEnt   *de = malloc( sizeof(tRAMFS_DirEnt) + strlen(Name) + 1 );
        de->Next = NULL;
@@ -200,7 +201,7 @@ int RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
                dir->FirstEnt = de;
        dir->LastEnt = de;
 
-       return 0;
+       return &de->Inode->Node;
 }
 
 int RAMFS_Link(tVFS_Node *DirNode, const char *Name, tVFS_Node *FileNode)
index 16e0f97..2a02fd2 100644 (file)
@@ -20,7 +20,7 @@
 void   *IPStack_Adapter_Add(const tIPStack_AdapterType *Type, void *Ptr, const void *HWAddr);
 void   IPStack_Adapter_Del(void *Handle);
 // --- VFS API ---
-char   *Adapter_ReadDir(tVFS_Node *Node, int Pos);
+ int   Adapter_ReadDir(tVFS_Node *Node, int Pos, char Name[FILENAME_MAX]);
 tVFS_Node      *Adapter_FindDir(tVFS_Node *Node, const char *Name);
  int   Adapter_DirIOCtl(tVFS_Node *Node, int Num, void *Data);
  int   Adapter_IOCtl(tVFS_Node *Node, int Num, void *Data);
@@ -130,13 +130,14 @@ void IPStack_Adapter_Del(void *Handle)
 }
 
 // --- VFS API ---
-char *Adapter_ReadDir(tVFS_Node *Node, int Pos)
+int Adapter_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
-       if( Pos < 0 )   return NULL;
+       if( Pos < 0 )   return -EINVAL;
 
        // Loopback
        if( Pos == 0 ) {
-               return strdup("lo");
+               strcpy(Dest, "lo");
+               return 0;
        }
        Pos --;
        
@@ -144,7 +145,8 @@ char *Adapter_ReadDir(tVFS_Node *Node, int Pos)
                tAdapter *a;  int i;\
                for(i=0,a=list; i < Pos && a; i ++, a = a->Next ); \
                if( a ) { \
-                       return Adapter_GetName(a);\
+                       strncpy(Dest, Adapter_GetName(a), FILENAME_MAX);\
+                       return 0;\
                } \
                Pos -= i; \
        } while(0);
@@ -152,7 +154,7 @@ char *Adapter_ReadDir(tVFS_Node *Node, int Pos)
        CHECK_LIST(gpIP_AdapterList, "eth");
        // TODO: Support other types of adapters (wifi, tap, ...)
 
-       return NULL;
+       return -EINVAL;
 }
 
 tVFS_Node *Adapter_FindDir(tVFS_Node *Node, const char *Name)
diff --git a/KernelLand/Modules/IPStack/init.h b/KernelLand/Modules/IPStack/init.h
new file mode 100644 (file)
index 0000000..1f14bf1
--- /dev/null
@@ -0,0 +1,12 @@
+
+#ifndef _IPSTACK__INIT_H_
+#define _IPSTACK__INIT_H_
+
+extern int     ARP_Initialise();
+extern void    UDP_Initialise();
+extern void    TCP_Initialise();
+extern int     IPv4_Initialise();
+extern int     IPv6_Initialise();
+
+#endif
+
index 9bd00d9..9ab4b9a 100644 (file)
@@ -8,6 +8,7 @@
 #include "link.h"
 #include <api_drv_common.h>
 #include "include/adapters.h"
+#include "interface.h"
 
 // === CONSTANTS ===
 //! Default timeout value, 5 seconds
@@ -20,18 +21,23 @@ extern tVFS_Node    gIP_RouteNode;
 extern tVFS_Node       gIP_AdaptersNode;
 
 // === PROTOTYPES ===
-char   *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos);
+ int   IPStack_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name);
  int   IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data);
 
  int   IPStack_AddFile(tSocketFile *File);
 tInterface     *IPStack_AddInterface(const char *Device, const char *Name);
 
-char   *IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos);
+ int   IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *IPStack_Iface_FindDir(tVFS_Node *Node, const char *Name);
  int   IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data);
 
 // === GLOBALS ===
+tVFS_NodeType  gIP_RootNodeType = {
+       .ReadDir = IPStack_Root_ReadDir,
+       .FindDir = IPStack_Root_FindDir,
+       .IOCtl = IPStack_Root_IOCtl
+};
 tVFS_NodeType  gIP_InterfaceNodeType = {
                .ReadDir = IPStack_Iface_ReadDir,
                .FindDir = IPStack_Iface_FindDir,
@@ -62,27 +68,26 @@ tSocketFile *gIP_FileTemplates;
 /**
  * \brief Read from the IP Stack's Device Directory
  */
-char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos)
+int IPStack_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tInterface      *iface;
-       char    *name;
        ENTER("pNode iPos", Node, Pos);
        
 
        // Routing Subdir
        if( Pos == 0 ) {
-               LEAVE('s', "routes");
-               return strdup("routes");
+               strcpy(Dest, "routes");
+               return 0;
        }
        // Adapters
        if( Pos == 1 ) {
-               LEAVE('s', "adapters");
-               return strdup("adapters");
+               strcpy(Dest, "adapters");
+               return 0;
        }
        // Pseudo Interfaces
        if( Pos == 2 ) {
-               LEAVE('s', "lo");
-               return strdup("lo");
+               strcpy(Dest, "lo");
+               return 0;
        }
        Pos -= 3;
        
@@ -91,38 +96,16 @@ char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos)
        
        // Did we run off the end?
        if(!iface) {
-               LEAVE('n');
-               return NULL;
-       }
-       
-       name = malloc(4);
-       if(!name) {
-               Log_Warning("IPStack", "IPStack_Root_ReadDir - malloc error");
-               LEAVE('n');
-               return NULL;
+               LEAVE('i', -EINTERNAL);
+               return -EINVAL;
        }
        
        // Create the name
        Pos = iface->Node.ImplInt;
-       if(Pos < 10) {
-               name[0] = '0' + Pos;
-               name[1] = '\0';
-       }
-       else if(Pos < 100) {
-               name[0] = '0' + Pos/10;
-               name[1] = '0' + Pos%10;
-               name[2] = '\0';
-       }
-       else {
-               name[0] = '0' + Pos/100;
-               name[1] = '0' + (Pos/10)%10;
-               name[2] = '0' + Pos%10;
-               name[3] = '\0';
-       }
+       snprintf(Dest, FILENAME_MAX, "%i", Pos);
        
-       LEAVE('s', name);
-       // Return the pre-generated name
-       return name;
+       LEAVE('i', 0);
+       return 0;
 }
 
 /**
@@ -296,16 +279,18 @@ int IPStack_AddFile(tSocketFile *File)
 /**
  * \brief Read from an interface's directory
  */
-char *IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos)
+int IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tSocketFile     *file = gIP_FileTemplates;
        while(Pos-- && file) {
                file = file->Next;
        }
        
-       if(!file)       return NULL;
+       if(!file)
+               return -EINVAL;
        
-       return strdup(file->Name);
+       strncpy(Dest, file->Name, FILENAME_MAX);
+       return 0;
 }
 
 /**
diff --git a/KernelLand/Modules/IPStack/interface.h b/KernelLand/Modules/IPStack/interface.h
new file mode 100644 (file)
index 0000000..60459a0
--- /dev/null
@@ -0,0 +1,10 @@
+
+#ifndef _IPSTACK__INTERFACE_H_
+#define _IPSTACK__INTERFACE_H_
+
+extern tInterface      gIP_LoopInterface;
+extern tVFS_NodeType   gIP_RootNodeType;
+extern tInterface      *IPStack_AddInterface(const char *Device, const char *Name);
+
+#endif
+
index 5763e2d..bc920f1 100644 (file)
@@ -9,19 +9,10 @@
 #include <modules.h>
 #include <fs_devfs.h>
 #include "include/adapters.h"
+#include "interface.h"
+#include "init.h"
 
 // === IMPORTS ===
-extern int     ARP_Initialise();
-extern void    UDP_Initialise();
-extern void    TCP_Initialise();
-extern int     IPv4_Initialise();
-extern int     IPv6_Initialise();
-
-extern char    *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos);
-extern tVFS_Node       *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name);
-extern int     IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data);
-extern tInterface      gIP_LoopInterface;
-extern tInterface      *IPStack_AddInterface(const char *Device, const char *Name);
 extern tRoute  *IPStack_AddRoute(const char *Interface, void *Network, int SubnetBits, void *NextHop, int Metric);
 
 // === PROTOTYPES ===
@@ -30,11 +21,6 @@ extern tRoute        *IPStack_AddRoute(const char *Interface, void *Network, int Subnet
 
 // === GLOBALS ===
 MODULE_DEFINE(0, VERSION, IPStack, IPStack_Install, NULL, NULL);
-tVFS_NodeType  gIP_RootNodeType = {
-       .ReadDir = IPStack_Root_ReadDir,
-       .FindDir = IPStack_Root_FindDir,
-       .IOCtl = IPStack_Root_IOCtl
-};
 tDevFS_Driver  gIP_DriverInfo = {
        NULL, "ip",
        {
index 3153ef2..d9efa99 100644 (file)
@@ -17,9 +17,9 @@ extern tVFS_Node      *IPStack_Root_FindDir(tVFS_Node *Node, const char *Filename);
 
 // === PROTOTYPES ===
 // - Routes directory
-char   *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos);
+ int   IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name);
- int   IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node      *IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
  int   IPStack_RouteDir_Unlink(tVFS_Node *Node, const char *OldName);
 tRoute *_Route_FindExactRoute(int Type, void *Network, int Subnet, int Metric);
  int   _Route_ParseRouteName(const char *Name, void *Addr, int *SubnetBits, int *Metric);
@@ -58,22 +58,20 @@ tVFS_Node   gIP_RouteNode = {
 /**
  * \brief ReadDir for the /Devices/ip/routes/ directory
  */
-char *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos)
+int IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tRoute  *rt;
        
        for(rt = gIP_Routes; rt && Pos --; rt = rt->Next);
-       if( !rt )       return NULL;
+       if( !rt )       return -EINVAL;
        
        {
                 int    addrlen = IPStack_GetAddressSize(rt->AddressType);
-                int    len = sprintf(NULL, "%i::%i:%i", rt->AddressType, rt->SubnetBits, rt->Metric) + addrlen*2;
-               char    buf[len+1];
                 int    ofs;
-               ofs = sprintf(buf, "%i:", rt->AddressType);
-               ofs += Hex(buf+ofs, addrlen, rt->Network);
-               sprintf(buf+ofs, ":%i:%i", rt->SubnetBits, rt->Metric);
-               return strdup(buf);
+               ofs = sprintf(Dest, "%i:", rt->AddressType);
+               ofs += Hex(Dest+ofs, addrlen, rt->Network);
+               sprintf(Dest+ofs, ":%i:%i", rt->SubnetBits, rt->Metric);
+               return 0;
        }
 }
 
@@ -169,13 +167,22 @@ tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name)
 /**
  * \brief Create a new route node
  */
-int IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
+tVFS_Node *IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
 {
-       if( Flags )     return -EINVAL; 
-       if( Threads_GetUID() != 0 )     return -EACCES;
+       if( Flags ) {
+               errno = EINVAL;
+               return NULL;
+       }
+       if( Threads_GetUID() != 0 ) {
+               errno = EACCES;
+               return NULL;
+       }
 
         int    type = _Route_ParseRouteName(Name, NULL, NULL, NULL);
-       if( type <= 0 ) return -EINVAL;
+       if( type <= 0 ) {
+               errno = EINVAL;
+               return NULL;
+       }
 
         int    size = IPStack_GetAddressSize(type);
        Uint8   addrdata[size]; 
@@ -184,12 +191,15 @@ int IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
        _Route_ParseRouteName(Name, addrdata, &subnet, &metric);
 
        // Check for duplicates
-       if( _Route_FindExactRoute(type, addrdata, subnet, metric) )
-               return -EEXIST;
+       if( _Route_FindExactRoute(type, addrdata, subnet, metric) ) {
+               errno = EEXIST;
+               return NULL;
+       }
 
-       IPStack_Route_Create(type, addrdata, subnet, metric);
+       tRoute *rt = IPStack_Route_Create(type, addrdata, subnet, metric);
+       rt->Node.ReferenceCount ++;
 
-       return 0;
+       return &rt->Node;
 }
 
 /**
index c8a5584..71dd4e5 100644 (file)
@@ -33,7 +33,7 @@ Uint16        TCP_GetUnusedPort();
  int   TCP_DeallocatePort(Uint16 Port);
 // --- Server
 tVFS_Node      *TCP_Server_Init(tInterface *Interface);
-char   *TCP_Server_ReadDir(tVFS_Node *Node, int Pos);
+ int   TCP_Server_ReadDir(tVFS_Node *Node, int Pos, char Name[FILENAME_MAX]);
 tVFS_Node      *TCP_Server_FindDir(tVFS_Node *Node, const char *Name);
  int   TCP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data);
 void   TCP_Server_Close(tVFS_Node *Node);
@@ -878,11 +878,10 @@ tVFS_Node *TCP_Server_Init(tInterface *Interface)
  * \param Node Server node
  * \param Pos  Position (ignored)
  */
-char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos)
+int TCP_Server_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
        tTCPListener    *srv = Node->ImplPtr;
        tTCPConnection  *conn;
-       char    *ret;
        
        ENTER("pNode iPos", Node, Pos);
 
@@ -911,11 +910,10 @@ char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos)
        LOG("srv->NewConnections = %p", srv->NewConnections);
        LOG("srv->ConnectionsTail = %p", srv->ConnectionsTail);
 
-       ret = malloc(9);
-       itoa(ret, conn->Node.ImplInt, 16, 8, '0');
-       Log_Log("TCP", "Thread %i got '%s'", Threads_GetTID(), ret);
-       LEAVE('s', ret);
-       return ret;
+       itoa(Dest, conn->Node.ImplInt, 16, 8, '0');
+       Log_Log("TCP", "Thread %i got connection '%s'", Threads_GetTID(), Dest);
+       LEAVE('i', 0);
+       return 0;
 }
 
 /**
index 56bf9b5..25185a2 100644 (file)
@@ -17,7 +17,7 @@
  int   Mouse_Install(char **Arguments);
  int   Mouse_Cleanup(void);
 // - "User" side
-char   *Mouse_Root_ReadDir(tVFS_Node *Node, int Pos);
+ int   Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name);
  int   Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data);
 size_t Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Data);
@@ -68,10 +68,12 @@ int Mouse_Cleanup(void)
 }
 
 // --- VFS Interface ---
-char *Mouse_Root_ReadDir(tVFS_Node *Node, int Pos)
+int Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
-       if( Pos != 0 )  return NULL;
-       return strdup("system");
+       if( Pos != 0 )
+               return -EINVAL;
+       strcpy(Dest, "system");
+       return 0;
 }
 
 tVFS_Node *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name)
index 1ca3a99..f5ace2b 100644 (file)
 // Needed out of io.c because it's the max for Read/WriteDMA
 #define        MAX_DMA_SECTORS (0x1000 / SECTOR_SIZE)
 
-// === STRUCTURES ===
-typedef struct
-{
-       Uint8   BootCode[0x1BE];
-       struct {
-               Uint8   Boot;
-               Uint8   Unused1;        // Also CHS Start
-               Uint16  StartHi;        // Also CHS Start
-               Uint8   SystemID;
-               Uint8   Unused2;        // Also CHS Length
-               Uint16  LengthHi;       // Also CHS Length
-               Uint32  LBAStart;
-               Uint32  LBALength;
-       } __attribute__ ((packed)) Parts[4];
-       Uint16  BootFlag;       // = 0xAA 55
-} __attribute__ ((packed))     tMBR;
-
-typedef struct
-{
-       Uint64  Start;
-       Uint64  Length;
-       char    Name[4];
-       tVFS_Node       Node;
-}      tATA_Partition;
-
-typedef struct
-{
-       Uint64  Sectors;
-}      tATA_Disk;
-
-// === GLOBALS ===
-extern tATA_Disk       gATA_Disks[];
-
 // === FUNCTIONS ===
-// --- Common ---
-extern void    ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length);
-
-// --- MBR Parsing ---
-extern void    ATA_ParseMBR(int Disk, tMBR *MBR);
-
 // --- IO Functions ---
 extern int     ATA_SetupIO(void);
 extern Uint64  ATA_GetDiskSize(int Disk);
index 0ed5e37..da0447a 100644 (file)
@@ -9,6 +9,8 @@
 #include <modules.h>   // Needed for error codes
 #include <drv_pci.h>
 #include "common.h"
+#include <events.h>
+#include <timers.h>
 
 // === MACROS ===
 #define IO_DELAY()     do{inb(0x80); inb(0x80); inb(0x80); inb(0x80);}while(0)
@@ -95,10 +97,11 @@ Uint8       *gATA_BusMasterBasePtr; //!< Paging Mapped MMIO (If needed)
  int   gATA_IRQPri = 14;
  int   gATA_IRQSec = 15;
 volatile int   gaATA_IRQs[2] = {0};
+tThread        *gATA_WaitingThreads[2];
 // - Locks to avoid tripping
 tMutex glaATA_ControllerLock[2];
 // - Buffers!
-Uint8  gATA_Buffers[2][(MAX_DMA_SECTORS+0xFFF)&~0xFFF] __attribute__ ((section(".padata")));
+void   *gATA_Buffers[2];
 // - PRDTs
 tPRDT_Ent      gATA_PRDTs[2] = {
        {0, 512, IDE_PRDT_LAST},
@@ -148,17 +151,27 @@ int ATA_SetupIO(void)
        IRQ_AddHandler( gATA_IRQPri, ATA_IRQHandlerPri, NULL );
        IRQ_AddHandler( gATA_IRQSec, ATA_IRQHandlerSec, NULL );
 
-       gATA_PRDTs[0].PBufAddr = MM_GetPhysAddr( &gATA_Buffers[0] );
-       gATA_PRDTs[1].PBufAddr = MM_GetPhysAddr( &gATA_Buffers[1] );
+       tPAddr  paddr;
+       gATA_Buffers[0] = (void*)MM_AllocDMA(1, 32, &paddr);
+       gATA_PRDTs[0].PBufAddr = paddr;
+       gATA_Buffers[1] = (void*)MM_AllocDMA(1, 32, &paddr);
+       gATA_PRDTs[1].PBufAddr = paddr;
 
        LOG("gATA_PRDTs = {PBufAddr: 0x%x, PBufAddr: 0x%x}", gATA_PRDTs[0].PBufAddr, gATA_PRDTs[1].PBufAddr);
 
+       // TODO: Ensure that this is within 32-bits
        gaATA_PRDT_PAddrs[0] = MM_GetPhysAddr( &gATA_PRDTs[0] );
-       LOG("gaATA_PRDT_PAddrs[0] = 0x%x", gaATA_PRDT_PAddrs[0]);
-       ATA_int_BusMasterWriteDWord(4, gaATA_PRDT_PAddrs[0]);
-       
        gaATA_PRDT_PAddrs[1] = MM_GetPhysAddr( &gATA_PRDTs[1] );
-       LOG("gaATA_PRDT_PAddrs[1] = 0x%x", gaATA_PRDT_PAddrs[1]);
+       LOG("gaATA_PRDT_PAddrs = {0x%P, 0x%P}", gaATA_PRDT_PAddrs[0], gaATA_PRDT_PAddrs[1]);
+       #if PHYS_BITS > 32
+       if( gaATA_PRDT_PAddrs[0] >> 32 || gaATA_PRDT_PAddrs[1] >> 32 ) {
+               Log_Error("ATA", "Physical addresses of PRDTs are not in 32-bits (%P and %P)",
+                       gaATA_PRDT_PAddrs[0], gaATA_PRDT_PAddrs[1]);
+               LEAVE('i', MODULE_ERR_MISC);
+               return MODULE_ERR_MISC;
+       }
+       #endif
+       ATA_int_BusMasterWriteDWord(4, gaATA_PRDT_PAddrs[0]);
        ATA_int_BusMasterWriteDWord(12, gaATA_PRDT_PAddrs[1]);
 
        // Enable controllers
@@ -275,22 +288,18 @@ Uint16 ATA_GetBasePort(int Disk)
        return 0;
 }
 
-/**
- * \fn int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
- * \return Boolean Failure
- */
-int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
+int ATA_DoDMA(Uint8 Disk, Uint64 Address, Uint Count, int bWrite, void *Buffer)
 {
         int    cont = (Disk>>1)&1;     // Controller ID
         int    disk = Disk & 1;
        Uint16  base;
-       Sint64  timeoutTime;
+        int    bUseBounceBuffer;
 
-       ENTER("iDisk XAddress iCount pBuffer", Disk, Address, Count, Buffer);
+       ENTER("iDisk XAddress iCount bbWrite pBuffer", Disk, Address, Count, bWrite, Buffer);
 
        // Check if the count is small enough
        if(Count > MAX_DMA_SECTORS) {
-               Log_Warning("ATA", "Passed too many sectors for a bulk DMA read (%i > %i)",
+               Log_Warning("ATA", "Passed too many sectors for a bulk DMA (%i > %i)",
                        Count, MAX_DMA_SECTORS);
                LEAVE('i');
                return 1;
@@ -306,6 +315,35 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
 
        // Set Size
        gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
+       
+       // Detemine if the transfer can be done directly
+       tPAddr  buf_ps = MM_GetPhysAddr(Buffer);
+       tPAddr  buf_pe = MM_GetPhysAddr((char*)Buffer + Count * SECTOR_SIZE - 1);
+       if( buf_pe == buf_ps + Count * SECTOR_SIZE - 1 ) {
+               // Contiguous, nice
+               #if PHYS_BITS > 32
+               if( buf_pe >> 32 ) {
+                       // Over 32-bits, need to copy anyway
+                       bUseBounceBuffer = 1;
+                       LOG("%P over 32-bit, using bounce buffer", buf_pe);
+               }
+               #endif
+       }
+       else {
+               // TODO: Handle splitting the read into two?
+               bUseBounceBuffer = 1;
+               LOG("%P + 0x%x != %P, using bounce buffer", buf_ps, Count * SECTOR_SIZE, buf_pe);
+       }
+
+       // Set up destination / source buffers
+       if( bUseBounceBuffer ) {
+               gATA_PRDTs[cont].PBufAddr = MM_GetPhysAddr(gATA_Buffers[cont]);
+               if( bWrite )
+                       memcpy(gATA_Buffers[cont], Buffer, Count * SECTOR_SIZE);
+       }
+       else {
+               gATA_PRDTs[cont].PBufAddr = MM_GetPhysAddr(Buffer);
+       }
 
        // Get Port Base
        base = ATA_GetBasePort(Disk);
@@ -313,6 +351,8 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
        // Reset IRQ Flag
        gaATA_IRQs[cont] = 0;
 
+       
+       // TODO: What the ____ does this do?
        #if 1
        if( cont == 0 ) {
                outb(IDE_PRI_CTRL, 4);
@@ -358,26 +398,29 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
        
        LOG("gATA_PRDTs[%i].Bytes = %i", cont, gATA_PRDTs[cont].Bytes);
        if( Address > 0x0FFFFFFF )
-               outb(base+0x07, HDD_DMA_R48);   // Read Command (LBA48)
+               outb(base+0x07, bWrite ? HDD_DMA_W48 : HDD_DMA_R48);    // Command (LBA48)
        else
-               outb(base+0x07, HDD_DMA_R28);   // Read Command (LBA28)
+               outb(base+0x07, bWrite ? HDD_DMA_W28 : HDD_DMA_R28);    // Command (LBA28)
 
+       // Intialise timeout timer
+       Threads_ClearEvent(THREAD_EVENT_SHORTWAIT|THREAD_EVENT_TIMER);
+       tTimer *timeout = Time_AllocateTimer(NULL, NULL);
+       Time_ScheduleTimer(timeout, ATA_TIMEOUT);
+       gATA_WaitingThreads[cont] = Proc_GetCurThread();
+       
        // Start transfer
-       ATA_int_BusMasterWriteByte( cont * 8, 9 );      // Read and start
+       ATA_int_BusMasterWriteByte( cont * 8, (bWrite ? 0 : 8) | 1 );   // Write(0)/Read(8) and start
 
        // Wait for transfer to complete
-       timeoutTime = now() + ATA_TIMEOUT;
-       while( gaATA_IRQs[cont] == 0 && now() < timeoutTime)
-       {
-               HALT();
-       }
-       
-       if( now() >= timeoutTime ) {
+       Uint32 ev = Threads_WaitEvents(THREAD_EVENT_SHORTWAIT|THREAD_EVENT_TIMER);
+       Time_FreeTimer(timeout);
+
+       if( ev & THREAD_EVENT_TIMER ) {
                Log_Notice("ATA", "Timeout of %i ms exceeded", ATA_TIMEOUT);
        }
 
        // Complete Transfer
-       ATA_int_BusMasterWriteByte( cont * 8, 8 );      // Read and stop
+       ATA_int_BusMasterWriteByte( cont * 8, (bWrite ? 0 : 8) );       // Write/Read and stop
 
        #if DEBUG
        {
@@ -394,10 +437,7 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
                if( ATA_int_BusMasterReadByte(cont * 8 + 2) & 0x4 ) {
                        Log_Error("ATA", "BM Status reports an interrupt, but none recieved");
                        ATA_int_BusMasterWriteByte(cont*8 + 2, 4);      // Clear interrupt
-                       memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE );
-                       Mutex_Release( &glaATA_ControllerLock[ cont ] );
-                       LEAVE('i', 0);
-                       return 0;
+                       goto _success;
                }
 
                #if 1
@@ -407,24 +447,35 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
                // Release controller lock
                Mutex_Release( &glaATA_ControllerLock[ cont ] );
                Log_Warning("ATA",
-                       "Read timeout on disk %i (Reading sector 0x%llx)",
-                       Disk, Address);
+                       "Timeout on disk %i (%s sector 0x%llx)",
+                       Disk, bWrite ? "Writing" : "Reading", Address);
                // Return error
                LEAVE('i', 1);
                return 1;
        }
-       else {
-               LOG("Transfer Completed & Acknowledged");
-               // Copy to destination buffer
+       
+       LOG("Transfer Completed & Acknowledged");
+_success:
+       // Copy to destination buffer (if bounce was used and it was a read)
+       if( bUseBounceBuffer && !bWrite )
                memcpy( Buffer, gATA_Buffers[cont], Count*SECTOR_SIZE );
-               // Release controller lock
-               Mutex_Release( &glaATA_ControllerLock[ cont ] );
+       // Release controller lock
+       Mutex_Release( &glaATA_ControllerLock[ cont ] );
 
-               LEAVE('i', 0);
-               return 0;
-       }
+       LEAVE('i', 0);
+       return 0;
+}
+
+/**
+ * \fn int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
+ * \return Boolean Failure
+ */
+int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
+{
+       return ATA_DoDMA(Disk, Address, Count, 0, Buffer);
 }
 
+
 /**
  * \fn int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
  * \brief Write up to \a MAX_DMA_SECTORS to a disk
@@ -436,77 +487,7 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
  */
 int ATA_WriteDMA(Uint8 Disk, Uint64 Address, Uint Count, const void *Buffer)
 {
-        int    cont = (Disk>>1)&1;     // Controller ID
-        int    disk = Disk & 1;
-       Uint16  base;
-       Sint64  timeoutTime;
-
-       // Check if the count is small enough
-       if(Count > MAX_DMA_SECTORS)     return 1;
-
-       // Get exclusive access to the disk controller
-       Mutex_Acquire( &glaATA_ControllerLock[ cont ] );
-
-       // Set Size
-       gATA_PRDTs[ cont ].Bytes = Count * SECTOR_SIZE;
-
-       // Get Port Base
-       base = ATA_GetBasePort(Disk);
-
-       // Reset IRQ Flag
-       gaATA_IRQs[cont] = 0;
-       
-       // Set up transfer
-       outb(base+0x01, 0x00);
-       if( Address > 0x0FFFFFFF )      // Use LBA48
-       {
-               outb(base+0x6, 0x40 | (disk << 4));
-               outb(base+0x2, 0 >> 8); // Upper Sector Count
-               outb(base+0x3, Address >> 24);  // Low 2 Addr
-               outb(base+0x3, Address >> 28);  // Mid 2 Addr
-               outb(base+0x3, Address >> 32);  // High 2 Addr
-       }
-       else
-       {
-               // Magic, Disk, High Address nibble
-               outb(base+0x06, 0xE0 | (disk << 4) | ((Address >> 24) & 0x0F));
-       }
-
-       outb(base+0x02, (Uint8) Count);         // Sector Count
-       outb(base+0x03, (Uint8) Address);               // Low Addr
-       outb(base+0x04, (Uint8) (Address >> 8));        // Middle Addr
-       outb(base+0x05, (Uint8) (Address >> 16));       // High Addr
-       if( Address > 0x0FFFFFFF )
-               outb(base+0x07, HDD_DMA_W48);   // Write Command (LBA48)
-       else
-               outb(base+0x07, HDD_DMA_W28);   // Write Command (LBA28)
-
-       // Copy to output buffer
-       memcpy( gATA_Buffers[cont], Buffer, Count*SECTOR_SIZE );
-
-       // Start transfer
-       ATA_int_BusMasterWriteByte( cont << 3, 1 );     // Write and start
-
-       // Wait for transfer to complete
-       timeoutTime = now() + ATA_TIMEOUT;
-       while( gaATA_IRQs[cont] == 0 && now() < timeoutTime)
-       {
-               HALT();
-       }
-
-       // Complete Transfer
-       ATA_int_BusMasterWriteByte( cont << 3, 0 );     // Write and stop
-
-       // If the IRQ is unset, return error
-       if( gaATA_IRQs[cont] == 0 ) {
-               // Release controller lock
-               Mutex_Release( &glaATA_ControllerLock[ cont ] );
-               return 1;       // Error
-       }
-       else {
-               Mutex_Release( &glaATA_ControllerLock[ cont ] );
-               return 0;
-       }
+       return ATA_DoDMA(Disk, Address, Count, 1, (void*)Buffer);
 }
 
 /**
@@ -519,10 +500,12 @@ void ATA_IRQHandlerPri(int UNUSED(IRQ), void *UNUSED(Ptr))
        // IRQ bit set for Primary Controller
        val = ATA_int_BusMasterReadByte( 0x2 );
        LOG("IRQ val = 0x%x", val);
-       if(val & 4) {
+       if(val & 4)
+       {
                LOG("IRQ hit (val = 0x%x)", val);
                ATA_int_BusMasterWriteByte( 0x2, 4 );
                gaATA_IRQs[0] = 1;
+               Threads_PostEvent(gATA_WaitingThreads[0], THREAD_EVENT_SHORTWAIT);
                return ;
        }
 }
@@ -540,6 +523,7 @@ void ATA_IRQHandlerSec(int UNUSED(IRQ), void *UNUSED(Ptr))
                LOG("IRQ hit (val = 0x%x)", val);
                ATA_int_BusMasterWriteByte( 0xA, 4 );
                gaATA_IRQs[1] = 1;
+               Threads_PostEvent(gATA_WaitingThreads[1], THREAD_EVENT_SHORTWAIT);
                return ;
        }
 }
index 94ee8a5..a131a44 100644 (file)
@@ -21,7 +21,6 @@
 void   ATA_SetupPartitions(void);
  int   ATA_ScanDisk(int Disk);
 void   ATA_ParseGPT(int Disk);
-void   ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length);
 Uint16 ATA_GetBasePort(int Disk);
 // Read/Write Interface/Quantiser
 int    ATA_ReadRaw(void *Ptr, Uint64 Address, size_t Count, void *Buffer);
index c33dcda..f6290d9 100644 (file)
@@ -21,7 +21,7 @@
  int   FDD_Install(char **Arguments);
  int   FDD_RegisterFS(void);
 // --- VFS
-char   *FDD_ReadDir(tVFS_Node *Node, int pos);
+ int   FDD_ReadDir(tVFS_Node *Node, int pos, char dest[FILENAME_MAX]);
 tVFS_Node      *FDD_FindDir(tVFS_Node *dirNode, const char *Name);
  int   FDD_IOCtl(tVFS_Node *Node, int ID, void *Data);
 size_t FDD_ReadFS(tVFS_Node *node, off_t Offset, size_t Len, void *buffer);
@@ -111,17 +111,16 @@ int FDD_RegisterFS(void)
  * \param Pos  Position
  * \return Heap string of node name
  */
-char *FDD_ReadDir(tVFS_Node *Node, int Pos)
+int FDD_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
-       char    ret_tpl[2];
        if(Pos < 0 || Pos > MAX_DISKS )
-               return NULL;
+               return -ENOENT;
        if(gaFDD_Disks[Pos].bValid)
-               return VFS_SKIP;
+               return 1;
        
-       ret_tpl[0] = '0' + Pos;
-       ret_tpl[1] = '\0';
-       return strdup(ret_tpl);
+       Dest[0] = '0' + Pos;
+       Dest[1] = '\0';
+       return 0;
 }
 
 /**
index d4e9aa4..8793d68 100644 (file)
@@ -17,9 +17,9 @@
  int   LVM_Initialise(char **Arguments);
  int   LVM_Cleanup(void);
 // ---
-char   *LVM_Root_ReadDir(tVFS_Node *Node, int ID);
+ int   LVM_Root_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
 tVFS_Node      *LVM_Root_FindDir(tVFS_Node *Node, const char *Name);
-char   *LVM_Vol_ReadDir(tVFS_Node *Node, int ID);
+ int   LVM_Vol_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
 tVFS_Node      *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name);
 size_t LVM_Vol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
 size_t LVM_Vol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);
@@ -124,18 +124,20 @@ int LVM_Cleanup(void)
 // --------------------------------------------------------------------
 // VFS Inteface
 // --------------------------------------------------------------------
-char *LVM_Root_ReadDir(tVFS_Node *Node, int ID)
+int LVM_Root_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
 {
        tLVM_Vol        *vol;
        
-       if( ID < 0 )    return NULL;    
+       if( ID < 0 )    return -EINVAL;
 
        for( vol = gpLVM_FirstVolume; vol && ID --; vol = vol->Next );
        
-       if(vol)
-               return strdup(vol->Name);
+       if(vol) {
+               strncpy(Dest, vol->Name, FILENAME_MAX);
+               return 0;
+       }
        else
-               return NULL;
+               return -ENOENT;
 }
 tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name)
 {
@@ -151,17 +153,22 @@ tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name)
        return NULL;
 }
 
-char *LVM_Vol_ReadDir(tVFS_Node *Node, int ID)
+int LVM_Vol_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
 {
        tLVM_Vol        *vol = Node->ImplPtr;
+       const char *src;
        
        if( ID < 0 || ID >= vol->nSubVolumes+1 )
-               return NULL;
+               return -EINVAL;
 
-       if( ID == 0 )
-               return strdup("ROOT");
-       else
-               return strdup( vol->SubVolumes[ID-1]->Name );
+       if( ID == 0 ) {
+               src = "ROOT";
+       }
+       else {
+               src = vol->SubVolumes[ID-1]->Name;
+       }
+       strncpy(Dest, src, FILENAME_MAX);
+       return 0;
 }
 tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name)
 {
index c137a8a..67fdbce 100644 (file)
@@ -76,7 +76,8 @@ int LVM_MBR_CountSubvolumes(tLVM_Vol *Volume, void *FirstSector)
        while(extendedLBA != 0)
        {
                extendedLBA = LVM_MBR_int_ReadExt(Volume, extendedLBA, &base, &len);
-               if( extendedLBA == -1 ) break;
+               if( extendedLBA == (Uint64)-1 )
+                       break;
                numPartitions ++;
        }
        LOG("numPartitions = %i", numPartitions);
@@ -127,7 +128,8 @@ void LVM_MBR_PopulateSubvolumes(tLVM_Vol *Volume, void *FirstSector)
        while(extendedLBA != 0)
        {
                extendedLBA = LVM_MBR_int_ReadExt(Volume, extendedLBA, &base, &len);
-               if(extendedLBA == -1)   break;
+               if(extendedLBA == (Uint64)-1)
+                       break;
                LVM_int_SetSubvolume_Anon( Volume, j, base, len );
                j ++ ;
        }
index 94ec253..cdbe2ee 100644 (file)
@@ -17,7 +17,7 @@ extern void   USB_AsyncThread(void *Unused);
 // === PROTOTYPES ===
  int   USB_Install(char **Arguments);
 void   USB_Cleanup(void);
-char   *USB_ReadDir(tVFS_Node *Node, int Pos);
+ int   USB_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
 tVFS_Node      *USB_FindDir(tVFS_Node *Node, const char *Name);
  int   USB_IOCtl(tVFS_Node *Node, int Id, void *Data);
 
@@ -60,9 +60,9 @@ void USB_Cleanup()
  * \fn char *USB_ReadDir(tVFS_Node *Node, int Pos)
  * \brief Read from the USB root
  */
-char *USB_ReadDir(tVFS_Node *Node, int Pos)
+int USB_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 {
-       return NULL;
+       return -ENOTIMPL;
 }
 
 /**
index 5ac59f4..1a54976 100644 (file)
--- a/TODO.txt
+++ b/TODO.txt
@@ -12,6 +12,9 @@ TODO:
 
 - UniChrome Driver
 
+- Sound Stack
+ > Intel 82801AA AC97 Audio (qemu)
+
 - Init Scripts
  > With an argument to init passed from the kernel?
 
@@ -32,13 +35,17 @@ TODO:
  > Allow hooks on PCI config accesses (to emulate power management etc)
 
 - VFS Path caching
+ > Is it needed?
  > Use a trie of path elements
+  - Trie on path content (with '/' included)
+  - Prefixed to reduce load
+  - Able to split
  > Maintain backwards cache of elements
  > Support symlink caching too
 
 - USB Stack
  > Check validity
- > Rework HC API to support structure used by OHCI/ECHI
+ > (DONE) Rework HC API to support structure used by OHCI/ECHI
 
 - LVM Usablity
  > /Devices/LVM/by-id/ and /Devices/LVM/by-label
@@ -52,6 +59,6 @@ TODO:
 - Omnispeak
  > Debug speed issues (tracing agian)
  > Port to AxWin3
- > Trace memory corruption
+ > (DONE) Trace memory corruption
 
 - Port dropbear!
index e63ae61..074aab9 100644 (file)
@@ -84,8 +84,6 @@ int DiskTool_MountImage(const char *Identifier, const char *Path)
        
        // Translate path       
        size_t tpath_len = DiskTool_int_TranslatePath(NULL, Path);
-       if(tpath_len == -1)
-               return -1;
        char tpath[tpath_len-1];
        DiskTool_int_TranslatePath(tpath, Path);
        
@@ -151,6 +149,29 @@ int DiskTool_ListDirectory(const char *Directory)
        return 0;
 }
 
+int DiskTool_Cat(const char *File)
+{
+       int src = DiskTool_int_TranslateOpen(File, VFS_OPENFLAG_READ);
+       if( src == -1 ) {
+               Log_Error("DiskTool", "Unable to open %s for reading", File);
+               return -1;
+       }
+       
+       char    buf[1024];
+       size_t  len, total = 0;
+       while( (len = VFS_Read(src, sizeof(buf), buf)) == sizeof(buf) ) {
+               _fwrite_stdout(len, buf);
+               total += len;
+       }
+       _fwrite_stdout(len, buf);
+       total += len;
+
+       Log_Notice("DiskTool", "%i bytes from %s", total, File);
+
+       VFS_Close(src);
+       return 0;
+}
+
 int DiskTool_LVM_Read(void *Handle, Uint64 Block, size_t BlockCount, void *Dest)
 {
        return VFS_ReadAt( (int)(tVAddr)Handle, Block*512, BlockCount*512, Dest) / 512;
@@ -168,7 +189,7 @@ void DiskTool_LVM_Cleanup(void *Handle)
 int DiskTool_int_TranslateOpen(const char *File, int Flags)
 {
        size_t tpath_len = DiskTool_int_TranslatePath(NULL, File);
-       if(tpath_len == -1)
+       if(tpath_len == 0)
                return -1;
        char tpath[tpath_len-1];
        DiskTool_int_TranslatePath(tpath, File);
index bd30b01..38703c2 100644 (file)
@@ -14,8 +14,11 @@ extern int   DiskTool_RegisterLVM(const char *Identifier, const char *Path);
 extern int     DiskTool_MountImage(const char *Identifier, const char *Path);
 extern int     DiskTool_Copy(const char *Source, const char *Destination);
 extern int     DiskTool_ListDirectory(const char *Directory);
+extern int     DiskTool_Cat(const char *File);
 
 extern size_t  DiskTool_int_TranslatePath(char *Buffer, const char *Path);
 
+extern size_t  _fwrite_stdout(size_t bytes, const void *data);
+
 #endif
 
index 0758fc2..2de26a6 100644 (file)
@@ -29,10 +29,10 @@ int main(int argc, char *argv[])
                        continue ;
                }
                
-               if( strcmp("mountlvm", argv[i]) == 0 ) {
+               if( strcmp("mountlvm", argv[i]) == 0 || strcmp("lvm", argv[i]) == 0 ) {
                        
                        if( argc - i < 3 ) {
-                               fprintf(stderr, "mountlvm takes 2 arguments (iamge and ident)\n");
+                               fprintf(stderr, "lvm takes 2 arguments (iamge and ident)\n");
                                exit(-1);
                        }
 
@@ -47,7 +47,7 @@ int main(int argc, char *argv[])
                
                if( strcmp("ls", argv[i]) == 0 ) {
                        if( argc - i < 2 ) {
-                               fprintf(stderr, "ls 1 argument (path)\n");
+                               fprintf(stderr, "ls takes 1 argument (path)\n");
                                break;
                        }
 
@@ -68,6 +68,19 @@ int main(int argc, char *argv[])
                        i += 2;
                        continue ;
                }
+
+               if( strcmp("cat", argv[i]) == 0 ) {
+
+                       if( argc - 1 < 2 ) {
+                               fprintf(stderr, "cat takes 1 argument (path)\n");
+                               break;
+                       }
+
+                       DiskTool_Cat(argv[i+1]);
+
+                       i += 1;
+                       continue;
+               }
        
                fprintf(stderr, "Unknown command '%s'\n", argv[i]);
        }
@@ -121,3 +134,7 @@ uint64_t DivMod64U(uint64_t value, uint64_t divisor, uint64_t *remainder)
        return value / divisor;
 }
 
+size_t _fwrite_stdout(size_t bytes, const void *data)
+{
+       return fwrite(data, bytes, 1, stdout);
+}
index 602aefd..a272214 100644 (file)
@@ -6,7 +6,7 @@
 #include <stdio.h>
 
 #define        MOUNTABLE_FILE  "/Acess/Conf/Mountable"
-#define        MOUNTED_FILE    "/Devices/System/VFS/Mounts"
+#define        MOUNTED_FILE    "/Devices/system/VFS/Mounts"
 
 // === PROTOTYPES ===
 void   ShowUsage(char *ProgName);
@@ -31,7 +31,7 @@ int main(int argc, char *argv[])
        // - This is cheating, isn't it?
        if(argc == 1) {
                // Dump the contents of /Devices/system/VFS/Mounts
-               FILE    *fp = fopen("/Devices/system/VFS/Mounts", "r");
+               FILE    *fp = fopen(MOUNTED_FILE, "r");
                char    buf[1024];
                 int    len;
                while( (len = fread(buf, 1024, 1, fp)) )
@@ -114,10 +114,10 @@ int main(int argc, char *argv[])
        else
        {
                // Check that we were passed a filesystem type
-               if(sType == NULL) {
-                       fprintf(stderr, "Please pass a filesystem type\n");
-                       return EXIT_FAILURE;
-               }
+//             if(sType == NULL) {
+//                     fprintf(stderr, "Please pass a filesystem type\n");
+//                     return EXIT_FAILURE;
+//             }
        }
        
        // Check Device
@@ -140,7 +140,10 @@ int main(int argc, char *argv[])
        if(sOptions == NULL)    sOptions = "";
 
        // Let's Mount!
-       _SysMount(sDevice, sDir, sType, sOptions);
+       if( _SysMount(sDevice, sDir, sType, sOptions) ) {
+               if( !sType )
+                       fprintf(stderr, "Filesystem autodetection failed, please pass a type\n");
+       }
 
        return 0;
 }

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