Commit 63d8cb3f authored by Peter Hurley's avatar Peter Hurley Committed by Greg Kroah-Hartman

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: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5841fc4b
...@@ -529,34 +529,21 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) ...@@ -529,34 +529,21 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
tty_lock(tty); tty_lock(tty);
retval = tty_ldisc_lock(tty, 5 * HZ); retval = tty_ldisc_lock(tty, 5 * HZ);
if (retval) { if (retval)
tty_ldisc_put(new_ldisc); goto err;
tty_unlock(tty);
return retval;
}
/* /* Check the no-op case */
* Check the no-op case if (tty->ldisc->ops->num == ldisc)
*/ goto out;
if (tty->ldisc->ops->num == ldisc) { if (test_bit(TTY_HUPPED, &tty->flags)) {
tty_ldisc_unlock(tty); /* We were raced by hangup */
tty_ldisc_put(new_ldisc); retval = -EIO;
tty_unlock(tty); goto out;
return 0;
} }
old_ldisc = tty->ldisc; 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. */ /* Shutdown the old discipline. */
tty_ldisc_close(tty, old_ldisc); tty_ldisc_close(tty, old_ldisc);
...@@ -582,18 +569,15 @@ int tty_set_ldisc(struct tty_struct *tty, int 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 the old ldisc (if it was restored as part of error cleanup
above). In either case, releasing a single reference from above). In either case, releasing a single reference from
the old ldisc is correct. */ the old ldisc is correct. */
new_ldisc = old_ldisc;
tty_ldisc_put(old_ldisc); out:
/*
* Allow ldisc referencing to occur again
*/
tty_ldisc_unlock(tty); tty_ldisc_unlock(tty);
/* Restart the work queue in case no characters kick it off. Safe if /* Restart the work queue in case no characters kick it off. Safe if
already running */ already running */
tty_buffer_restart_work(tty->port); tty_buffer_restart_work(tty->port);
err:
tty_ldisc_put(new_ldisc); /* drop the extra reference */
tty_unlock(tty); tty_unlock(tty);
return retval; return retval;
} }
......
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