Merge remote-tracking branch 'origin/develop-3.0' into develop-3.0-jb
[firefly-linux-kernel-4.4.55.git] / drivers / tty / pty.c
index 98b6e3bdb000bda730a69a05680d76b8584f1715..e18604b3fc7d6c00f13bb05079f48554dca143aa 100644 (file)
@@ -446,8 +446,19 @@ static inline void legacy_pty_init(void) { }
 int pty_limit = NR_UNIX98_PTY_DEFAULT;
 static int pty_limit_min;
 static int pty_limit_max = NR_UNIX98_PTY_MAX;
+static int tty_count;
 static int pty_count;
 
+static inline void pty_inc_count(void)
+{
+       pty_count = (++tty_count) / 2;
+}
+
+static inline void pty_dec_count(void)
+{
+       pty_count = (--tty_count) / 2;
+}
+
 static struct cdev ptmx_cdev;
 
 static struct ctl_table pty_table[] = {
@@ -542,6 +553,7 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
 
 static void pty_unix98_shutdown(struct tty_struct *tty)
 {
+       tty_driver_remove_tty(tty->driver, tty);
        /* We have our own method as we don't use the tty index */
        kfree(tty->termios);
 }
@@ -588,7 +600,8 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
         */
        tty_driver_kref_get(driver);
        tty->count++;
-       pty_count++;
+       pty_inc_count(); /* tty */
+       pty_inc_count(); /* tty->link */
        return 0;
 err_free_mem:
        deinitialize_tty_struct(o_tty);
@@ -602,7 +615,7 @@ err_free_tty:
 
 static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
 {
-       pty_count--;
+       pty_dec_count();
 }
 
 static const struct tty_operations ptm_unix98_ops = {
@@ -657,12 +670,18 @@ static int ptmx_open(struct inode *inode, struct file *filp)
 
        nonseekable_open(inode, filp);
 
+       retval = tty_alloc_file(filp);
+       if (retval)
+               return retval;
+
        /* find a device that is not in use. */
        tty_lock();
        index = devpts_new_index(inode);
        tty_unlock();
-       if (index < 0)
-               return index;
+       if (index < 0) {
+               retval = index;
+               goto err_file;
+       }
 
        mutex_lock(&tty_mutex);
        tty_lock();
@@ -676,27 +695,27 @@ static int ptmx_open(struct inode *inode, struct file *filp)
 
        set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
 
-       retval = tty_add_file(tty, filp);
-       if (retval)
-               goto out;
+       tty_add_file(tty, filp);
 
        retval = devpts_pty_new(inode, tty->link);
        if (retval)
-               goto out1;
+               goto err_release;
 
        retval = ptm_driver->ops->open(tty, filp);
        if (retval)
-               goto out2;
-out1:
+               goto err_release;
+
        tty_unlock();
-       return retval;
-out2:
+       return 0;
+err_release:
        tty_unlock();
        tty_release(inode, filp);
        return retval;
 out:
        devpts_kill_index(inode, index);
        tty_unlock();
+err_file:
+       tty_free_file(filp);
        return retval;
 }