tty: Simplify tty_set_ldisc() exit handling
Perform common exit for both successful and error exit handling in tty_set_ldisc(). Fixes unlikely possibility of failing to restart input kworker when switching to the same line discipline (noop case). Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
5841fc4b13
commit
63d8cb3f19
1 changed files with 13 additions and 29 deletions
|
@ -529,34 +529,21 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
|
|||
|
||||
tty_lock(tty);
|
||||
retval = tty_ldisc_lock(tty, 5 * HZ);
|
||||
if (retval) {
|
||||
tty_ldisc_put(new_ldisc);
|
||||
tty_unlock(tty);
|
||||
return retval;
|
||||
}
|
||||
if (retval)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Check the no-op case
|
||||
*/
|
||||
/* Check the no-op case */
|
||||
if (tty->ldisc->ops->num == ldisc)
|
||||
goto out;
|
||||
|
||||
if (tty->ldisc->ops->num == ldisc) {
|
||||
tty_ldisc_unlock(tty);
|
||||
tty_ldisc_put(new_ldisc);
|
||||
tty_unlock(tty);
|
||||
return 0;
|
||||
if (test_bit(TTY_HUPPED, &tty->flags)) {
|
||||
/* We were raced by hangup */
|
||||
retval = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
old_ldisc = tty->ldisc;
|
||||
|
||||
if (test_bit(TTY_HUPPED, &tty->flags)) {
|
||||
/* We were raced by the hangup method. It will have stomped
|
||||
the ldisc data and closed the ldisc down */
|
||||
tty_ldisc_unlock(tty);
|
||||
tty_ldisc_put(new_ldisc);
|
||||
tty_unlock(tty);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Shutdown the old discipline. */
|
||||
tty_ldisc_close(tty, old_ldisc);
|
||||
|
||||
|
@ -582,18 +569,15 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
|
|||
the old ldisc (if it was restored as part of error cleanup
|
||||
above). In either case, releasing a single reference from
|
||||
the old ldisc is correct. */
|
||||
|
||||
tty_ldisc_put(old_ldisc);
|
||||
|
||||
/*
|
||||
* Allow ldisc referencing to occur again
|
||||
*/
|
||||
new_ldisc = old_ldisc;
|
||||
out:
|
||||
tty_ldisc_unlock(tty);
|
||||
|
||||
/* Restart the work queue in case no characters kick it off. Safe if
|
||||
already running */
|
||||
tty_buffer_restart_work(tty->port);
|
||||
|
||||
err:
|
||||
tty_ldisc_put(new_ldisc); /* drop the extra reference */
|
||||
tty_unlock(tty);
|
||||
return retval;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue