]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
tty: Simplify tty_set_ldisc() exit handling
authorPeter Hurley <peter@hurleysoftware.com>
Sun, 8 Nov 2015 14:29:38 +0000 (09:29 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Dec 2015 03:59:48 +0000 (19:59 -0800)
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>
drivers/tty/tty_ldisc.c

index 7d43ff12f6e200768557e3019051db55d9ad70db..9ec12504634368b4f8c49fa43bdf5dc79331175c 100644 (file)
@@ -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;
 }