From 48548299e32bd64800c48d4b9f254351f7df1ae0 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 29 Nov 2010 10:16:54 +0100 Subject: [PATCH] --- yaml --- r: 222827 b: refs/heads/master c: acfa747baf73922021a047f2d87a2d866f5dbab5 h: refs/heads/master i: 222825: e633c277741d48494c1c3a40c3ea5e5ce4cf1559 222823: 09512af54a536eede67bd8964858abdd213611c9 v: v3 --- [refs] | 2 +- trunk/drivers/tty/tty_io.c | 10 +++++++++- trunk/include/linux/tty.h | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 1cddbb936d38..fb31c750e875 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e2efafbf139d2bfdfe96f2901f03189fecd172e4 +refs/heads/master: acfa747baf73922021a047f2d87a2d866f5dbab5 diff --git a/trunk/drivers/tty/tty_io.c b/trunk/drivers/tty/tty_io.c index 878f6d667b17..35480dd57a30 100644 --- a/trunk/drivers/tty/tty_io.c +++ b/trunk/drivers/tty/tty_io.c @@ -559,6 +559,9 @@ void __tty_hangup(struct tty_struct *tty) tty_lock(); + /* some functions below drop BTM, so we need this bit */ + set_bit(TTY_HUPPING, &tty->flags); + /* inuse_filps is protected by the single tty lock, this really needs to change if we want to flush the workqueue with the lock held */ @@ -578,6 +581,10 @@ void __tty_hangup(struct tty_struct *tty) } spin_unlock(&tty_files_lock); + /* + * it drops BTM and thus races with reopen + * we protect the race by TTY_HUPPING + */ tty_ldisc_hangup(tty); read_lock(&tasklist_lock); @@ -615,7 +622,6 @@ void __tty_hangup(struct tty_struct *tty) tty->session = NULL; tty->pgrp = NULL; tty->ctrl_status = 0; - set_bit(TTY_HUPPED, &tty->flags); spin_unlock_irqrestore(&tty->ctrl_lock, flags); /* Account for the p->signal references we killed */ @@ -641,6 +647,7 @@ void __tty_hangup(struct tty_struct *tty) * can't yet guarantee all that. */ set_bit(TTY_HUPPED, &tty->flags); + clear_bit(TTY_HUPPING, &tty->flags); tty_ldisc_enable(tty); tty_unlock(); @@ -1311,6 +1318,7 @@ static int tty_reopen(struct tty_struct *tty) struct tty_driver *driver = tty->driver; if (test_bit(TTY_CLOSING, &tty->flags) || + test_bit(TTY_HUPPING, &tty->flags) || test_bit(TTY_LDISC_CHANGING, &tty->flags)) return -EIO; diff --git a/trunk/include/linux/tty.h b/trunk/include/linux/tty.h index c7ea9bc8897c..021bfd2f0860 100644 --- a/trunk/include/linux/tty.h +++ b/trunk/include/linux/tty.h @@ -367,6 +367,7 @@ struct tty_file_private { #define TTY_HUPPED 18 /* Post driver->hangup() */ #define TTY_FLUSHING 19 /* Flushing to ldisc in progress */ #define TTY_FLUSHPENDING 20 /* Queued buffer flush pending */ +#define TTY_HUPPING 21 /* ->hangup() in progress */ #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))