@@ -1994,6 +1994,69 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
1994
1994
return driver ;
1995
1995
}
1996
1996
1997
+ /**
1998
+ * tty_open_by_driver - open a tty device
1999
+ * @device: dev_t of device to open
2000
+ * @inode: inode of device file
2001
+ * @filp: file pointer to tty
2002
+ *
2003
+ * Performs the driver lookup, checks for a reopen, or otherwise
2004
+ * performs the first-time tty initialization.
2005
+ *
2006
+ * Returns the locked initialized or re-opened &tty_struct
2007
+ *
2008
+ * Claims the global tty_mutex to serialize:
2009
+ * - concurrent first-time tty initialization
2010
+ * - concurrent tty driver removal w/ lookup
2011
+ * - concurrent tty removal from driver table
2012
+ */
2013
+ static struct tty_struct * tty_open_by_driver (dev_t device , struct inode * inode ,
2014
+ struct file * filp )
2015
+ {
2016
+ struct tty_struct * tty ;
2017
+ struct tty_driver * driver = NULL ;
2018
+ int index = -1 ;
2019
+ int retval ;
2020
+
2021
+ mutex_lock (& tty_mutex );
2022
+ driver = tty_lookup_driver (device , filp , & index );
2023
+ if (IS_ERR (driver )) {
2024
+ mutex_unlock (& tty_mutex );
2025
+ return ERR_CAST (driver );
2026
+ }
2027
+
2028
+ /* check whether we're reopening an existing tty */
2029
+ tty = tty_driver_lookup_tty (driver , inode , index );
2030
+ if (IS_ERR (tty )) {
2031
+ mutex_unlock (& tty_mutex );
2032
+ goto out ;
2033
+ }
2034
+
2035
+ if (tty ) {
2036
+ mutex_unlock (& tty_mutex );
2037
+ retval = tty_lock_interruptible (tty );
2038
+ if (retval ) {
2039
+ if (retval == - EINTR )
2040
+ retval = - ERESTARTSYS ;
2041
+ tty = ERR_PTR (retval );
2042
+ goto out ;
2043
+ }
2044
+ /* safe to drop the kref from tty_driver_lookup_tty() */
2045
+ tty_kref_put (tty );
2046
+ retval = tty_reopen (tty );
2047
+ if (retval < 0 ) {
2048
+ tty_unlock (tty );
2049
+ tty = ERR_PTR (retval );
2050
+ }
2051
+ } else { /* Returns with the tty_lock held for now */
2052
+ tty = tty_init_dev (driver , index );
2053
+ mutex_unlock (& tty_mutex );
2054
+ }
2055
+ out :
2056
+ tty_driver_kref_put (driver );
2057
+ return tty ;
2058
+ }
2059
+
1997
2060
/**
1998
2061
* tty_open - open a tty device
1999
2062
* @inode: inode of device file
@@ -2022,8 +2085,6 @@ static int tty_open(struct inode *inode, struct file *filp)
2022
2085
{
2023
2086
struct tty_struct * tty ;
2024
2087
int noctty , retval ;
2025
- struct tty_driver * driver = NULL ;
2026
- int index ;
2027
2088
dev_t device = inode -> i_rdev ;
2028
2089
unsigned saved_flags = filp -> f_flags ;
2029
2090
@@ -2034,53 +2095,15 @@ static int tty_open(struct inode *inode, struct file *filp)
2034
2095
if (retval )
2035
2096
return - ENOMEM ;
2036
2097
2037
- index = -1 ;
2038
- retval = 0 ;
2039
-
2040
2098
tty = tty_open_current_tty (device , filp );
2041
- if (!tty ) {
2042
- mutex_lock (& tty_mutex );
2043
- driver = tty_lookup_driver (device , filp , & index );
2044
- if (IS_ERR (driver )) {
2045
- retval = PTR_ERR (driver );
2046
- goto err_unlock ;
2047
- }
2048
-
2049
- /* check whether we're reopening an existing tty */
2050
- tty = tty_driver_lookup_tty (driver , inode , index );
2051
- if (IS_ERR (tty )) {
2052
- retval = PTR_ERR (tty );
2053
- goto err_unlock ;
2054
- }
2055
-
2056
- if (tty ) {
2057
- mutex_unlock (& tty_mutex );
2058
- retval = tty_lock_interruptible (tty );
2059
- if (retval ) {
2060
- if (retval == - EINTR )
2061
- retval = - ERESTARTSYS ;
2062
- goto err_unref ;
2063
- }
2064
- /* safe to drop the kref from tty_driver_lookup_tty() */
2065
- tty_kref_put (tty );
2066
- retval = tty_reopen (tty );
2067
- if (retval < 0 ) {
2068
- tty_unlock (tty );
2069
- tty = ERR_PTR (retval );
2070
- }
2071
- } else { /* Returns with the tty_lock held for now */
2072
- tty = tty_init_dev (driver , index );
2073
- mutex_unlock (& tty_mutex );
2074
- }
2075
-
2076
- tty_driver_kref_put (driver );
2077
- }
2099
+ if (!tty )
2100
+ tty = tty_open_by_driver (device , inode , filp );
2078
2101
2079
2102
if (IS_ERR (tty )) {
2103
+ tty_free_file (filp );
2080
2104
retval = PTR_ERR (tty );
2081
2105
if (retval != - EAGAIN || signal_pending (current ))
2082
- goto err_file ;
2083
- tty_free_file (filp );
2106
+ return retval ;
2084
2107
schedule ();
2085
2108
goto retry_open ;
2086
2109
}
@@ -2151,15 +2174,6 @@ static int tty_open(struct inode *inode, struct file *filp)
2151
2174
read_unlock (& tasklist_lock );
2152
2175
tty_unlock (tty );
2153
2176
return 0 ;
2154
- err_unlock :
2155
- mutex_unlock (& tty_mutex );
2156
- err_unref :
2157
- /* after locks to avoid deadlock */
2158
- if (!IS_ERR_OR_NULL (driver ))
2159
- tty_driver_kref_put (driver );
2160
- err_file :
2161
- tty_free_file (filp );
2162
- return retval ;
2163
2177
}
2164
2178
2165
2179
0 commit comments