summaryrefslogtreecommitdiff
path: root/fs/exec.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2005-01-14 23:39:40 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-14 23:39:40 -0800
commit10059cbc3d6a4a3c8ea359608e11d14027f612ea (patch)
tree4f603526fd092ca7ae186c06a62cc05bbeba75cd /fs/exec.c
parent3c7223f1d709dfc9cf9afa281c3ecadb9b6a7df9 (diff)
[PATCH] clear false pending signal indication in core dump
When kill is used to force a core dump, __group_complete_signal uses the group_stop_count machinery to stop other threads from doing anything more before the signal-taking thread starts the coredump synchronization. This intentionally results in group_stop_count always still being > 0 when the signal-taking thread gets into do_coredump. However, that has the unintended effect that signal_pending can return true when called from the filesystem code while writing the core dump file. For NFS mounts using the "intr" option, this results in NFS operations bailing out before they even try, so core files never get successfully dumped on such a filesystem when the crash was induced by an asynchronous process-wide signal. This patch fixes the problem by clearing group_stop_count after the coredump synchronization is complete. The locking I threw in is not directly related, but always should have been there and may avoid some potential races with kill. Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 8459791d6bc1..115e6f15b30a 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1442,10 +1442,19 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
}
mm->dumpable = 0;
init_completion(&mm->core_done);
+ spin_lock_irq(&current->sighand->siglock);
current->signal->flags = SIGNAL_GROUP_EXIT;
current->signal->group_exit_code = exit_code;
+ spin_unlock_irq(&current->sighand->siglock);
coredump_wait(mm);
+ /*
+ * 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)
goto fail_unlock;