diff options
Diffstat (limited to 'drivers/tty/tty_io.c')
| -rw-r--r-- | drivers/tty/tty_io.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index c05c5af5aa04..35480dd57a30 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
| @@ -559,6 +559,9 @@ void __tty_hangup(struct tty_struct *tty) | |||
| 559 | 559 | ||
| 560 | tty_lock(); | 560 | tty_lock(); |
| 561 | 561 | ||
| 562 | /* some functions below drop BTM, so we need this bit */ | ||
| 563 | set_bit(TTY_HUPPING, &tty->flags); | ||
| 564 | |||
| 562 | /* inuse_filps is protected by the single tty lock, | 565 | /* inuse_filps is protected by the single tty lock, |
| 563 | this really needs to change if we want to flush the | 566 | this really needs to change if we want to flush the |
| 564 | workqueue with the lock held */ | 567 | workqueue with the lock held */ |
| @@ -578,6 +581,10 @@ void __tty_hangup(struct tty_struct *tty) | |||
| 578 | } | 581 | } |
| 579 | spin_unlock(&tty_files_lock); | 582 | spin_unlock(&tty_files_lock); |
| 580 | 583 | ||
| 584 | /* | ||
| 585 | * it drops BTM and thus races with reopen | ||
| 586 | * we protect the race by TTY_HUPPING | ||
| 587 | */ | ||
| 581 | tty_ldisc_hangup(tty); | 588 | tty_ldisc_hangup(tty); |
| 582 | 589 | ||
| 583 | read_lock(&tasklist_lock); | 590 | read_lock(&tasklist_lock); |
| @@ -615,7 +622,6 @@ void __tty_hangup(struct tty_struct *tty) | |||
| 615 | tty->session = NULL; | 622 | tty->session = NULL; |
| 616 | tty->pgrp = NULL; | 623 | tty->pgrp = NULL; |
| 617 | tty->ctrl_status = 0; | 624 | tty->ctrl_status = 0; |
| 618 | set_bit(TTY_HUPPED, &tty->flags); | ||
| 619 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 625 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
| 620 | 626 | ||
| 621 | /* Account for the p->signal references we killed */ | 627 | /* Account for the p->signal references we killed */ |
| @@ -641,6 +647,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
| 641 | * can't yet guarantee all that. | 647 | * can't yet guarantee all that. |
| 642 | */ | 648 | */ |
| 643 | set_bit(TTY_HUPPED, &tty->flags); | 649 | set_bit(TTY_HUPPED, &tty->flags); |
| 650 | clear_bit(TTY_HUPPING, &tty->flags); | ||
| 644 | tty_ldisc_enable(tty); | 651 | tty_ldisc_enable(tty); |
| 645 | 652 | ||
| 646 | tty_unlock(); | 653 | tty_unlock(); |
| @@ -1310,7 +1317,9 @@ static int tty_reopen(struct tty_struct *tty) | |||
| 1310 | { | 1317 | { |
| 1311 | struct tty_driver *driver = tty->driver; | 1318 | struct tty_driver *driver = tty->driver; |
| 1312 | 1319 | ||
| 1313 | if (test_bit(TTY_CLOSING, &tty->flags)) | 1320 | if (test_bit(TTY_CLOSING, &tty->flags) || |
| 1321 | test_bit(TTY_HUPPING, &tty->flags) || | ||
| 1322 | test_bit(TTY_LDISC_CHANGING, &tty->flags)) | ||
| 1314 | return -EIO; | 1323 | return -EIO; |
| 1315 | 1324 | ||
| 1316 | if (driver->type == TTY_DRIVER_TYPE_PTY && | 1325 | if (driver->type == TTY_DRIVER_TYPE_PTY && |
