diff options
author | Paul Fulghum <paulkf@microgate.com> | 2007-06-16 13:15:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-16 16:16:15 -0400 |
commit | 38ad2ed08d89a4b830a03131fa73e4ef3e98d9f4 (patch) | |
tree | 07b2cc23c70157c8ad65bb91db5f319bb0843947 /drivers/char | |
parent | f4d2781731e846c2f01dd85e71883d120860c6dd (diff) |
tty: restore locked ioctl file op
Restore tty locked ioctl handler which was replaced with
an unlocked ioctl handler in hung_up_tty_fops by the patch:
commit e10cc1df1d2014f68a4bdcf73f6dd122c4561f94
Author: Paul Fulghum <paulkf@microgate.com>
Date: Thu May 10 22:22:50 2007 -0700
tty: add compat_ioctl
This was reported in:
[Bug 8473] New: Oops: 0010 [1] SMP
The bug is caused by switching to hung_up_tty_fops in do_tty_hangup. An
ioctl call can be waiting on BLK after testing for existence of the locked
ioctl handler in the normal tty fops, but before calling the locked ioctl
handler. If a hangup occurs at that point, the locked ioctl fop is NULL
and an oops occurs.
(akpm: we can remove my debugging code from do_ioctl() now, but it'll be OK to
do that for 2.6.23)
Signed-off-by: Paul Fulghum <paulkf@microgate.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/tty_io.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 3752edc30c36..a96f26a63fa2 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -1173,8 +1173,14 @@ static unsigned int hung_up_tty_poll(struct file * filp, poll_table * wait) | |||
1173 | return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM; | 1173 | return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM; |
1174 | } | 1174 | } |
1175 | 1175 | ||
1176 | static long hung_up_tty_ioctl(struct file * file, | 1176 | static int hung_up_tty_ioctl(struct inode * inode, struct file * file, |
1177 | unsigned int cmd, unsigned long arg) | 1177 | unsigned int cmd, unsigned long arg) |
1178 | { | ||
1179 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; | ||
1180 | } | ||
1181 | |||
1182 | static long hung_up_tty_compat_ioctl(struct file * file, | ||
1183 | unsigned int cmd, unsigned long arg) | ||
1178 | { | 1184 | { |
1179 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; | 1185 | return cmd == TIOCSPGRP ? -ENOTTY : -EIO; |
1180 | } | 1186 | } |
@@ -1222,8 +1228,8 @@ static const struct file_operations hung_up_tty_fops = { | |||
1222 | .read = hung_up_tty_read, | 1228 | .read = hung_up_tty_read, |
1223 | .write = hung_up_tty_write, | 1229 | .write = hung_up_tty_write, |
1224 | .poll = hung_up_tty_poll, | 1230 | .poll = hung_up_tty_poll, |
1225 | .unlocked_ioctl = hung_up_tty_ioctl, | 1231 | .ioctl = hung_up_tty_ioctl, |
1226 | .compat_ioctl = hung_up_tty_ioctl, | 1232 | .compat_ioctl = hung_up_tty_compat_ioctl, |
1227 | .release = tty_release, | 1233 | .release = tty_release, |
1228 | }; | 1234 | }; |
1229 | 1235 | ||