@@ -1994,6 +1994,69 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
19941994 return driver ;
19951995}
19961996
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+
19972060/**
19982061 * tty_open - open a tty device
19992062 * @inode: inode of device file
@@ -2022,8 +2085,6 @@ static int tty_open(struct inode *inode, struct file *filp)
20222085{
20232086 struct tty_struct * tty ;
20242087 int noctty , retval ;
2025- struct tty_driver * driver = NULL ;
2026- int index ;
20272088 dev_t device = inode -> i_rdev ;
20282089 unsigned saved_flags = filp -> f_flags ;
20292090
@@ -2034,53 +2095,15 @@ static int tty_open(struct inode *inode, struct file *filp)
20342095 if (retval )
20352096 return - ENOMEM ;
20362097
2037- index = -1 ;
2038- retval = 0 ;
2039-
20402098 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 );
20782101
20792102 if (IS_ERR (tty )) {
2103+ tty_free_file (filp );
20802104 retval = PTR_ERR (tty );
20812105 if (retval != - EAGAIN || signal_pending (current ))
2082- goto err_file ;
2083- tty_free_file (filp );
2106+ return retval ;
20842107 schedule ();
20852108 goto retry_open ;
20862109 }
@@ -2151,15 +2174,6 @@ static int tty_open(struct inode *inode, struct file *filp)
21512174 read_unlock (& tasklist_lock );
21522175 tty_unlock (tty );
21532176 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 ;
21632177}
21642178
21652179
0 commit comments