Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.4.19 /kernel/fork.c

Filename:/kernel/fork.c
Lines Added:29
Lines Deleted:8
Also changed in: (Previous) 2.4.19-rc5-ac1  2.4.19-rc5  2.4.19-rc4  2.4.19-rc3-ac5  2.4.19-rc3-ac4  2.4.19-rc3-ac3 
(Following) 2.4.19-ac1  2.4.19-ac2  2.4.19-ac3  2.4.19-ac4  2.4.20-pre1-ac1  2.4.20-pre2 

Location
[  2.4.19
  [  kernel
     o  fork.c

Patch

diff -urN linux-2.4.18/kernel/fork.c linux-2.4.19/kernel/fork.c
--- linux-2.4.18/kernel/fork.c   Mon Feb 25 11:38:13 2002
+++ linux-2.4.19/kernel/fork.c   Fri Aug  2 17:39:46 2002
@@ -19,7 +19,9 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/completion.h>
+#include <linux/namespace.h>
 #include <linux/personality.h>
+#include <linux/compiler.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -85,12 +87,13 @@
 {
    static int next_safe = PID_MAX;
    struct task_struct *p;
-   int pid;
+   int pid, beginpid;
 
    if (flags & CLONE_PID)
       return current->pid;
 
    spin_lock(&lastpid_lock);
+   beginpid = last_pid;
    if((++last_pid) & 0xffff8000) {
       last_pid = 300;      /* Skip daemons etc. */
       goto inside;
@@ -110,12 +113,16 @@
                   last_pid = 300;
                next_safe = PID_MAX;
             }
+            if(unlikely(last_pid == beginpid))
+               goto nomorepids;
             goto repeat;
          }
          if(p->pid > last_pid && next_safe > p->pid)
             next_safe = p->pid;
          if(p->pgrp > last_pid && next_safe > p->pgrp)
             next_safe = p->pgrp;
+         if(p->tgid > last_pid && next_safe > p->tgid)
+            next_safe = p->tgid;
          if(p->session > last_pid && next_safe > p->session)
             next_safe = p->session;
       }
@@ -125,6 +132,11 @@
    spin_unlock(&lastpid_lock);
 
    return pid;
+
+nomorepids:
+   read_unlock(&tasklist_lock);
+   spin_unlock(&lastpid_lock);
+   return 0;
 }
 
 static inline int dup_mmap(struct mm_struct * mm)
@@ -251,7 +263,7 @@
  */
 inline void __mmdrop(struct mm_struct *mm)
 {
-   if (mm == &init_mm) BUG();
+   BUG_ON(mm == &init_mm);
    pgd_free(mm->pgd);
    destroy_context(mm);
    free_mm(mm);
@@ -336,6 +348,9 @@
    if (!mm_init(mm))
       goto fail_nomem;
 
+   if (init_new_context(tsk,mm))
+      goto free_pt;
+
    down_write(&oldmm->mmap_sem);
    retval = dup_mmap(mm);
    up_write(&oldmm->mmap_sem);
@@ -348,9 +363,6 @@
     */
    copy_segments(tsk, mm);
 
-   if (init_new_context(tsk,mm))
-      goto free_pt;
-
 good_mm:
    tsk->mm = mm;
    tsk->active_mm = mm;
@@ -569,6 +581,9 @@
    struct task_struct *p;
    struct completion vfork;
 
+   if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
+      return -EINVAL;
+
    retval = -EPERM;
 
    /* 
@@ -620,6 +635,8 @@
 
    copy_flags(clone_flags, p);
    p->pid = get_pid(clone_flags);
+   if (p->pid == 0 && current->pid != 0)
+      goto bad_fork_cleanup;
 
    p->run_list.next = NULL;
    p->run_list.prev = NULL;
@@ -671,9 +688,11 @@
       goto bad_fork_cleanup_fs;
    if (copy_mm(clone_flags, p))
       goto bad_fork_cleanup_sighand;
+   if (copy_namespace(clone_flags, p))
+      goto bad_fork_cleanup_mm;
    retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
    if (retval)
-      goto bad_fork_cleanup_mm;
+      goto bad_fork_cleanup_namespace;
    p->semundo = NULL;
    
    /* Our parent execution domain becomes current domain
@@ -710,10 +729,10 @@
    /* Need tasklist lock for parent etc handling! */
    write_lock_irq(&tasklist_lock);
 
-   /* CLONE_PARENT and CLONE_THREAD re-use the old parent */
+   /* CLONE_PARENT re-uses the old parent */
    p->p_opptr = current->p_opptr;
    p->p_pptr = current->p_pptr;
-   if (!(clone_flags & (CLONE_PARENT | CLONE_THREAD))) {
+   if (!(clone_flags & CLONE_PARENT)) {
       p->p_opptr = current;
       if (!(p->ptrace & PT_PTRACED))
          p->p_pptr = current;
@@ -740,6 +759,8 @@
 fork_out:
    return retval;
 
+bad_fork_cleanup_namespace:
+   exit_namespace(p);
 bad_fork_cleanup_mm:
    exit_mm(p);
 bad_fork_cleanup_sighand:


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.