|
@@ -1293,6 +1293,12 @@ static int init_dev(struct tty_driver *driver, int idx,
|
|
o_tty = alloc_tty_struct();
|
|
o_tty = alloc_tty_struct();
|
|
if (!o_tty)
|
|
if (!o_tty)
|
|
goto free_mem_out;
|
|
goto free_mem_out;
|
|
|
|
+ if (!try_module_get(driver->other->owner)) {
|
|
|
|
+ /* This cannot in fact currently happen */
|
|
|
|
+ free_tty_struct(o_tty);
|
|
|
|
+ o_tty = NULL;
|
|
|
|
+ goto free_mem_out;
|
|
|
|
+ }
|
|
initialize_tty_struct(o_tty);
|
|
initialize_tty_struct(o_tty);
|
|
o_tty->driver = driver->other;
|
|
o_tty->driver = driver->other;
|
|
o_tty->ops = driver->ops;
|
|
o_tty->ops = driver->ops;
|
|
@@ -1411,8 +1417,10 @@ end_init:
|
|
/* Release locally allocated memory ... nothing placed in slots */
|
|
/* Release locally allocated memory ... nothing placed in slots */
|
|
free_mem_out:
|
|
free_mem_out:
|
|
kfree(o_tp);
|
|
kfree(o_tp);
|
|
- if (o_tty)
|
|
|
|
|
|
+ if (o_tty) {
|
|
|
|
+ module_put(o_tty->driver->owner);
|
|
free_tty_struct(o_tty);
|
|
free_tty_struct(o_tty);
|
|
|
|
+ }
|
|
kfree(ltp);
|
|
kfree(ltp);
|
|
kfree(tp);
|
|
kfree(tp);
|
|
free_tty_struct(tty);
|
|
free_tty_struct(tty);
|
|
@@ -1447,6 +1455,7 @@ release_mem_out:
|
|
static void release_one_tty(struct kref *kref)
|
|
static void release_one_tty(struct kref *kref)
|
|
{
|
|
{
|
|
struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
|
|
struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
|
|
|
|
+ struct tty_driver *driver = tty->driver;
|
|
int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM;
|
|
int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM;
|
|
struct ktermios *tp;
|
|
struct ktermios *tp;
|
|
int idx = tty->index;
|
|
int idx = tty->index;
|
|
@@ -1471,6 +1480,7 @@ static void release_one_tty(struct kref *kref)
|
|
tty->magic = 0;
|
|
tty->magic = 0;
|
|
/* FIXME: locking on tty->driver->refcount */
|
|
/* FIXME: locking on tty->driver->refcount */
|
|
tty->driver->refcount--;
|
|
tty->driver->refcount--;
|
|
|
|
+ module_put(driver->owner);
|
|
|
|
|
|
file_list_lock();
|
|
file_list_lock();
|
|
list_del_init(&tty->tty_files);
|
|
list_del_init(&tty->tty_files);
|
|
@@ -1506,20 +1516,15 @@ EXPORT_SYMBOL(tty_kref_put);
|
|
* of ttys that the driver keeps.
|
|
* of ttys that the driver keeps.
|
|
* FIXME: should we require tty_mutex is held here ??
|
|
* FIXME: should we require tty_mutex is held here ??
|
|
*
|
|
*
|
|
- * FIXME: We want to defer the module put of the driver to the
|
|
|
|
- * destructor.
|
|
|
|
*/
|
|
*/
|
|
static void release_tty(struct tty_struct *tty, int idx)
|
|
static void release_tty(struct tty_struct *tty, int idx)
|
|
{
|
|
{
|
|
- struct tty_driver *driver = tty->driver;
|
|
|
|
-
|
|
|
|
/* This should always be true but check for the moment */
|
|
/* This should always be true but check for the moment */
|
|
WARN_ON(tty->index != idx);
|
|
WARN_ON(tty->index != idx);
|
|
|
|
|
|
if (tty->link)
|
|
if (tty->link)
|
|
tty_kref_put(tty->link);
|
|
tty_kref_put(tty->link);
|
|
tty_kref_put(tty);
|
|
tty_kref_put(tty);
|
|
- module_put(driver->owner);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|