tty: Redo current tty locking
authorAlan Cox <alan@redhat.com>
Mon, 13 Oct 2008 09:40:43 +0000 (10:40 +0100)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 Oct 2008 16:51:41 +0000 (09:51 -0700)
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: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/char/tty_io.c
drivers/s390/char/fs3270.c
fs/dquot.c
security/selinux/hooks.c

index b5f57d0b30ee1bdb5e931825010c59ab0b2627a2..f40298e9873a0f274a8563181efa394d0e04bf50 100644 (file)
@@ -739,13 +739,11 @@ void tty_vhangup_self(void)
 {
        struct tty_struct *tty;
 
-       mutex_lock(&tty_mutex);
        tty = get_current_tty();
        if (tty) {
                tty_vhangup(tty);
                tty_kref_put(tty);
        }
-       mutex_unlock(&tty_mutex);
 }
 
 /**
@@ -801,11 +799,9 @@ void disassociate_ctty(int on_exit)
        struct pid *tty_pgrp = NULL;
 
 
-       mutex_lock(&tty_mutex);
        tty = get_current_tty();
        if (tty) {
                tty_pgrp = get_pid(tty->pgrp);
-               mutex_unlock(&tty_mutex);
                lock_kernel();
                if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
                        tty_vhangup(tty);
@@ -822,7 +818,6 @@ void disassociate_ctty(int on_exit)
                        kill_pgrp(old_pgrp, SIGCONT, on_exit);
                        put_pid(old_pgrp);
                }
-               mutex_unlock(&tty_mutex);
                return;
        }
        if (tty_pgrp) {
@@ -837,7 +832,6 @@ void disassociate_ctty(int on_exit)
        current->signal->tty_old_pgrp = NULL;
        spin_unlock_irq(&current->sighand->siglock);
 
-       mutex_lock(&tty_mutex);
        tty = get_current_tty();
        if (tty) {
                unsigned long flags;
@@ -854,7 +848,6 @@ void disassociate_ctty(int on_exit)
                       " = NULL", tty);
 #endif
        }
-       mutex_unlock(&tty_mutex);
 
        /* Now clear signal->tty under the lock */
        read_lock(&tasklist_lock);
@@ -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 *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);
-       /*
-        * 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();
+       spin_unlock_irqrestore(&current->sighand->siglock, flags);
        return tty;
 }
 EXPORT_SYMBOL_GPL(get_current_tty);
index 3ef5425d0eb834063f46f0714828ba5461f4694d..84fbc90480dcb858f310b6fdfab4403a110e4ca3 100644 (file)
@@ -431,6 +431,7 @@ fs3270_open(struct inode *inode, struct file *filp)
                tty = get_current_tty();
                if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) {
                        tty_kref_put(tty);
+                       mutex_unlock(&tty_mutex);
                        rc = -ENODEV;
                        goto out;
                }
index 7417a6ca3129993b316456acd364e17a1102ee02..ad7e59003e0445943d21f8b9f78090f7b9e19b53 100644 (file)
@@ -895,9 +895,7 @@ static void print_warning(struct dquot *dquot, const int warntype)
            warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot))
                return;
 
-       mutex_lock(&tty_mutex);
        tty = get_current_tty();
-       mutex_unlock(&tty_mutex);
        if (!tty)
                return;
        tty_write_message(tty, dquot->dq_sb->s_id);
index 089d61a239523419efdba9861e0b583a62c6b706..48881394fbd401a356d4e313ea19473132c1c187 100644 (file)
@@ -2121,9 +2121,7 @@ static inline void flush_unauthorized_files(struct files_struct *files)
        long j = -1;
        int drop_tty = 0;
 
-       mutex_lock(&tty_mutex);
        tty = get_current_tty();
-       mutex_unlock(&tty_mutex);
        if (tty) {
                file_list_lock();
                file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list);