提交 934e6ebf 编写于 作者: A Alan Cox 提交者: Linus Torvalds

tty: Redo current tty locking

Currently it is sometimes locked by the tty mutex and sometimes by the
sighand lock. The latter is in fact correct and now we can hand back referenced
objects we can fix this up without problems around sleeping functions.
Signed-off-by: NAlan Cox <alan@redhat.com>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 2cb5998b
...@@ -739,13 +739,11 @@ void tty_vhangup_self(void) ...@@ -739,13 +739,11 @@ void tty_vhangup_self(void)
{ {
struct tty_struct *tty; struct tty_struct *tty;
mutex_lock(&tty_mutex);
tty = get_current_tty(); tty = get_current_tty();
if (tty) { if (tty) {
tty_vhangup(tty); tty_vhangup(tty);
tty_kref_put(tty); tty_kref_put(tty);
} }
mutex_unlock(&tty_mutex);
} }
/** /**
...@@ -801,11 +799,9 @@ void disassociate_ctty(int on_exit) ...@@ -801,11 +799,9 @@ void disassociate_ctty(int on_exit)
struct pid *tty_pgrp = NULL; struct pid *tty_pgrp = NULL;
mutex_lock(&tty_mutex);
tty = get_current_tty(); tty = get_current_tty();
if (tty) { if (tty) {
tty_pgrp = get_pid(tty->pgrp); tty_pgrp = get_pid(tty->pgrp);
mutex_unlock(&tty_mutex);
lock_kernel(); lock_kernel();
if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
tty_vhangup(tty); tty_vhangup(tty);
...@@ -822,7 +818,6 @@ void disassociate_ctty(int on_exit) ...@@ -822,7 +818,6 @@ void disassociate_ctty(int on_exit)
kill_pgrp(old_pgrp, SIGCONT, on_exit); kill_pgrp(old_pgrp, SIGCONT, on_exit);
put_pid(old_pgrp); put_pid(old_pgrp);
} }
mutex_unlock(&tty_mutex);
return; return;
} }
if (tty_pgrp) { if (tty_pgrp) {
...@@ -837,7 +832,6 @@ void disassociate_ctty(int on_exit) ...@@ -837,7 +832,6 @@ void disassociate_ctty(int on_exit)
current->signal->tty_old_pgrp = NULL; current->signal->tty_old_pgrp = NULL;
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&current->sighand->siglock);
mutex_lock(&tty_mutex);
tty = get_current_tty(); tty = get_current_tty();
if (tty) { if (tty) {
unsigned long flags; unsigned long flags;
...@@ -854,7 +848,6 @@ void disassociate_ctty(int on_exit) ...@@ -854,7 +848,6 @@ void disassociate_ctty(int on_exit)
" = NULL", tty); " = NULL", tty);
#endif #endif
} }
mutex_unlock(&tty_mutex);
/* Now clear signal->tty under the lock */ /* Now clear signal->tty under the lock */
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
...@@ -3180,14 +3173,11 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) ...@@ -3180,14 +3173,11 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
struct tty_struct *get_current_tty(void) struct tty_struct *get_current_tty(void)
{ {
struct tty_struct *tty; struct tty_struct *tty;
WARN_ON_ONCE(!mutex_is_locked(&tty_mutex)); unsigned long flags;
spin_lock_irqsave(&current->sighand->siglock, flags);
tty = tty_kref_get(current->signal->tty); tty = tty_kref_get(current->signal->tty);
/* spin_unlock_irqrestore(&current->sighand->siglock, flags);
* session->tty can be changed/cleared from under us, make sure we
* issue the load. The obtained pointer, when not NULL, is valid as
* long as we hold tty_mutex.
*/
barrier();
return tty; return tty;
} }
EXPORT_SYMBOL_GPL(get_current_tty); EXPORT_SYMBOL_GPL(get_current_tty);
......
...@@ -431,6 +431,7 @@ fs3270_open(struct inode *inode, struct file *filp) ...@@ -431,6 +431,7 @@ fs3270_open(struct inode *inode, struct file *filp)
tty = get_current_tty(); tty = get_current_tty();
if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) { if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) {
tty_kref_put(tty); tty_kref_put(tty);
mutex_unlock(&tty_mutex);
rc = -ENODEV; rc = -ENODEV;
goto out; goto out;
} }
......
...@@ -895,9 +895,7 @@ static void print_warning(struct dquot *dquot, const int warntype) ...@@ -895,9 +895,7 @@ static void print_warning(struct dquot *dquot, const int warntype)
warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot)) warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot))
return; return;
mutex_lock(&tty_mutex);
tty = get_current_tty(); tty = get_current_tty();
mutex_unlock(&tty_mutex);
if (!tty) if (!tty)
return; return;
tty_write_message(tty, dquot->dq_sb->s_id); tty_write_message(tty, dquot->dq_sb->s_id);
......
...@@ -2121,9 +2121,7 @@ static inline void flush_unauthorized_files(struct files_struct *files) ...@@ -2121,9 +2121,7 @@ static inline void flush_unauthorized_files(struct files_struct *files)
long j = -1; long j = -1;
int drop_tty = 0; int drop_tty = 0;
mutex_lock(&tty_mutex);
tty = get_current_tty(); tty = get_current_tty();
mutex_unlock(&tty_mutex);
if (tty) { if (tty) {
file_list_lock(); file_list_lock();
file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list); file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册