tty: Refactor tty_open()
authorPeter Hurley <peter@hurleysoftware.com>
Sun, 10 Jan 2016 05:13:53 +0000 (21:13 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 27 Jan 2016 22:28:20 +0000 (14:28 -0800)
Extract the driver lookup and reopen-or-initialize logic into helper
function tty_open_by_driver(). No functional change.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/tty_io.c

index 741a0d7f51ce14e55630e8927281931aedaf9ff9..524703a7df2b175d33241eada47bc852641748bc 100644 (file)
@@ -1994,6 +1994,69 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
        return driver;
 }
 
+/**
+ *     tty_open_by_driver      -       open a tty device
+ *     @device: dev_t of device to open
+ *     @inode: inode of device file
+ *     @filp: file pointer to tty
+ *
+ *     Performs the driver lookup, checks for a reopen, or otherwise
+ *     performs the first-time tty initialization.
+ *
+ *     Returns the locked initialized or re-opened &tty_struct
+ *
+ *     Claims the global tty_mutex to serialize:
+ *       - concurrent first-time tty initialization
+ *       - concurrent tty driver removal w/ lookup
+ *       - concurrent tty removal from driver table
+ */
+static struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode,
+                                            struct file *filp)
+{
+       struct tty_struct *tty;
+       struct tty_driver *driver = NULL;
+       int index = -1;
+       int retval;
+
+       mutex_lock(&tty_mutex);
+       driver = tty_lookup_driver(device, filp, &index);
+       if (IS_ERR(driver)) {
+               mutex_unlock(&tty_mutex);
+               return ERR_CAST(driver);
+       }
+
+       /* check whether we're reopening an existing tty */
+       tty = tty_driver_lookup_tty(driver, inode, index);
+       if (IS_ERR(tty)) {
+               mutex_unlock(&tty_mutex);
+               goto out;
+       }
+
+       if (tty) {
+               mutex_unlock(&tty_mutex);
+               retval = tty_lock_interruptible(tty);
+               if (retval) {
+                       if (retval == -EINTR)
+                               retval = -ERESTARTSYS;
+                       tty = ERR_PTR(retval);
+                       goto out;
+               }
+               /* safe to drop the kref from tty_driver_lookup_tty() */
+               tty_kref_put(tty);
+               retval = tty_reopen(tty);
+               if (retval < 0) {
+                       tty_unlock(tty);
+                       tty = ERR_PTR(retval);
+               }
+       } else { /* Returns with the tty_lock held for now */
+               tty = tty_init_dev(driver, index);
+               mutex_unlock(&tty_mutex);
+       }
+out:
+       tty_driver_kref_put(driver);
+       return tty;
+}
+
 /**
  *     tty_open                -       open a tty device
  *     @inode: inode of device file
@@ -2022,8 +2085,6 @@ static int tty_open(struct inode *inode, struct file *filp)
 {
        struct tty_struct *tty;
        int noctty, retval;
-       struct tty_driver *driver = NULL;
-       int index;
        dev_t device = inode->i_rdev;
        unsigned saved_flags = filp->f_flags;
 
@@ -2034,53 +2095,15 @@ retry_open:
        if (retval)
                return -ENOMEM;
 
-       index  = -1;
-       retval = 0;
-
        tty = tty_open_current_tty(device, filp);
-       if (!tty) {
-               mutex_lock(&tty_mutex);
-               driver = tty_lookup_driver(device, filp, &index);
-               if (IS_ERR(driver)) {
-                       retval = PTR_ERR(driver);
-                       goto err_unlock;
-               }
-
-               /* check whether we're reopening an existing tty */
-               tty = tty_driver_lookup_tty(driver, inode, index);
-               if (IS_ERR(tty)) {
-                       retval = PTR_ERR(tty);
-                       goto err_unlock;
-               }
-
-               if (tty) {
-                       mutex_unlock(&tty_mutex);
-                       retval = tty_lock_interruptible(tty);
-                       if (retval) {
-                               if (retval == -EINTR)
-                                       retval = -ERESTARTSYS;
-                               goto err_unref;
-                       }
-                       /* safe to drop the kref from tty_driver_lookup_tty() */
-                       tty_kref_put(tty);
-                       retval = tty_reopen(tty);
-                       if (retval < 0) {
-                               tty_unlock(tty);
-                               tty = ERR_PTR(retval);
-                       }
-               } else { /* Returns with the tty_lock held for now */
-                       tty = tty_init_dev(driver, index);
-                       mutex_unlock(&tty_mutex);
-               }
-
-               tty_driver_kref_put(driver);
-       }
+       if (!tty)
+               tty = tty_open_by_driver(device, inode, filp);
 
        if (IS_ERR(tty)) {
+               tty_free_file(filp);
                retval = PTR_ERR(tty);
                if (retval != -EAGAIN || signal_pending(current))
-                       goto err_file;
-               tty_free_file(filp);
+                       return retval;
                schedule();
                goto retry_open;
        }
@@ -2151,15 +2174,6 @@ retry_open:
        read_unlock(&tasklist_lock);
        tty_unlock(tty);
        return 0;
-err_unlock:
-       mutex_unlock(&tty_mutex);
-err_unref:
-       /* after locks to avoid deadlock */
-       if (!IS_ERR_OR_NULL(driver))
-               tty_driver_kref_put(driver);
-err_file:
-       tty_free_file(filp);
-       return retval;
 }