Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1305431
| From | Peter Hurley <peter@hurleysoftware.com> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH v2 16/19] tty: Refactor tty_ldisc_reinit() for reuse |
| Date | 2016-01-10 05:50 +0100 |
| Message-ID | <qPg71-7Hn-41@gated-at.bofh.it> (permalink) |
| References | <qzyUh-8cQ-9@gated-at.bofh.it> <qPg6Z-7Hn-3@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
At tty hangup, the line discipline instance is reinitialized by
closing the current ldisc instance and opening a new instance.
This operation is complicated by error recovery: if the attempt
to reinit the current line discipline fails, the line discipline
is reset to N_TTY (which should not but can fail).
Re-purpose tty_ldisc_reinit() to return a valid, open line discipline
instance, or otherwise, an error.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
---
drivers/tty/tty_ldisc.c | 53 +++++++++++++++++++++++++++++--------------------
1 file changed, 31 insertions(+), 22 deletions(-)
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 6ba6fe1..527fc5b 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -643,26 +643,41 @@ static void tty_reset_termios(struct tty_struct *tty)
* @tty: tty to reinit
* @disc: line discipline to reinitialize
*
- * Switch the tty to a line discipline and leave the ldisc
- * state closed
+ * Completely reinitialize the line discipline state, by closing the
+ * current instance and opening a new instance. If an error occurs opening
+ * the new non-N_TTY instance, the instance is dropped and tty->ldisc reset
+ * to NULL. The caller can then retry with N_TTY instead.
+ *
+ * Returns 0 if successful, otherwise error code < 0
*/
static int tty_ldisc_reinit(struct tty_struct *tty, int disc)
{
- struct tty_ldisc *ld = tty_ldisc_get(tty, disc);
+ struct tty_ldisc *ld;
+ int retval;
- if (IS_ERR(ld))
- return -1;
+ ld = tty_ldisc_get(tty, disc);
+ if (IS_ERR(ld)) {
+ BUG_ON(disc == N_TTY);
+ return PTR_ERR(ld);
+ }
- tty_ldisc_close(tty, tty->ldisc);
- tty_ldisc_put(tty->ldisc);
- /*
- * Switch the line discipline back
- */
+ if (tty->ldisc) {
+ tty_ldisc_close(tty, tty->ldisc);
+ tty_ldisc_put(tty->ldisc);
+ }
+
+ /* switch the line discipline */
tty->ldisc = ld;
tty_set_termios_ldisc(tty, disc);
-
- return 0;
+ retval = tty_ldisc_open(tty, tty->ldisc);
+ if (retval) {
+ if (!WARN_ON(disc == N_TTY)) {
+ tty_ldisc_put(tty->ldisc);
+ tty->ldisc = NULL;
+ }
+ }
+ return retval;
}
/**
@@ -718,19 +733,13 @@ void tty_ldisc_hangup(struct tty_struct *tty)
reopen a new ldisc. We could defer the reopen to the next
open but it means auditing a lot of other paths so this is
a FIXME */
- if (reset == 0) {
+ if (reset == 0)
+ err = tty_ldisc_reinit(tty, tty->termios.c_line);
- if (!tty_ldisc_reinit(tty, tty->termios.c_line))
- err = tty_ldisc_open(tty, tty->ldisc);
- else
- err = 1;
- }
/* If the re-open fails or we reset then go to N_TTY. The
N_TTY open cannot fail */
- if (reset || err) {
- BUG_ON(tty_ldisc_reinit(tty, N_TTY));
- WARN_ON(tty_ldisc_open(tty, tty->ldisc));
- }
+ if (reset || err < 0)
+ tty_ldisc_reinit(tty, N_TTY);
}
tty_ldisc_unlock(tty);
if (reset)
--
2.7.0
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH v2 00/19] Fix driver crashes on hangup Peter Hurley <peter@hurleysoftware.com> - 2016-01-10 05:50 +0100
[PATCH v2 05/19] tty: Remove chars_in_buffer() line discipline method Peter Hurley <peter@hurleysoftware.com> - 2016-01-10 05:50 +0100
[PATCH v2 14/19] tty: Move tty_ldisc_kill() Peter Hurley <peter@hurleysoftware.com> - 2016-01-10 05:50 +0100
[PATCH v2 01/19] staging: digi: Replace open-coded tty_wakeup() Peter Hurley <peter@hurleysoftware.com> - 2016-01-10 05:50 +0100
[PATCH v2 12/19] tty: Prepare for destroying line discipline on hangup Peter Hurley <peter@hurleysoftware.com> - 2016-01-10 05:50 +0100
[PATCH v2 08/19] tty: Reset c_line from driver's init_termios Peter Hurley <peter@hurleysoftware.com> - 2016-01-10 05:50 +0100
[PATCH v2 02/19] serial: 68328: Remove bogus ldisc reset Peter Hurley <peter@hurleysoftware.com> - 2016-01-10 05:50 +0100
[PATCH v2 16/19] tty: Refactor tty_ldisc_reinit() for reuse Peter Hurley <peter@hurleysoftware.com> - 2016-01-10 05:50 +0100
[PATCH v2 03/19] bluetooth: hci_ldisc: Remove dead code Peter Hurley <peter@hurleysoftware.com> - 2016-01-10 05:50 +0100
[PATCH v3 19/19] tty: Avoid unnecessary temporaries for tty->ldisc Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 17/19] tty: Destroy ldisc instance on hangup Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 08/19] tty: Reset c_line from driver's init_termios Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 06/19] tty: Fix unsafe ldisc reference via ioctl(TIOCGETD) Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 04/19] NFC: nci: Remove dead code Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 15/19] tty: Use 'disc' for line discipline index name Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 01/19] staging: digi: Replace open-coded tty_wakeup() Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 14/19] tty: Move tty_ldisc_kill() Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 05/19] tty: Remove chars_in_buffer() line discipline method Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 02/19] serial: 68328: Remove bogus ldisc reset Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
Re: [PATCH v3 02/19] serial: 68328: Remove bogus ldisc reset One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk> - 2016-01-11 15:20 +0100
[PATCH v3 13/19] tty: Handle NULL tty->ldisc Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 12/19] tty: Prepare for destroying line discipline on hangup Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 03/19] bluetooth: hci_ldisc: Remove dead code Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 10/19] tty: Fix comments for tty_ldisc_get() Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 07/19] n_tty: Fix unsafe reference to "other" ldisc Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 11/19] tty: Fix comments for tty_ldisc_release() Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 09/19] staging/speakup: Use tty_ldisc_ref() for paste kworker Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 18/19] tty: Document c_line == N_TTY initial condition Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 16/19] tty: Refactor tty_ldisc_reinit() for reuse Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
[PATCH v3 00/19] Fix driver crashes on hangup Peter Hurley <peter@hurleysoftware.com> - 2016-01-11 07:50 +0100
csiph-web