]> err.no Git - linux-2.6/blobdiff - fs/exec.c
[PATCH] update kfree, vfree, and vunmap kerneldoc
[linux-2.6] / fs / exec.c
index 48871917d3639c2b4d679ddd47d0db10651dc88c..14dd03907ccb58ed1b8c9cbdce76b6246d4ce727 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -642,6 +642,18 @@ static inline int de_thread(struct task_struct *tsk)
        count = 2;
        if (thread_group_leader(current))
                count = 1;
+       else {
+               /*
+                * The SIGALRM timer survives the exec, but needs to point
+                * at us as the new group leader now.  We have a race with
+                * a timer firing now getting the old leader, so we need to
+                * 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;
+               if (del_timer_sync(&sig->real_timer))
+                       add_timer(&sig->real_timer);
+       }
        while (atomic_read(&sig->count) > count) {
                sig->group_exit_task = current;
                sig->notify_count = count;
@@ -786,6 +798,7 @@ no_thread_group:
 static inline void flush_old_files(struct files_struct * files)
 {
        long j = -1;
+       struct fdtable *fdt;
 
        spin_lock(&files->file_lock);
        for (;;) {
@@ -793,12 +806,13 @@ static inline void flush_old_files(struct files_struct * files)
 
                j++;
                i = j * __NFDBITS;
-               if (i >= files->max_fds || i >= files->max_fdset)
+               fdt = files_fdtable(files);
+               if (i >= fdt->max_fds || i >= fdt->max_fdset)
                        break;
-               set = files->close_on_exec->fds_bits[j];
+               set = fdt->close_on_exec->fds_bits[j];
                if (!set)
                        continue;
-               files->close_on_exec->fds_bits[j] = 0;
+               fdt->close_on_exec->fds_bits[j] = 0;
                spin_unlock(&files->file_lock);
                for ( ; set ; i++,set >>= 1) {
                        if (set & 1) {