[PATCH] ipmi: use refcount in message handler
[safe/jmp/linux-2.6] / fs / exec.c
index fc02dad..cd6c574 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -48,6 +48,7 @@
 #include <linux/syscalls.h>
 #include <linux/rmap.h>
 #include <linux/acct.h>
+#include <linux/cn_proc.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -1096,6 +1097,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
                                        fput(bprm->file);
                                bprm->file = NULL;
                                current->did_exec = 1;
+                               proc_exec_connector(current);
                                return retval;
                        }
                        read_lock(&binfmt_lock);
@@ -1417,19 +1419,16 @@ static void zap_threads (struct mm_struct *mm)
 static void coredump_wait(struct mm_struct *mm)
 {
        DECLARE_COMPLETION(startup_done);
+       int core_waiters;
 
-       mm->core_waiters++; /* let other threads block */
        mm->core_startup_done = &startup_done;
 
-       /* give other threads a chance to run: */
-       yield();
-
        zap_threads(mm);
-       if (--mm->core_waiters) {
-               up_write(&mm->mmap_sem);
+       core_waiters = mm->core_waiters;
+       up_write(&mm->mmap_sem);
+
+       if (core_waiters)
                wait_for_completion(&startup_done);
-       } else
-               up_write(&mm->mmap_sem);
        BUG_ON(mm->core_waiters);
 }
 
@@ -1463,11 +1462,21 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
                current->fsuid = 0;     /* Dump root private */
        }
        mm->dumpable = 0;
-       init_completion(&mm->core_done);
+
+       retval = -EAGAIN;
        spin_lock_irq(&current->sighand->siglock);
-       current->signal->flags = SIGNAL_GROUP_EXIT;
-       current->signal->group_exit_code = exit_code;
+       if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
+               current->signal->flags = SIGNAL_GROUP_EXIT;
+               current->signal->group_exit_code = exit_code;
+               retval = 0;
+       }
        spin_unlock_irq(&current->sighand->siglock);
+       if (retval) {
+               up_write(&mm->mmap_sem);
+               goto fail;
+       }
+
+       init_completion(&mm->core_done);
        coredump_wait(mm);
 
        /*
@@ -1502,7 +1511,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) != 0)
+       if (do_truncate(file->f_dentry, 0, file) != 0)
                goto close_fail;
 
        retval = binfmt->core_dump(signr, regs, file);