aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <akpm@linux-foundation.org>2007-06-03 13:50:41 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-06-04 13:25:10 -0700
commit78ae87c3cd723c8a8dcd67d4e4cbc6d63671c108 (patch)
treeba550d1d94a11b8f758f905e40c3d2aa7494007d
parent4c738480d21a190e3d99c7ce985ab9484f373a3c (diff)
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>
-rw-r--r--fs/ioctl.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 479c1038ed4..8c90cbc903f 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 @@ 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();
}