mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-11 03:48:00 +00:00
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;
|
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
|
* tty_open - open a tty device
|
||||||
* @inode: inode of device file
|
* @inode: inode of device file
|
||||||
@ -2022,8 +2085,6 @@ static int tty_open(struct inode *inode, struct file *filp)
|
|||||||
{
|
{
|
||||||
struct tty_struct *tty;
|
struct tty_struct *tty;
|
||||||
int noctty, retval;
|
int noctty, retval;
|
||||||
struct tty_driver *driver = NULL;
|
|
||||||
int index;
|
|
||||||
dev_t device = inode->i_rdev;
|
dev_t device = inode->i_rdev;
|
||||||
unsigned saved_flags = filp->f_flags;
|
unsigned saved_flags = filp->f_flags;
|
||||||
|
|
||||||
@ -2034,53 +2095,15 @@ retry_open:
|
|||||||
if (retval)
|
if (retval)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
index = -1;
|
|
||||||
retval = 0;
|
|
||||||
|
|
||||||
tty = tty_open_current_tty(device, filp);
|
tty = tty_open_current_tty(device, filp);
|
||||||
if (!tty) {
|
if (!tty)
|
||||||
mutex_lock(&tty_mutex);
|
tty = tty_open_by_driver(device, inode, filp);
|
||||||
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 (IS_ERR(tty)) {
|
if (IS_ERR(tty)) {
|
||||||
|
tty_free_file(filp);
|
||||||
retval = PTR_ERR(tty);
|
retval = PTR_ERR(tty);
|
||||||
if (retval != -EAGAIN || signal_pending(current))
|
if (retval != -EAGAIN || signal_pending(current))
|
||||||
goto err_file;
|
return retval;
|
||||||
tty_free_file(filp);
|
|
||||||
schedule();
|
schedule();
|
||||||
goto retry_open;
|
goto retry_open;
|
||||||
}
|
}
|
||||||
@ -2151,15 +2174,6 @@ retry_open:
|
|||||||
read_unlock(&tasklist_lock);
|
read_unlock(&tasklist_lock);
|
||||||
tty_unlock(tty);
|
tty_unlock(tty);
|
||||||
return 0;
|
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…
x
Reference in New Issue
Block a user