Skip to content

Commit

Permalink
tty: Refactor tty_open()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Peter Hurley authored and Greg Kroah-Hartman committed Jan 27, 2016
1 parent 11e1d4a commit d6203d0
Showing 1 changed file with 67 additions and 53 deletions.
120 changes: 67 additions & 53 deletions drivers/tty/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand All @@ -2034,53 +2095,15 @@ static int tty_open(struct inode *inode, struct file *filp)
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;
}
Expand Down Expand Up @@ -2151,15 +2174,6 @@ static int tty_open(struct inode *inode, struct file *filp)
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;
}


Expand Down

0 comments on commit d6203d0

Please sign in to comment.