TTY: vt, fix paste_selection ldisc handling

There used to be a single tty_ldisc_ref_wait. But then, when a
big-tty-mutex (BTM) was introduced, it has to be tty_ldisc_ref +
tty_unlock + tty_ldisc_ref_wait + tty_lock. Later, BTM was removed
from that path and tty_ldisc_ref + tty_ldisc_ref_wait remained there.
But it makes no sense now. So leave there only tty_ldisc_ref_wait.

And when we have a reference to an ldisc, actually use it in the loop.
Otherwise it may be racy.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Acked-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Jiri Slaby 2012-10-18 22:26:32 +02:00 committed by Greg Kroah-Hartman
parent fa2ecfc5a6
commit 7ee00fdb16

View file

@ -341,15 +341,11 @@ int paste_selection(struct tty_struct *tty)
struct tty_ldisc *ld;
DECLARE_WAITQUEUE(wait, current);
console_lock();
poke_blanked_console();
console_unlock();
/* FIXME: wtf is this supposed to achieve ? */
ld = tty_ldisc_ref(tty);
if (!ld)
ld = tty_ldisc_ref_wait(tty);
ld = tty_ldisc_ref_wait(tty);
/* FIXME: this is completely unsafe */
add_wait_queue(&vc->paste_wait, &wait);
@ -361,8 +357,7 @@ int paste_selection(struct tty_struct *tty)
}
count = sel_buffer_lth - pasted;
count = min(count, tty->receive_room);
tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
NULL, count);
ld->ops->receive_buf(tty, sel_buffer + pasted, NULL, count);
pasted += count;
}
remove_wait_queue(&vc->paste_wait, &wait);