]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/fork.c
hugetlbfs: architecture header cleanup
[linux-2.6-omap-h63xx.git] / kernel / fork.c
index 89fe414645e9b76aa777a0de7b5e9d6777814a0f..6067e429f2816ecd71990c4991354933d129502f 100644 (file)
@@ -279,7 +279,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
                if (!tmp)
                        goto fail_nomem;
                *tmp = *mpnt;
-               pol = mpol_copy(vma_policy(mpnt));
+               pol = mpol_dup(vma_policy(mpnt));
                retval = PTR_ERR(pol);
                if (IS_ERR(pol))
                        goto fail_nomem_policy;
@@ -521,7 +521,7 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
  * Allocate a new mm structure and copy contents from the
  * mm structure of the passed in task structure.
  */
-static struct mm_struct *dup_mm(struct task_struct *tsk)
+struct mm_struct *dup_mm(struct task_struct *tsk)
 {
        struct mm_struct *mm, *oldmm = current->mm;
        int err;
@@ -805,12 +805,6 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
                goto out;
        }
 
-       /*
-        * Note: we may be using current for both targets (See exec.c)
-        * This works because we cache current->files (old) as oldf. Don't
-        * break this.
-        */
-       tsk->files = NULL;
        newf = dup_fd(oldf, &error);
        if (!newf)
                goto out;
@@ -846,34 +840,6 @@ static int copy_io(unsigned long clone_flags, struct task_struct *tsk)
        return 0;
 }
 
-/*
- *     Helper to unshare the files of the current task.
- *     We don't want to expose copy_files internals to
- *     the exec layer of the kernel.
- */
-
-int unshare_files(void)
-{
-       struct files_struct *files  = current->files;
-       int rc;
-
-       BUG_ON(!files);
-
-       /* This can race but the race causes us to copy when we don't
-          need to and drop the copy */
-       if(atomic_read(&files->count) == 1)
-       {
-               atomic_inc(&files->count);
-               return 0;
-       }
-       rc = copy_files(0, current);
-       if(rc)
-               current->files = files;
-       return rc;
-}
-
-EXPORT_SYMBOL(unshare_files);
-
 static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
 {
        struct sighand_struct *sig;
@@ -1150,7 +1116,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        p->audit_context = NULL;
        cgroup_fork(p);
 #ifdef CONFIG_NUMA
-       p->mempolicy = mpol_copy(p->mempolicy);
+       p->mempolicy = mpol_dup(p->mempolicy);
        if (IS_ERR(p->mempolicy)) {
                retval = PTR_ERR(p->mempolicy);
                p->mempolicy = NULL;
@@ -1408,7 +1374,7 @@ bad_fork_cleanup_security:
        security_task_free(p);
 bad_fork_cleanup_policy:
 #ifdef CONFIG_NUMA
-       mpol_free(p->mempolicy);
+       mpol_put(p->mempolicy);
 bad_fork_cleanup_cgroup:
 #endif
        cgroup_exit(p, cgroup_callbacks_done);
@@ -1811,3 +1777,27 @@ bad_unshare_cleanup_thread:
 bad_unshare_out:
        return err;
 }
+
+/*
+ *     Helper to unshare the files of the current task.
+ *     We don't want to expose copy_files internals to
+ *     the exec layer of the kernel.
+ */
+
+int unshare_files(struct files_struct **displaced)
+{
+       struct task_struct *task = current;
+       struct files_struct *copy = NULL;
+       int error;
+
+       error = unshare_fd(CLONE_FILES, &copy);
+       if (error || !copy) {
+               *displaced = NULL;
+               return error;
+       }
+       *displaced = task->files;
+       task_lock(task);
+       task->files = copy;
+       task_unlock(task);
+       return 0;
+}