aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r--drivers/tty/tty_io.c50
1 files changed, 38 insertions, 12 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 4f1fc81112e6..05085beb83db 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -194,8 +194,7 @@ static inline struct tty_struct *file_tty(struct file *file)
194 return ((struct tty_file_private *)file->private_data)->tty; 194 return ((struct tty_file_private *)file->private_data)->tty;
195} 195}
196 196
197/* Associate a new file with the tty structure */ 197int tty_alloc_file(struct file *file)
198int tty_add_file(struct tty_struct *tty, struct file *file)
199{ 198{
200 struct tty_file_private *priv; 199 struct tty_file_private *priv;
201 200
@@ -203,15 +202,36 @@ int tty_add_file(struct tty_struct *tty, struct file *file)
203 if (!priv) 202 if (!priv)
204 return -ENOMEM; 203 return -ENOMEM;
205 204
205 file->private_data = priv;
206
207 return 0;
208}
209
210/* Associate a new file with the tty structure */
211void tty_add_file(struct tty_struct *tty, struct file *file)
212{
213 struct tty_file_private *priv = file->private_data;
214
206 priv->tty = tty; 215 priv->tty = tty;
207 priv->file = file; 216 priv->file = file;
208 file->private_data = priv;
209 217
210 spin_lock(&tty_files_lock); 218 spin_lock(&tty_files_lock);
211 list_add(&priv->list, &tty->tty_files); 219 list_add(&priv->list, &tty->tty_files);
212 spin_unlock(&tty_files_lock); 220 spin_unlock(&tty_files_lock);
221}
213 222
214 return 0; 223/**
224 * tty_free_file - free file->private_data
225 *
226 * This shall be used only for fail path handling when tty_add_file was not
227 * called yet.
228 */
229void tty_free_file(struct file *file)
230{
231 struct tty_file_private *priv = file->private_data;
232
233 file->private_data = NULL;
234 kfree(priv);
215} 235}
216 236
217/* Delete file from its tty */ 237/* Delete file from its tty */
@@ -222,8 +242,7 @@ void tty_del_file(struct file *file)
222 spin_lock(&tty_files_lock); 242 spin_lock(&tty_files_lock);
223 list_del(&priv->list); 243 list_del(&priv->list);
224 spin_unlock(&tty_files_lock); 244 spin_unlock(&tty_files_lock);
225 file->private_data = NULL; 245 tty_free_file(file);
226 kfree(priv);
227} 246}
228 247
229 248
@@ -1811,6 +1830,10 @@ static int tty_open(struct inode *inode, struct file *filp)
1811 nonseekable_open(inode, filp); 1830 nonseekable_open(inode, filp);
1812 1831
1813retry_open: 1832retry_open:
1833 retval = tty_alloc_file(filp);
1834 if (retval)
1835 return -ENOMEM;
1836
1814 noctty = filp->f_flags & O_NOCTTY; 1837 noctty = filp->f_flags & O_NOCTTY;
1815 index = -1; 1838 index = -1;
1816 retval = 0; 1839 retval = 0;
@@ -1823,6 +1846,7 @@ retry_open:
1823 if (!tty) { 1846 if (!tty) {
1824 tty_unlock(); 1847 tty_unlock();
1825 mutex_unlock(&tty_mutex); 1848 mutex_unlock(&tty_mutex);
1849 tty_free_file(filp);
1826 return -ENXIO; 1850 return -ENXIO;
1827 } 1851 }
1828 driver = tty_driver_kref_get(tty->driver); 1852 driver = tty_driver_kref_get(tty->driver);
@@ -1855,6 +1879,7 @@ retry_open:
1855 } 1879 }
1856 tty_unlock(); 1880 tty_unlock();
1857 mutex_unlock(&tty_mutex); 1881 mutex_unlock(&tty_mutex);
1882 tty_free_file(filp);
1858 return -ENODEV; 1883 return -ENODEV;
1859 } 1884 }
1860 1885
@@ -1862,6 +1887,7 @@ retry_open:
1862 if (!driver) { 1887 if (!driver) {
1863 tty_unlock(); 1888 tty_unlock();
1864 mutex_unlock(&tty_mutex); 1889 mutex_unlock(&tty_mutex);
1890 tty_free_file(filp);
1865 return -ENODEV; 1891 return -ENODEV;
1866 } 1892 }
1867got_driver: 1893got_driver:
@@ -1872,6 +1898,8 @@ got_driver:
1872 if (IS_ERR(tty)) { 1898 if (IS_ERR(tty)) {
1873 tty_unlock(); 1899 tty_unlock();
1874 mutex_unlock(&tty_mutex); 1900 mutex_unlock(&tty_mutex);
1901 tty_driver_kref_put(driver);
1902 tty_free_file(filp);
1875 return PTR_ERR(tty); 1903 return PTR_ERR(tty);
1876 } 1904 }
1877 } 1905 }
@@ -1887,15 +1915,11 @@ got_driver:
1887 tty_driver_kref_put(driver); 1915 tty_driver_kref_put(driver);
1888 if (IS_ERR(tty)) { 1916 if (IS_ERR(tty)) {
1889 tty_unlock(); 1917 tty_unlock();
1918 tty_free_file(filp);
1890 return PTR_ERR(tty); 1919 return PTR_ERR(tty);
1891 } 1920 }
1892 1921
1893 retval = tty_add_file(tty, filp); 1922 tty_add_file(tty, filp);
1894 if (retval) {
1895 tty_unlock();
1896 tty_release(inode, filp);
1897 return retval;
1898 }
1899 1923
1900 check_tty_count(tty, "tty_open"); 1924 check_tty_count(tty, "tty_open");
1901 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 1925 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
@@ -2716,6 +2740,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
2716 ld = tty_ldisc_ref_wait(tty); 2740 ld = tty_ldisc_ref_wait(tty);
2717 if (ld->ops->compat_ioctl) 2741 if (ld->ops->compat_ioctl)
2718 retval = ld->ops->compat_ioctl(tty, file, cmd, arg); 2742 retval = ld->ops->compat_ioctl(tty, file, cmd, arg);
2743 else
2744 retval = n_tty_compat_ioctl_helper(tty, file, cmd, arg);
2719 tty_ldisc_deref(ld); 2745 tty_ldisc_deref(ld);
2720 2746
2721 return retval; 2747 return retval;