[PATCH] don't do exit_io_context() until we know we won't be doing any IO
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 28 Feb 2006 17:51:55 +0000 (12:51 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 18 Mar 2006 23:33:46 +0000 (18:33 -0500)
testcase:

mount /dev/sdb10 /mnt
touch /mnt/tmp/b
umount /mnt
mount /dev/sdb10 /mnt
rm /mnt/tmp/b </mnt/tmp/b
umount /mnt

and watch blkdev_ioc line in /proc/slabinfo.  Vanilla kernel leaks.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
kernel/exit.c

index 531aadc..d1e8d50 100644 (file)
@@ -807,8 +807,6 @@ fastcall NORET_TYPE void do_exit(long code)
                panic("Attempted to kill the idle task!");
        if (unlikely(tsk->pid == 1))
                panic("Attempted to kill init!");
-       if (tsk->io_context)
-               exit_io_context();
 
        if (unlikely(current->ptrace & PT_TRACE_EXIT)) {
                current->ptrace_message = code;
@@ -822,6 +820,8 @@ fastcall NORET_TYPE void do_exit(long code)
        if (unlikely(tsk->flags & PF_EXITING)) {
                printk(KERN_ALERT
                        "Fixing recursive fault but reboot is needed!\n");
+               if (tsk->io_context)
+                       exit_io_context();
                set_current_state(TASK_UNINTERRUPTIBLE);
                schedule();
        }
@@ -881,6 +881,9 @@ fastcall NORET_TYPE void do_exit(long code)
         */
        mutex_debug_check_no_locks_held(tsk);
 
+       if (tsk->io_context)
+               exit_io_context();
+
        /* PF_DEAD causes final put_task_struct after we schedule. */
        preempt_disable();
        BUG_ON(tsk->flags & PF_DEAD);