Fix file system racing and ext2 directory insertion (#58)
[lunaix-os.git] / lunaix-os / kernel / process / fork.c
index 6dbe737206c8e2d4f8a698795bfd9430625c7ad3..d68a8f830d3768553d66f97ef2599dabfcdf255b 100644 (file)
@@ -8,9 +8,10 @@
 #include <lunaix/syscall.h>
 #include <lunaix/syslog.h>
 #include <lunaix/signal.h>
 #include <lunaix/syscall.h>
 #include <lunaix/syslog.h>
 #include <lunaix/signal.h>
+#include <lunaix/kpreempt.h>
 
 
-#include <sys/abi.h>
-#include <sys/mm/mm_defs.h>
+#include <asm/abi.h>
+#include <asm/mm_defs.h>
 
 #include <klibc/string.h>
 
 
 #include <klibc/string.h>
 
@@ -44,30 +45,18 @@ region_maybe_cow(struct mm_region* region)
     tlb_flush_vmr_all(region);
 }
 
     tlb_flush_vmr_all(region);
 }
 
-static inline void
-__dup_fdtable(struct proc_info* pcb)
-{
-    for (size_t i = 0; i < VFS_MAX_FD; i++) {
-        struct v_fd* fd = __current->fdtable->fds[i];
-        if (!fd)
-            continue;
-        vfs_dup_fd(fd, &pcb->fdtable->fds[i]);
-    }
-}
-
-
 static void
 __dup_kernel_stack(struct thread* thread, ptr_t vm_mnt)
 {
     struct leaflet* leaflet;
 
     ptr_t kstack_pn = pfn(current_thread->kstack);
 static void
 __dup_kernel_stack(struct thread* thread, ptr_t vm_mnt)
 {
     struct leaflet* leaflet;
 
     ptr_t kstack_pn = pfn(current_thread->kstack);
-    kstack_pn -= pfn(KSTACK_SIZE) - 1;
+    kstack_pn -= pfn(KSTACK_SIZE);
 
     // copy the kernel stack
     pte_t* src_ptep = mkptep_pn(VMS_SELF, kstack_pn);
     pte_t* dest_ptep = mkptep_pn(vm_mnt, kstack_pn);
 
     // copy the kernel stack
     pte_t* src_ptep = mkptep_pn(VMS_SELF, kstack_pn);
     pte_t* dest_ptep = mkptep_pn(vm_mnt, kstack_pn);
-    for (size_t i = 0; i < pfn(KSTACK_SIZE); i++) {
+    for (size_t i = 0; i <= pfn(KSTACK_SIZE); i++) {
         pte_t p = *src_ptep;
 
         if (pte_isguardian(p)) {
         pte_t p = *src_ptep;
 
         if (pte_isguardian(p)) {
@@ -149,9 +138,8 @@ done:
 pid_t
 dup_proc()
 {
 pid_t
 dup_proc()
 {
-    // FIXME need investigate: issue with fork, as well as pthread
-    //       especially when involving frequent alloc and dealloc ops
-    //       (could be issue in allocator's segregated free list)
+    no_preemption();
+    
     struct proc_info* pcb = alloc_process();
     if (!pcb) {
         syscall_result(ENOMEM);
     struct proc_info* pcb = alloc_process();
     if (!pcb) {
         syscall_result(ENOMEM);
@@ -172,7 +160,8 @@ dup_proc()
         vfs_ref_dnode(pcb->cwd);
     }
 
         vfs_ref_dnode(pcb->cwd);
     }
 
-    __dup_fdtable(pcb);
+    fdtable_copy(pcb->fdtable, __current->fdtable);
+    uscope_copy(&pcb->uscope, current_user_scope());
 
     struct proc_mm* mm = vmspace(pcb);
     procvm_dupvms_mount(mm);
 
     struct proc_mm* mm = vmspace(pcb);
     procvm_dupvms_mount(mm);