|
@@ -194,8 +194,7 @@ static inline struct tty_struct *file_tty(struct file *file)
|
|
|
return ((struct tty_file_private *)file->private_data)->tty;
|
|
|
}
|
|
|
|
|
|
-/* Associate a new file with the tty structure */
|
|
|
-int tty_add_file(struct tty_struct *tty, struct file *file)
|
|
|
+int tty_alloc_file(struct file *file)
|
|
|
{
|
|
|
struct tty_file_private *priv;
|
|
|
|
|
@@ -203,15 +202,36 @@ int tty_add_file(struct tty_struct *tty, struct file *file)
|
|
|
if (!priv)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
+ file->private_data = priv;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* Associate a new file with the tty structure */
|
|
|
+void tty_add_file(struct tty_struct *tty, struct file *file)
|
|
|
+{
|
|
|
+ struct tty_file_private *priv = file->private_data;
|
|
|
+
|
|
|
priv->tty = tty;
|
|
|
priv->file = file;
|
|
|
- file->private_data = priv;
|
|
|
|
|
|
spin_lock(&tty_files_lock);
|
|
|
list_add(&priv->list, &tty->tty_files);
|
|
|
spin_unlock(&tty_files_lock);
|
|
|
+}
|
|
|
|
|
|
- return 0;
|
|
|
+/**
|
|
|
+ * tty_free_file - free file->private_data
|
|
|
+ *
|
|
|
+ * This shall be used only for fail path handling when tty_add_file was not
|
|
|
+ * called yet.
|
|
|
+ */
|
|
|
+void tty_free_file(struct file *file)
|
|
|
+{
|
|
|
+ struct tty_file_private *priv = file->private_data;
|
|
|
+
|
|
|
+ file->private_data = NULL;
|
|
|
+ kfree(priv);
|
|
|
}
|
|
|
|
|
|
/* Delete file from its tty */
|
|
@@ -222,8 +242,7 @@ void tty_del_file(struct file *file)
|
|
|
spin_lock(&tty_files_lock);
|
|
|
list_del(&priv->list);
|
|
|
spin_unlock(&tty_files_lock);
|
|
|
- file->private_data = NULL;
|
|
|
- kfree(priv);
|
|
|
+ tty_free_file(file);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1812,6 +1831,10 @@ static int tty_open(struct inode *inode, struct file *filp)
|
|
|
nonseekable_open(inode, filp);
|
|
|
|
|
|
retry_open:
|
|
|
+ retval = tty_alloc_file(filp);
|
|
|
+ if (retval)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
noctty = filp->f_flags & O_NOCTTY;
|
|
|
index = -1;
|
|
|
retval = 0;
|
|
@@ -1824,6 +1847,7 @@ retry_open:
|
|
|
if (!tty) {
|
|
|
tty_unlock();
|
|
|
mutex_unlock(&tty_mutex);
|
|
|
+ tty_free_file(filp);
|
|
|
return -ENXIO;
|
|
|
}
|
|
|
driver = tty_driver_kref_get(tty->driver);
|
|
@@ -1856,6 +1880,7 @@ retry_open:
|
|
|
}
|
|
|
tty_unlock();
|
|
|
mutex_unlock(&tty_mutex);
|
|
|
+ tty_free_file(filp);
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
@@ -1863,6 +1888,7 @@ retry_open:
|
|
|
if (!driver) {
|
|
|
tty_unlock();
|
|
|
mutex_unlock(&tty_mutex);
|
|
|
+ tty_free_file(filp);
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
got_driver:
|
|
@@ -1874,6 +1900,7 @@ got_driver:
|
|
|
tty_unlock();
|
|
|
mutex_unlock(&tty_mutex);
|
|
|
tty_driver_kref_put(driver);
|
|
|
+ tty_free_file(filp);
|
|
|
return PTR_ERR(tty);
|
|
|
}
|
|
|
}
|
|
@@ -1889,15 +1916,11 @@ got_driver:
|
|
|
tty_driver_kref_put(driver);
|
|
|
if (IS_ERR(tty)) {
|
|
|
tty_unlock();
|
|
|
+ tty_free_file(filp);
|
|
|
return PTR_ERR(tty);
|
|
|
}
|
|
|
|
|
|
- retval = tty_add_file(tty, filp);
|
|
|
- if (retval) {
|
|
|
- tty_unlock();
|
|
|
- tty_release(inode, filp);
|
|
|
- return retval;
|
|
|
- }
|
|
|
+ tty_add_file(tty, filp);
|
|
|
|
|
|
check_tty_count(tty, "tty_open");
|
|
|
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
|