diff options
author | Jiri Slaby <jslaby@suse.cz> | 2011-11-09 15:33:20 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-11-15 18:52:45 -0500 |
commit | 5b5e70408f1e8a48deebedc26ba982bbc7db343e (patch) | |
tree | 67abea63ef57bac25f300eadd567b290bcae1794 /drivers/tty/tty_io.c | |
parent | b82154ac37a7d12335c7c3d3c34c549171ec0cb4 (diff) |
TTY: extract driver lookup from tty_open
The error handling in tty_open became unbearable. There were many
errors fixed recently. Extract the tty driver lookup from tty_open to
a separate function. This reduces the fail paths significantly and
makes tty_open more readable.
In the next patch we will move the fail path handling to the end of
the function.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r-- | drivers/tty/tty_io.c | 93 |
1 files changed, 55 insertions, 38 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 1b90c986b1bf..00b84984308d 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -1824,6 +1824,53 @@ static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp) | |||
1824 | } | 1824 | } |
1825 | 1825 | ||
1826 | /** | 1826 | /** |
1827 | * tty_lookup_driver - lookup a tty driver for a given device file | ||
1828 | * @device: device number | ||
1829 | * @filp: file pointer to tty | ||
1830 | * @noctty: set if the device should not become a controlling tty | ||
1831 | * @index: index for the device in the @return driver | ||
1832 | * @return: driver for this inode (with increased refcount) | ||
1833 | * | ||
1834 | * If @return is not erroneous, the caller is responsible to decrement the | ||
1835 | * refcount by tty_driver_kref_put. | ||
1836 | * | ||
1837 | * Locking: tty_mutex protects get_tty_driver | ||
1838 | */ | ||
1839 | static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | ||
1840 | int *noctty, int *index) | ||
1841 | { | ||
1842 | struct tty_driver *driver; | ||
1843 | |||
1844 | #ifdef CONFIG_VT | ||
1845 | if (device == MKDEV(TTY_MAJOR, 0)) { | ||
1846 | extern struct tty_driver *console_driver; | ||
1847 | driver = tty_driver_kref_get(console_driver); | ||
1848 | *index = fg_console; | ||
1849 | *noctty = 1; | ||
1850 | return driver; | ||
1851 | } | ||
1852 | #endif | ||
1853 | if (device == MKDEV(TTYAUX_MAJOR, 1)) { | ||
1854 | struct tty_driver *console_driver = console_device(index); | ||
1855 | if (console_driver) { | ||
1856 | driver = tty_driver_kref_get(console_driver); | ||
1857 | if (driver) { | ||
1858 | /* Don't let /dev/console block */ | ||
1859 | filp->f_flags |= O_NONBLOCK; | ||
1860 | *noctty = 1; | ||
1861 | return driver; | ||
1862 | } | ||
1863 | } | ||
1864 | return ERR_PTR(-ENODEV); | ||
1865 | } | ||
1866 | |||
1867 | driver = get_tty_driver(device, index); | ||
1868 | if (!driver) | ||
1869 | return ERR_PTR(-ENODEV); | ||
1870 | return driver; | ||
1871 | } | ||
1872 | |||
1873 | /** | ||
1827 | * tty_open - open a tty device | 1874 | * tty_open - open a tty device |
1828 | * @inode: inode of device file | 1875 | * @inode: inode of device file |
1829 | * @filp: file pointer to tty | 1876 | * @filp: file pointer to tty |
@@ -1839,7 +1886,7 @@ static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp) | |||
1839 | * The termios state of a pty is reset on first open so that | 1886 | * The termios state of a pty is reset on first open so that |
1840 | * settings don't persist across reuse. | 1887 | * settings don't persist across reuse. |
1841 | * | 1888 | * |
1842 | * Locking: tty_mutex protects tty, get_tty_driver and tty_init_dev work. | 1889 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. |
1843 | * tty->count should protect the rest. | 1890 | * tty->count should protect the rest. |
1844 | * ->siglock protects ->signal/->sighand | 1891 | * ->siglock protects ->signal/->sighand |
1845 | */ | 1892 | */ |
@@ -1873,47 +1920,17 @@ retry_open: | |||
1873 | mutex_unlock(&tty_mutex); | 1920 | mutex_unlock(&tty_mutex); |
1874 | tty_free_file(filp); | 1921 | tty_free_file(filp); |
1875 | return PTR_ERR(tty); | 1922 | return PTR_ERR(tty); |
1876 | } else if (tty) | 1923 | } else if (!tty) { |
1877 | goto got_driver; | 1924 | driver = tty_lookup_driver(device, filp, &noctty, &index); |
1878 | 1925 | if (IS_ERR(driver)) { | |
1879 | #ifdef CONFIG_VT | 1926 | tty_unlock(); |
1880 | if (device == MKDEV(TTY_MAJOR, 0)) { | 1927 | mutex_unlock(&tty_mutex); |
1881 | extern struct tty_driver *console_driver; | 1928 | tty_free_file(filp); |
1882 | driver = tty_driver_kref_get(console_driver); | 1929 | return PTR_ERR(driver); |
1883 | index = fg_console; | ||
1884 | noctty = 1; | ||
1885 | goto got_driver; | ||
1886 | } | ||
1887 | #endif | ||
1888 | if (device == MKDEV(TTYAUX_MAJOR, 1)) { | ||
1889 | struct tty_driver *console_driver = console_device(&index); | ||
1890 | if (console_driver) { | ||
1891 | driver = tty_driver_kref_get(console_driver); | ||
1892 | if (driver) { | ||
1893 | /* Don't let /dev/console block */ | ||
1894 | filp->f_flags |= O_NONBLOCK; | ||
1895 | noctty = 1; | ||
1896 | goto got_driver; | ||
1897 | } | ||
1898 | } | 1930 | } |
1899 | tty_unlock(); | ||
1900 | mutex_unlock(&tty_mutex); | ||
1901 | tty_free_file(filp); | ||
1902 | return -ENODEV; | ||
1903 | } | ||
1904 | 1931 | ||
1905 | driver = get_tty_driver(device, &index); | ||
1906 | if (!driver) { | ||
1907 | tty_unlock(); | ||
1908 | mutex_unlock(&tty_mutex); | ||
1909 | tty_free_file(filp); | ||
1910 | return -ENODEV; | ||
1911 | } | ||
1912 | got_driver: | ||
1913 | if (!tty) { | ||
1914 | /* check whether we're reopening an existing tty */ | 1932 | /* check whether we're reopening an existing tty */ |
1915 | tty = tty_driver_lookup_tty(driver, inode, index); | 1933 | tty = tty_driver_lookup_tty(driver, inode, index); |
1916 | |||
1917 | if (IS_ERR(tty)) { | 1934 | if (IS_ERR(tty)) { |
1918 | tty_unlock(); | 1935 | tty_unlock(); |
1919 | mutex_unlock(&tty_mutex); | 1936 | mutex_unlock(&tty_mutex); |