Commit 7f1707ca authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] TTY module refcounting fix

Patch from Max Krasnyansky <maxk@qualcomm.com>

This changeset adds module refcounting for TTY line disciplines.  I've sent
the patch to LKM earlier.  No negative comments (actually most people didn't
seem to care).  This is needed at least for Bluetooth and IrDA (Jean is ok
with the patch).
parent f5e31c2f
......@@ -286,6 +286,10 @@ static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
if (tty->ldisc.num == ldisc)
return 0; /* We are already in the desired discipline */
if (!try_module_get(ldiscs[ldisc].owner))
return -EINVAL;
o_ldisc = tty->ldisc;
tty_wait_until_sent(tty, 0);
......@@ -300,9 +304,13 @@ static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
if (tty->ldisc.open)
retval = (tty->ldisc.open)(tty);
if (retval < 0) {
module_put(tty->ldisc.owner);
tty->ldisc = o_ldisc;
tty->termios->c_line = tty->ldisc.num;
if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) {
module_put(tty->ldisc.owner);
tty->ldisc = ldiscs[N_TTY];
tty->termios->c_line = N_TTY;
if (tty->ldisc.open) {
......@@ -314,7 +322,10 @@ static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
tty_name(tty, buf), r);
}
}
} else {
module_put(o_ldisc.owner);
}
if (tty->ldisc.num != o_ldisc.num && tty->driver.set_ldisc)
tty->driver.set_ldisc(tty);
return retval;
......@@ -490,6 +501,8 @@ void do_tty_hangup(void *data)
if (tty->ldisc.num != ldiscs[N_TTY].num) {
if (tty->ldisc.close)
(tty->ldisc.close)(tty);
module_put(tty->ldisc.owner);
tty->ldisc = ldiscs[N_TTY];
tty->termios->c_line = N_TTY;
if (tty->ldisc.open) {
......@@ -1268,11 +1281,14 @@ static void release_dev(struct file * filp)
*/
if (tty->ldisc.close)
(tty->ldisc.close)(tty);
module_put(tty->ldisc.owner);
tty->ldisc = ldiscs[N_TTY];
tty->termios->c_line = N_TTY;
if (o_tty) {
if (o_tty->ldisc.close)
(o_tty->ldisc.close)(o_tty);
module_put(o_tty->ldisc.owner);
o_tty->ldisc = ldiscs[N_TTY];
}
......
......@@ -105,6 +105,7 @@ struct tty_ldisc {
char *name;
int num;
int flags;
/*
* The following routines are called from above.
*/
......@@ -129,6 +130,8 @@ struct tty_ldisc {
char *fp, int count);
int (*receive_room)(struct tty_struct *);
void (*write_wakeup)(struct tty_struct *);
struct module *owner;
};
#define TTY_LDISC_MAGIC 0x5403
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment