vanishing ioctl handler debugging

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>
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 479c103..8c90cbc 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -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 @@
 		unsigned long arg)
 {
 	int error = -ENOTTY;
+	void *f;
 
 	if (!filp->f_op)
 		goto out;
@@ -29,10 +31,16 @@
 		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();
 	}