Commit f309532b authored by Linus Torvalds's avatar Linus Torvalds

tty: Revert the tty locking series, it needs more work

This reverts the tty layer change to use per-tty locking, because it's
not correct yet, and fixing it will require some more deep surgery.

The main revert is d29f3ef3 ("tty_lock: Localise the lock"), but
there are several smaller commits that built upon it, they also get
reverted here. The list of reverted commits is:

  fde86d31 - tty: add lockdep annotations
  8f6576ad - tty: fix ldisc lock inversion trace
  d3ca8b64 - pty: Fix lock inversion
  b1d679af - tty: drop the pty lock during hangup
  abcefe5f - tty/amiserial: Add missing argument for tty_unlock()
  fd11b42e - cris: fix missing tty arg in wait_event_interruptible_tty call
  d29f3ef3 - tty_lock: Localise the lock

The revert had a trivial conflict in the 68360serial.c staging driver
that got removed in the meantime.
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 233e562e
...@@ -1033,7 +1033,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state, ...@@ -1033,7 +1033,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state,
if (!retinfo) if (!retinfo)
return -EFAULT; return -EFAULT;
memset(&tmp, 0, sizeof(tmp)); memset(&tmp, 0, sizeof(tmp));
tty_lock(tty); tty_lock();
tmp.line = tty->index; tmp.line = tty->index;
tmp.port = state->port; tmp.port = state->port;
tmp.flags = state->tport.flags; tmp.flags = state->tport.flags;
...@@ -1042,7 +1042,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state, ...@@ -1042,7 +1042,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state,
tmp.close_delay = state->tport.close_delay; tmp.close_delay = state->tport.close_delay;
tmp.closing_wait = state->tport.closing_wait; tmp.closing_wait = state->tport.closing_wait;
tmp.custom_divisor = state->custom_divisor; tmp.custom_divisor = state->custom_divisor;
tty_unlock(tty); tty_unlock();
if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -1059,12 +1059,12 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, ...@@ -1059,12 +1059,12 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
return -EFAULT; return -EFAULT;
tty_lock(tty); tty_lock();
change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) || change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) ||
new_serial.custom_divisor != state->custom_divisor; new_serial.custom_divisor != state->custom_divisor;
if (new_serial.irq || new_serial.port != state->port || if (new_serial.irq || new_serial.port != state->port ||
new_serial.xmit_fifo_size != state->xmit_fifo_size) { new_serial.xmit_fifo_size != state->xmit_fifo_size) {
tty_unlock(tty); tty_unlock();
return -EINVAL; return -EINVAL;
} }
...@@ -1074,7 +1074,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, ...@@ -1074,7 +1074,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
(new_serial.xmit_fifo_size != state->xmit_fifo_size) || (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
((new_serial.flags & ~ASYNC_USR_MASK) != ((new_serial.flags & ~ASYNC_USR_MASK) !=
(port->flags & ~ASYNC_USR_MASK))) { (port->flags & ~ASYNC_USR_MASK))) {
tty_unlock(tty); tty_unlock();
return -EPERM; return -EPERM;
} }
port->flags = ((port->flags & ~ASYNC_USR_MASK) | port->flags = ((port->flags & ~ASYNC_USR_MASK) |
...@@ -1084,7 +1084,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, ...@@ -1084,7 +1084,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
} }
if (new_serial.baud_base < 9600) { if (new_serial.baud_base < 9600) {
tty_unlock(tty); tty_unlock();
return -EINVAL; return -EINVAL;
} }
...@@ -1116,7 +1116,7 @@ check_and_exit: ...@@ -1116,7 +1116,7 @@ check_and_exit:
} }
} else } else
retval = startup(tty, state); retval = startup(tty, state);
tty_unlock(tty); tty_unlock();
return retval; return retval;
} }
......
...@@ -1599,7 +1599,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp) ...@@ -1599,7 +1599,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
* If the port is the middle of closing, bail out now * If the port is the middle of closing, bail out now
*/ */
if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) { if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
wait_event_interruptible_tty(tty, info->port.close_wait, wait_event_interruptible_tty(info->port.close_wait,
!(info->port.flags & ASYNC_CLOSING)); !(info->port.flags & ASYNC_CLOSING));
return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
} }
......
...@@ -1065,8 +1065,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, ...@@ -1065,8 +1065,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
TRACE_L("read()"); TRACE_L("read()");
/* FIXME: should use a private lock */ tty_lock();
tty_lock(tty);
pClient = findClient(pInfo, task_pid(current)); pClient = findClient(pInfo, task_pid(current));
if (pClient) { if (pClient) {
...@@ -1078,7 +1077,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, ...@@ -1078,7 +1077,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
goto unlock; goto unlock;
} }
/* block until there is a message: */ /* block until there is a message: */
wait_event_interruptible_tty(tty, pInfo->read_wait, wait_event_interruptible_tty(pInfo->read_wait,
(pMsg = remove_msg(pInfo, pClient))); (pMsg = remove_msg(pInfo, pClient)));
} }
...@@ -1108,7 +1107,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, ...@@ -1108,7 +1107,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
} }
ret = -EPERM; ret = -EPERM;
unlock: unlock:
tty_unlock(tty); tty_unlock();
return ret; return ret;
} }
...@@ -1157,7 +1156,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, ...@@ -1157,7 +1156,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
pHeader->locks = 0; pHeader->locks = 0;
pHeader->owner = NULL; pHeader->owner = NULL;
tty_lock(tty); tty_lock();
pClient = findClient(pInfo, task_pid(current)); pClient = findClient(pInfo, task_pid(current));
if (pClient) { if (pClient) {
...@@ -1176,7 +1175,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, ...@@ -1176,7 +1175,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
add_tx_queue(pInfo, pHeader); add_tx_queue(pInfo, pHeader);
trigger_transmit(pInfo); trigger_transmit(pInfo);
tty_unlock(tty); tty_unlock();
return 0; return 0;
} }
......
...@@ -47,7 +47,6 @@ static void pty_close(struct tty_struct *tty, struct file *filp) ...@@ -47,7 +47,6 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
wake_up_interruptible(&tty->read_wait); wake_up_interruptible(&tty->read_wait);
wake_up_interruptible(&tty->write_wait); wake_up_interruptible(&tty->write_wait);
tty->packet = 0; tty->packet = 0;
/* Review - krefs on tty_link ?? */
if (!tty->link) if (!tty->link)
return; return;
tty->link->packet = 0; tty->link->packet = 0;
...@@ -63,9 +62,9 @@ static void pty_close(struct tty_struct *tty, struct file *filp) ...@@ -63,9 +62,9 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
mutex_unlock(&devpts_mutex); mutex_unlock(&devpts_mutex);
} }
#endif #endif
tty_unlock(tty); tty_unlock();
tty_vhangup(tty->link); tty_vhangup(tty->link);
tty_lock(tty); tty_lock();
} }
} }
...@@ -623,27 +622,26 @@ static int ptmx_open(struct inode *inode, struct file *filp) ...@@ -623,27 +622,26 @@ static int ptmx_open(struct inode *inode, struct file *filp)
return retval; return retval;
/* find a device that is not in use. */ /* find a device that is not in use. */
mutex_lock(&devpts_mutex); tty_lock();
index = devpts_new_index(inode); index = devpts_new_index(inode);
tty_unlock();
if (index < 0) { if (index < 0) {
retval = index; retval = index;
goto err_file; goto err_file;
} }
mutex_unlock(&devpts_mutex);
mutex_lock(&tty_mutex); mutex_lock(&tty_mutex);
mutex_lock(&devpts_mutex);
tty = tty_init_dev(ptm_driver, index); tty = tty_init_dev(ptm_driver, index);
mutex_unlock(&devpts_mutex);
tty_lock();
mutex_unlock(&tty_mutex);
if (IS_ERR(tty)) { if (IS_ERR(tty)) {
retval = PTR_ERR(tty); retval = PTR_ERR(tty);
goto out; goto out;
} }
/* The tty returned here is locked so we can safely
drop the mutex */
mutex_unlock(&tty_mutex);
set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
tty_add_file(tty, filp); tty_add_file(tty, filp);
...@@ -656,17 +654,16 @@ static int ptmx_open(struct inode *inode, struct file *filp) ...@@ -656,17 +654,16 @@ static int ptmx_open(struct inode *inode, struct file *filp)
if (retval) if (retval)
goto err_release; goto err_release;
tty_unlock(tty); tty_unlock();
return 0; return 0;
err_release: err_release:
tty_unlock(tty); tty_unlock();
tty_release(inode, filp); tty_release(inode, filp);
return retval; return retval;
out: out:
mutex_unlock(&tty_mutex);
devpts_kill_index(inode, index); devpts_kill_index(inode, index);
tty_unlock();
err_file: err_file:
mutex_unlock(&devpts_mutex);
tty_free_file(filp); tty_free_file(filp);
return retval; return retval;
} }
......
...@@ -3976,7 +3976,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, ...@@ -3976,7 +3976,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
*/ */
if (tty_hung_up_p(filp) || if (tty_hung_up_p(filp) ||
(info->flags & ASYNC_CLOSING)) { (info->flags & ASYNC_CLOSING)) {
wait_event_interruptible_tty(tty, info->close_wait, wait_event_interruptible_tty(info->close_wait,
!(info->flags & ASYNC_CLOSING)); !(info->flags & ASYNC_CLOSING));
#ifdef SERIAL_DO_RESTART #ifdef SERIAL_DO_RESTART
if (info->flags & ASYNC_HUP_NOTIFY) if (info->flags & ASYNC_HUP_NOTIFY)
...@@ -4052,9 +4052,9 @@ block_til_ready(struct tty_struct *tty, struct file * filp, ...@@ -4052,9 +4052,9 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
printk("block_til_ready blocking: ttyS%d, count = %d\n", printk("block_til_ready blocking: ttyS%d, count = %d\n",
info->line, info->count); info->line, info->count);
#endif #endif
tty_unlock(tty); tty_unlock();
schedule(); schedule();
tty_lock(tty); tty_lock();
} }
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait); remove_wait_queue(&info->open_wait, &wait);
...@@ -4115,7 +4115,7 @@ rs_open(struct tty_struct *tty, struct file * filp) ...@@ -4115,7 +4115,7 @@ rs_open(struct tty_struct *tty, struct file * filp)
*/ */
if (tty_hung_up_p(filp) || if (tty_hung_up_p(filp) ||
(info->flags & ASYNC_CLOSING)) { (info->flags & ASYNC_CLOSING)) {
wait_event_interruptible_tty(tty, info->close_wait, wait_event_interruptible_tty(info->close_wait,
!(info->flags & ASYNC_CLOSING)); !(info->flags & ASYNC_CLOSING));
#ifdef SERIAL_DO_RESTART #ifdef SERIAL_DO_RESTART
return ((info->flags & ASYNC_HUP_NOTIFY) ? return ((info->flags & ASYNC_HUP_NOTIFY) ?
......
...@@ -3338,9 +3338,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, ...@@ -3338,9 +3338,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
printk("%s(%d):block_til_ready blocking on %s count=%d\n", printk("%s(%d):block_til_ready blocking on %s count=%d\n",
__FILE__,__LINE__, tty->driver->name, port->count ); __FILE__,__LINE__, tty->driver->name, port->count );
tty_unlock(tty); tty_unlock();
schedule(); schedule();
tty_lock(tty); tty_lock();
} }
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
......
...@@ -3336,9 +3336,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, ...@@ -3336,9 +3336,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
} }
DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); DBGINFO(("%s block_til_ready wait\n", tty->driver->name));
tty_unlock(tty); tty_unlock();
schedule(); schedule();
tty_lock(tty); tty_lock();
} }
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
......
...@@ -3357,9 +3357,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, ...@@ -3357,9 +3357,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
printk("%s(%d):%s block_til_ready() count=%d\n", printk("%s(%d):%s block_til_ready() count=%d\n",
__FILE__,__LINE__, tty->driver->name, port->count ); __FILE__,__LINE__, tty->driver->name, port->count );
tty_unlock(tty); tty_unlock();
schedule(); schedule();
tty_lock(tty); tty_lock();
} }
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
......
...@@ -185,7 +185,6 @@ void free_tty_struct(struct tty_struct *tty) ...@@ -185,7 +185,6 @@ void free_tty_struct(struct tty_struct *tty)
put_device(tty->dev); put_device(tty->dev);
kfree(tty->write_buf); kfree(tty->write_buf);
tty_buffer_free_all(tty); tty_buffer_free_all(tty);
tty->magic = 0xDEADDEAD;
kfree(tty); kfree(tty);
} }
...@@ -574,7 +573,7 @@ void __tty_hangup(struct tty_struct *tty) ...@@ -574,7 +573,7 @@ void __tty_hangup(struct tty_struct *tty)
} }
spin_unlock(&redirect_lock); spin_unlock(&redirect_lock);
tty_lock(tty); tty_lock();
/* some functions below drop BTM, so we need this bit */ /* some functions below drop BTM, so we need this bit */
set_bit(TTY_HUPPING, &tty->flags); set_bit(TTY_HUPPING, &tty->flags);
...@@ -667,7 +666,7 @@ void __tty_hangup(struct tty_struct *tty) ...@@ -667,7 +666,7 @@ void __tty_hangup(struct tty_struct *tty)
clear_bit(TTY_HUPPING, &tty->flags); clear_bit(TTY_HUPPING, &tty->flags);
tty_ldisc_enable(tty); tty_ldisc_enable(tty);
tty_unlock(tty); tty_unlock();
if (f) if (f)
fput(f); fput(f);
...@@ -1104,12 +1103,12 @@ void tty_write_message(struct tty_struct *tty, char *msg) ...@@ -1104,12 +1103,12 @@ void tty_write_message(struct tty_struct *tty, char *msg)
{ {
if (tty) { if (tty) {
mutex_lock(&tty->atomic_write_lock); mutex_lock(&tty->atomic_write_lock);
tty_lock(tty); tty_lock();
if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
tty_unlock(tty); tty_unlock();
tty->ops->write(tty, msg, strlen(msg)); tty->ops->write(tty, msg, strlen(msg));
} else } else
tty_unlock(tty); tty_unlock();
tty_write_unlock(tty); tty_write_unlock(tty);
} }
return; return;
...@@ -1404,7 +1403,6 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) ...@@ -1404,7 +1403,6 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
} }
initialize_tty_struct(tty, driver, idx); initialize_tty_struct(tty, driver, idx);
tty_lock(tty);
retval = tty_driver_install_tty(driver, tty); retval = tty_driver_install_tty(driver, tty);
if (retval < 0) if (retval < 0)
goto err_deinit_tty; goto err_deinit_tty;
...@@ -1417,11 +1415,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) ...@@ -1417,11 +1415,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
retval = tty_ldisc_setup(tty, tty->link); retval = tty_ldisc_setup(tty, tty->link);
if (retval) if (retval)
goto err_release_tty; goto err_release_tty;
/* Return the tty locked so that it cannot vanish under the caller */
return tty; return tty;
err_deinit_tty: err_deinit_tty:
tty_unlock(tty);
deinitialize_tty_struct(tty); deinitialize_tty_struct(tty);
free_tty_struct(tty); free_tty_struct(tty);
err_module_put: err_module_put:
...@@ -1430,7 +1426,6 @@ err_module_put: ...@@ -1430,7 +1426,6 @@ err_module_put:
/* call the tty release_tty routine to clean out this slot */ /* call the tty release_tty routine to clean out this slot */
err_release_tty: err_release_tty:
tty_unlock(tty);
printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, "
"clearing slot %d\n", idx); "clearing slot %d\n", idx);
release_tty(tty, idx); release_tty(tty, idx);
...@@ -1633,7 +1628,7 @@ int tty_release(struct inode *inode, struct file *filp) ...@@ -1633,7 +1628,7 @@ int tty_release(struct inode *inode, struct file *filp)
if (tty_paranoia_check(tty, inode, __func__)) if (tty_paranoia_check(tty, inode, __func__))
return 0; return 0;
tty_lock(tty); tty_lock();
check_tty_count(tty, __func__); check_tty_count(tty, __func__);
__tty_fasync(-1, filp, 0); __tty_fasync(-1, filp, 0);
...@@ -1642,11 +1637,10 @@ int tty_release(struct inode *inode, struct file *filp) ...@@ -1642,11 +1637,10 @@ int tty_release(struct inode *inode, struct file *filp)
pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
tty->driver->subtype == PTY_TYPE_MASTER); tty->driver->subtype == PTY_TYPE_MASTER);
devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0;
/* Review: parallel close */
o_tty = tty->link; o_tty = tty->link;
if (tty_release_checks(tty, o_tty, idx)) { if (tty_release_checks(tty, o_tty, idx)) {
tty_unlock(tty); tty_unlock();
return 0; return 0;
} }
...@@ -1658,7 +1652,7 @@ int tty_release(struct inode *inode, struct file *filp) ...@@ -1658,7 +1652,7 @@ int tty_release(struct inode *inode, struct file *filp)
if (tty->ops->close) if (tty->ops->close)
tty->ops->close(tty, filp); tty->ops->close(tty, filp);
tty_unlock(tty); tty_unlock();
/* /*
* Sanity check: if tty->count is going to zero, there shouldn't be * Sanity check: if tty->count is going to zero, there shouldn't be
* any waiters on tty->read_wait or tty->write_wait. We test the * any waiters on tty->read_wait or tty->write_wait. We test the
...@@ -1681,7 +1675,7 @@ int tty_release(struct inode *inode, struct file *filp) ...@@ -1681,7 +1675,7 @@ int tty_release(struct inode *inode, struct file *filp)
opens on /dev/tty */ opens on /dev/tty */
mutex_lock(&tty_mutex); mutex_lock(&tty_mutex);
tty_lock_pair(tty, o_tty); tty_lock();
tty_closing = tty->count <= 1; tty_closing = tty->count <= 1;
o_tty_closing = o_tty && o_tty_closing = o_tty &&
(o_tty->count <= (pty_master ? 1 : 0)); (o_tty->count <= (pty_master ? 1 : 0));
...@@ -1712,7 +1706,7 @@ int tty_release(struct inode *inode, struct file *filp) ...@@ -1712,7 +1706,7 @@ int tty_release(struct inode *inode, struct file *filp)
printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", printk(KERN_WARNING "%s: %s: read/write wait queue active!\n",
__func__, tty_name(tty, buf)); __func__, tty_name(tty, buf));
tty_unlock_pair(tty, o_tty); tty_unlock();
mutex_unlock(&tty_mutex); mutex_unlock(&tty_mutex);
schedule(); schedule();
} }
...@@ -1775,7 +1769,7 @@ int tty_release(struct inode *inode, struct file *filp) ...@@ -1775,7 +1769,7 @@ int tty_release(struct inode *inode, struct file *filp)
/* check whether both sides are closing ... */ /* check whether both sides are closing ... */
if (!tty_closing || (o_tty && !o_tty_closing)) { if (!tty_closing || (o_tty && !o_tty_closing)) {
tty_unlock_pair(tty, o_tty); tty_unlock();
return 0; return 0;
} }
...@@ -1788,16 +1782,14 @@ int tty_release(struct inode *inode, struct file *filp) ...@@ -1788,16 +1782,14 @@ int tty_release(struct inode *inode, struct file *filp)
tty_ldisc_release(tty, o_tty); tty_ldisc_release(tty, o_tty);
/* /*
* The release_tty function takes care of the details of clearing * The release_tty function takes care of the details of clearing
* the slots and preserving the termios structure. The tty_unlock_pair * the slots and preserving the termios structure.
* should be safe as we keep a kref while the tty is locked (so the
* unlock never unlocks a freed tty).
*/ */
release_tty(tty, idx); release_tty(tty, idx);
tty_unlock_pair(tty, o_tty);
/* Make this pty number available for reallocation */ /* Make this pty number available for reallocation */
if (devpts) if (devpts)
devpts_kill_index(inode, idx); devpts_kill_index(inode, idx);
tty_unlock();
return 0; return 0;
} }
...@@ -1901,9 +1893,6 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, ...@@ -1901,9 +1893,6 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
* Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev.
* tty->count should protect the rest. * tty->count should protect the rest.
* ->siglock protects ->signal/->sighand * ->siglock protects ->signal/->sighand
*
* Note: the tty_unlock/lock cases without a ref are only safe due to
* tty_mutex
*/ */
static int tty_open(struct inode *inode, struct file *filp) static int tty_open(struct inode *inode, struct file *filp)
...@@ -1927,7 +1916,8 @@ retry_open: ...@@ -1927,7 +1916,8 @@ retry_open:
retval = 0; retval = 0;
mutex_lock(&tty_mutex); mutex_lock(&tty_mutex);
/* This is protected by the tty_mutex */ tty_lock();
tty = tty_open_current_tty(device, filp); tty = tty_open_current_tty(device, filp);
if (IS_ERR(tty)) { if (IS_ERR(tty)) {
retval = PTR_ERR(tty); retval = PTR_ERR(tty);
...@@ -1948,19 +1938,17 @@ retry_open: ...@@ -1948,19 +1938,17 @@ retry_open:
} }
if (tty) { if (tty) {
tty_lock(tty);
retval = tty_reopen(tty); retval = tty_reopen(tty);
if (retval < 0) { if (retval)
tty_unlock(tty);
tty = ERR_PTR(retval); tty = ERR_PTR(retval);
}