From c34752b7ccc945a70a2d9b1e505aa4a4de43163b Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 16 May 2013 13:46:16 +0800 Subject: [PATCH] Kernel - Implimented VFS_Reopen --- KernelLand/Kernel/include/vfs_ext.h | 5 +++++ KernelLand/Kernel/include/vfs_int.h | 12 ++++++++++++ KernelLand/Kernel/syscalls.c | 5 +++++ KernelLand/Kernel/vfs/handle.c | 14 -------------- KernelLand/Kernel/vfs/open.c | 26 ++++++++++++++++++++++++++ 5 files changed, 48 insertions(+), 14 deletions(-) diff --git a/KernelLand/Kernel/include/vfs_ext.h b/KernelLand/Kernel/include/vfs_ext.h index a3a85642..d18009d4 100644 --- a/KernelLand/Kernel/include/vfs_ext.h +++ b/KernelLand/Kernel/include/vfs_ext.h @@ -222,6 +222,11 @@ extern int VFS_OpenChild(int FD, const char *Name, Uint Mode); */ extern int VFS_OpenInode(Uint32 Mount, Uint64 Inode, int Mode); +/** + * \brief Open a file reusing an old FD + */ +extern int VFS_Reopen(int FD, const char *Path, int Flags); + /** * \brief Close a currently open file * \param FD Handle returned by ::VFS_Open diff --git a/KernelLand/Kernel/include/vfs_int.h b/KernelLand/Kernel/include/vfs_int.h index 06ad8dab..c2dacd34 100644 --- a/KernelLand/Kernel/include/vfs_int.h +++ b/KernelLand/Kernel/include/vfs_int.h @@ -73,6 +73,18 @@ static inline void _CloseNode(tVFS_Node *Node) if(Node && Node->Type && Node->Type->Close) Node->Type->Close( Node ); } +static inline void _ReferenceNode(tVFS_Node *Node) +{ + if( !MM_GetPhysAddr(Node->Type) ) { + Log_Error("VFS", "Node %p's type is invalid (%p bad pointer) - %P corrupted", + Node, Node->Type, MM_GetPhysAddr(&Node->Type)); + return ; + } + if( Node->Type && Node->Type->Reference ) + Node->Type->Reference( Node ); + else + Node->ReferenceCount ++; +} #endif diff --git a/KernelLand/Kernel/syscalls.c b/KernelLand/Kernel/syscalls.c index 340a5ccc..34a35c5f 100644 --- a/KernelLand/Kernel/syscalls.c +++ b/KernelLand/Kernel/syscalls.c @@ -208,6 +208,11 @@ void SyscallHandler(tSyscallRegs *Regs) LOG("VFS_Open(\"%s\", 0x%x)", (char*)Regs->Arg1, Regs->Arg2 | VFS_OPENFLAG_USER); ret = VFS_Open((char*)Regs->Arg1, Regs->Arg2 | VFS_OPENFLAG_USER); break; + case SYS_REOPEN: + CHECK_STR_NONULL( (char*)Regs->Arg2 ); + LOG("VFS_Reopen(%i, \"%s\", 0x%x)", Regs->Arg1, (char*)Regs->Arg2, Regs->Arg3 | VFS_OPENFLAG_USER); + ret = VFS_Reopen(Regs->Arg1, (char*)Regs->Arg2, Regs->Arg3 | VFS_OPENFLAG_USER); + break; case SYS_CLOSE: LOG("VFS_Close(%i)", Regs->Arg1); diff --git a/KernelLand/Kernel/vfs/handle.c b/KernelLand/Kernel/vfs/handle.c index 35aa00c8..6173c29a 100644 --- a/KernelLand/Kernel/vfs/handle.c +++ b/KernelLand/Kernel/vfs/handle.c @@ -16,26 +16,12 @@ #define MAX_KERNEL_FILES 128 // === PROTOTYPES === -inline void _ReferenceNode(tVFS_Node *Node); // === GLOBALS === tVFS_Handle *gaUserHandles = (void*)MM_PPD_HANDLES; tVFS_Handle *gaKernelHandles = (void*)MM_KERNEL_VFS; // === CODE === -inline void _ReferenceNode(tVFS_Node *Node) -{ - if( !MM_GetPhysAddr(Node->Type) ) { - Log_Error("VFS", "Node %p's type is invalid (%p bad pointer) - %P corrupted", - Node, Node->Type, MM_GetPhysAddr(&Node->Type)); - return ; - } - if( Node->Type && Node->Type->Reference ) - Node->Type->Reference( Node ); - else - Node->ReferenceCount ++; -} - /** * \fn tVFS_Handle *VFS_GetHandle(int FD) * \brief Gets a pointer to the handle information structure diff --git a/KernelLand/Kernel/vfs/open.c b/KernelLand/Kernel/vfs/open.c index 2bfb2612..748d0f7e 100644 --- a/KernelLand/Kernel/vfs/open.c +++ b/KernelLand/Kernel/vfs/open.c @@ -722,6 +722,30 @@ int VFS_OpenInode(Uint32 Mount, Uint64 Inode, int Mode) LEAVE_RET('x', VFS_int_CreateHandle(node, mnt, Mode)); } +int VFS_Reopen(int FD, const char *Path, int Flags) +{ + tVFS_Handle *h = VFS_GetHandle(FD); + if(!h) { + errno = EBADF; + return -1; + } + + int newf = VFS_Open(Path, Flags); + if( newf == -1 ) { + return -1; + } + + _CloseNode(h->Node); + _DereferenceMount(h->Mount, "Reopen"); + memcpy(h, VFS_GetHandle(newf), sizeof(*h)); + _ReferenceNode(h->Node); + _ReferenceMount(h->Mount, "Reopen"); + + VFS_Close(newf); + + return FD; +} + /** * \fn void VFS_Close(int FD) * \brief Closes an open file handle @@ -774,6 +798,8 @@ int VFS_DuplicateFD(int SrcFD, int DstFD) return -1; VFS_SetHandle(DstFD, src->Node, src->Mode); } + _ReferenceMount(src->Mount, "DuplicateFD"); + _ReferenceNode(src->Node); memcpy(VFS_GetHandle(DstFD), src, sizeof(tVFS_Handle)); return DstFD; } -- 2.20.1