mirror of https://gitee.com/openkylin/linux.git
tty: Refactor tty_open()
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>
This commit is contained in:
parent
11e1d4aa4d
commit
d6203d0c7b
|
@ -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 @@ 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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue