diff options
-rw-r--r-- | drivers/char/tty_io.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 310e0703e4a1..fa162c93ee02 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -1293,6 +1293,12 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1293 | o_tty = alloc_tty_struct(); | 1293 | o_tty = alloc_tty_struct(); |
1294 | if (!o_tty) | 1294 | if (!o_tty) |
1295 | goto free_mem_out; | 1295 | goto free_mem_out; |
1296 | if (!try_module_get(driver->other->owner)) { | ||
1297 | /* This cannot in fact currently happen */ | ||
1298 | free_tty_struct(o_tty); | ||
1299 | o_tty = NULL; | ||
1300 | goto free_mem_out; | ||
1301 | } | ||
1296 | initialize_tty_struct(o_tty); | 1302 | initialize_tty_struct(o_tty); |
1297 | o_tty->driver = driver->other; | 1303 | o_tty->driver = driver->other; |
1298 | o_tty->ops = driver->ops; | 1304 | o_tty->ops = driver->ops; |
@@ -1411,8 +1417,10 @@ end_init: | |||
1411 | /* Release locally allocated memory ... nothing placed in slots */ | 1417 | /* Release locally allocated memory ... nothing placed in slots */ |
1412 | free_mem_out: | 1418 | free_mem_out: |
1413 | kfree(o_tp); | 1419 | kfree(o_tp); |
1414 | if (o_tty) | 1420 | if (o_tty) { |
1421 | module_put(o_tty->driver->owner); | ||
1415 | free_tty_struct(o_tty); | 1422 | free_tty_struct(o_tty); |
1423 | } | ||
1416 | kfree(ltp); | 1424 | kfree(ltp); |
1417 | kfree(tp); | 1425 | kfree(tp); |
1418 | free_tty_struct(tty); | 1426 | free_tty_struct(tty); |
@@ -1447,6 +1455,7 @@ release_mem_out: | |||
1447 | static void release_one_tty(struct kref *kref) | 1455 | static void release_one_tty(struct kref *kref) |
1448 | { | 1456 | { |
1449 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); | 1457 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); |
1458 | struct tty_driver *driver = tty->driver; | ||
1450 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; | 1459 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; |
1451 | struct ktermios *tp; | 1460 | struct ktermios *tp; |
1452 | int idx = tty->index; | 1461 | int idx = tty->index; |
@@ -1471,6 +1480,7 @@ static void release_one_tty(struct kref *kref) | |||
1471 | tty->magic = 0; | 1480 | tty->magic = 0; |
1472 | /* FIXME: locking on tty->driver->refcount */ | 1481 | /* FIXME: locking on tty->driver->refcount */ |
1473 | tty->driver->refcount--; | 1482 | tty->driver->refcount--; |
1483 | module_put(driver->owner); | ||
1474 | 1484 | ||
1475 | file_list_lock(); | 1485 | file_list_lock(); |
1476 | list_del_init(&tty->tty_files); | 1486 | list_del_init(&tty->tty_files); |
@@ -1506,20 +1516,15 @@ EXPORT_SYMBOL(tty_kref_put); | |||
1506 | * of ttys that the driver keeps. | 1516 | * of ttys that the driver keeps. |
1507 | * FIXME: should we require tty_mutex is held here ?? | 1517 | * FIXME: should we require tty_mutex is held here ?? |
1508 | * | 1518 | * |
1509 | * FIXME: We want to defer the module put of the driver to the | ||
1510 | * destructor. | ||
1511 | */ | 1519 | */ |
1512 | static void release_tty(struct tty_struct *tty, int idx) | 1520 | static void release_tty(struct tty_struct *tty, int idx) |
1513 | { | 1521 | { |
1514 | struct tty_driver *driver = tty->driver; | ||
1515 | |||
1516 | /* This should always be true but check for the moment */ | 1522 | /* This should always be true but check for the moment */ |
1517 | WARN_ON(tty->index != idx); | 1523 | WARN_ON(tty->index != idx); |
1518 | 1524 | ||
1519 | if (tty->link) | 1525 | if (tty->link) |
1520 | tty_kref_put(tty->link); | 1526 | tty_kref_put(tty->link); |
1521 | tty_kref_put(tty); | 1527 | tty_kref_put(tty); |
1522 | module_put(driver->owner); | ||
1523 | } | 1528 | } |
1524 | 1529 | ||
1525 | /* | 1530 | /* |