]> err.no Git - linux-2.6/commitdiff
vanishing ioctl handler debugging
authorAndrew Morton <akpm@linux-foundation.org>
Sun, 3 Jun 2007 20:50:41 +0000 (13:50 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 4 Jun 2007 20:25:10 +0000 (13:25 -0700)
We've had several reoprts of the CPU jumping to 0x00000000 is do_ioctl().  I
assume that there's a race and someone is zeroing out the ioctl handler while
this CPU waits for the lock_kernel().

The patch adds code to detect this, then emits stuff which will hopefuly lead
us to the culprit.

Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/ioctl.c

index 479c1038ed4a4f7d3354e5939f6eae6a910e1d4f..8c90cbc903fa812e562984dab11ccc4e9212f2d2 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/fs.h>
 #include <linux/security.h>
 #include <linux/module.h>
+#include <linux/kallsyms.h>
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
@@ -20,6 +21,7 @@ static long do_ioctl(struct file *filp, unsigned int cmd,
                unsigned long arg)
 {
        int error = -ENOTTY;
+       void *f;
 
        if (!filp->f_op)
                goto out;
@@ -29,10 +31,16 @@ static long do_ioctl(struct file *filp, unsigned int cmd,
                if (error == -ENOIOCTLCMD)
                        error = -EINVAL;
                goto out;
-       } else if (filp->f_op->ioctl) {
+       } else if ((f = filp->f_op->ioctl)) {
                lock_kernel();
-               error = filp->f_op->ioctl(filp->f_path.dentry->d_inode,
-                                         filp, cmd, arg);
+               if (!filp->f_op->ioctl) {
+                       printk("%s: ioctl %p disappeared\n", __FUNCTION__, f);
+                       print_symbol("symbol: %s\n", (unsigned long)f);
+                       dump_stack();
+               } else {
+                       error = filp->f_op->ioctl(filp->f_path.dentry->d_inode,
+                                                 filp, cmd, arg);
+               }
                unlock_kernel();
        }