]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/exec.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge
[linux-2.6-omap-h63xx.git] / fs / exec.c
index cd6c574557dc19a0b405d7fac06bc166db72a830..b5bcf1aae0abe61a6d7524b2614bcda7c78e18da 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -135,7 +135,7 @@ asmlinkage long sys_uselib(const char __user * library)
        if (!S_ISREG(nd.dentry->d_inode->i_mode))
                goto exit;
 
-       error = permission(nd.dentry->d_inode, MAY_READ | MAY_EXEC, &nd);
+       error = vfs_permission(&nd, MAY_READ | MAY_EXEC);
        if (error)
                goto exit;
 
@@ -306,9 +306,6 @@ void install_arg_page(struct vm_area_struct *vma,
                        struct page *page, unsigned long address)
 {
        struct mm_struct *mm = vma->vm_mm;
-       pgd_t * pgd;
-       pud_t * pud;
-       pmd_t * pmd;
        pte_t * pte;
        spinlock_t *ptl;
 
@@ -316,14 +313,7 @@ void install_arg_page(struct vm_area_struct *vma,
                goto out;
 
        flush_dcache_page(page);
-       pgd = pgd_offset(mm, address);
-       pud = pud_alloc(mm, pgd, address);
-       if (!pud)
-               goto out;
-       pmd = pmd_alloc(mm, pud, address);
-       if (!pmd)
-               goto out;
-       pte = pte_alloc_map_lock(mm, pmd, address, &ptl);
+       pte = get_locked_pte(mm, address, &ptl);
        if (!pte)
                goto out;
        if (!pte_none(*pte)) {
@@ -334,7 +324,7 @@ void install_arg_page(struct vm_area_struct *vma,
        lru_cache_add_active(page);
        set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
                                        page, vma->vm_page_prot))));
-       page_add_anon_rmap(page, vma, address);
+       page_add_new_anon_rmap(page, vma, address);
        pte_unmap_unlock(pte, ptl);
 
        /* no need for flush_tlb */
@@ -495,7 +485,7 @@ struct file *open_exec(const char *name)
                file = ERR_PTR(-EACCES);
                if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
                    S_ISREG(inode->i_mode)) {
-                       int err = permission(inode, MAY_EXEC, &nd);
+                       int err = vfs_permission(&nd, MAY_EXEC);
                        if (!err && !(inode->i_mode & 0111))
                                err = -EACCES;
                        file = ERR_PTR(err);
@@ -590,6 +580,7 @@ static inline int de_thread(struct task_struct *tsk)
        struct signal_struct *sig = tsk->signal;
        struct sighand_struct *newsighand, *oldsighand = tsk->sighand;
        spinlock_t *lock = &oldsighand->siglock;
+       struct task_struct *leader = NULL;
        int count;
 
        /*
@@ -641,10 +632,10 @@ static inline int de_thread(struct task_struct *tsk)
                 * synchronize with any firing (by calling del_timer_sync)
                 * before we can safely let the old group leader die.
                 */
-               sig->real_timer.data = (unsigned long)current;
+               sig->real_timer.data = current;
                spin_unlock_irq(lock);
-               if (del_timer_sync(&sig->real_timer))
-                       add_timer(&sig->real_timer);
+               if (hrtimer_cancel(&sig->real_timer))
+                       hrtimer_restart(&sig->real_timer);
                spin_lock_irq(lock);
        }
        while (atomic_read(&sig->count) > count) {
@@ -665,15 +656,16 @@ static inline int de_thread(struct task_struct *tsk)
         * and to assume its PID:
         */
        if (!thread_group_leader(current)) {
-               struct task_struct *leader = current->group_leader, *parent;
+               struct task_struct *parent;
                struct dentry *proc_dentry1, *proc_dentry2;
-               unsigned long exit_state, ptrace;
+               unsigned long ptrace;
 
                /*
                 * Wait for the thread group leader to be a zombie.
                 * It should already be zombie at this point, most
                 * of the time.
                 */
+               leader = current->group_leader;
                while (leader->exit_state != EXIT_ZOMBIE)
                        yield();
 
@@ -724,16 +716,15 @@ static inline int de_thread(struct task_struct *tsk)
                list_del(&current->tasks);
                list_add_tail(&current->tasks, &init_task.tasks);
                current->exit_signal = SIGCHLD;
-               exit_state = leader->exit_state;
+
+               BUG_ON(leader->exit_state != EXIT_ZOMBIE);
+               leader->exit_state = EXIT_DEAD;
 
                write_unlock_irq(&tasklist_lock);
                spin_unlock(&leader->proc_lock);
                spin_unlock(&current->proc_lock);
                proc_pid_flush(proc_dentry1);
                proc_pid_flush(proc_dentry2);
-
-               BUG_ON(exit_state != EXIT_ZOMBIE);
-               release_task(leader);
         }
 
        /*
@@ -743,8 +734,11 @@ static inline int de_thread(struct task_struct *tsk)
        sig->flags = 0;
 
 no_thread_group:
-       BUG_ON(atomic_read(&sig->count) != 1);
        exit_itimers(sig);
+       if (leader)
+               release_task(leader);
+
+       BUG_ON(atomic_read(&sig->count) != 1);
 
        if (atomic_read(&oldsighand->count) == 1) {
                /*
@@ -766,7 +760,7 @@ no_thread_group:
                spin_lock(&oldsighand->siglock);
                spin_lock(&newsighand->siglock);
 
-               current->sighand = newsighand;
+               rcu_assign_pointer(current->sighand, newsighand);
                recalc_sigpending();
 
                spin_unlock(&newsighand->siglock);
@@ -774,7 +768,7 @@ no_thread_group:
                write_unlock_irq(&tasklist_lock);
 
                if (atomic_dec_and_test(&oldsighand->count))
-                       kmem_cache_free(sighand_cachep, oldsighand);
+                       sighand_free(oldsighand);
        }
 
        BUG_ON(!thread_group_leader(current));
@@ -892,7 +886,7 @@ int flush_old_exec(struct linux_binprm * bprm)
        flush_thread();
 
        if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 
-           permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) ||
+           file_permission(bprm->file, MAY_READ) ||
            (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
                suid_keys(current);
                current->mm->dumpable = suid_dumpable;
@@ -1468,6 +1462,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
        if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
                current->signal->flags = SIGNAL_GROUP_EXIT;
                current->signal->group_exit_code = exit_code;
+               current->signal->group_stop_count = 0;
                retval = 0;
        }
        spin_unlock_irq(&current->sighand->siglock);
@@ -1483,7 +1478,6 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
         * Clear any false indication of pending signals that might
         * be seen by the filesystem code called to write the core file.
         */
-       current->signal->group_stop_count = 0;
        clear_thread_flag(TIF_SIGPENDING);
 
        if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
@@ -1511,7 +1505,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
                goto close_fail;
        if (!file->f_op->write)
                goto close_fail;
-       if (do_truncate(file->f_dentry, 0, file) != 0)
+       if (do_truncate(file->f_dentry, 0, 0, file) != 0)
                goto close_fail;
 
        retval = binfmt->core_dump(signr, regs, file);