diff options
| author | Jiri Slaby <jslaby@suse.cz> | 2012-10-18 16:26:32 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-10-22 19:50:53 -0400 |
| commit | 7ee00fdb16418dd5078ec73e4a631c278a366501 (patch) | |
| tree | 5010d222fb5cc65c8f03d1e96bf2e25b130697f6 | |
| parent | fa2ecfc5a68d85624bbd84f7d010860776b7e602 (diff) | |
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>
| -rw-r--r-- | drivers/tty/vt/selection.c | 9 |
1 files changed, 2 insertions, 7 deletions
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index 8e9b4be97a2d..60b7b6926059 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c | |||
| @@ -341,15 +341,11 @@ int paste_selection(struct tty_struct *tty) | |||
| 341 | struct tty_ldisc *ld; | 341 | struct tty_ldisc *ld; |
| 342 | DECLARE_WAITQUEUE(wait, current); | 342 | DECLARE_WAITQUEUE(wait, current); |
| 343 | 343 | ||
| 344 | |||
| 345 | console_lock(); | 344 | console_lock(); |
| 346 | poke_blanked_console(); | 345 | poke_blanked_console(); |
| 347 | console_unlock(); | 346 | console_unlock(); |
| 348 | 347 | ||
| 349 | /* FIXME: wtf is this supposed to achieve ? */ | 348 | ld = tty_ldisc_ref_wait(tty); |
| 350 | ld = tty_ldisc_ref(tty); | ||
| 351 | if (!ld) | ||
| 352 | ld = tty_ldisc_ref_wait(tty); | ||
| 353 | 349 | ||
| 354 | /* FIXME: this is completely unsafe */ | 350 | /* FIXME: this is completely unsafe */ |
| 355 | add_wait_queue(&vc->paste_wait, &wait); | 351 | add_wait_queue(&vc->paste_wait, &wait); |
| @@ -361,8 +357,7 @@ int paste_selection(struct tty_struct *tty) | |||
| 361 | } | 357 | } |
| 362 | count = sel_buffer_lth - pasted; | 358 | count = sel_buffer_lth - pasted; |
| 363 | count = min(count, tty->receive_room); | 359 | count = min(count, tty->receive_room); |
| 364 | tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, | 360 | ld->ops->receive_buf(tty, sel_buffer + pasted, NULL, count); |
| 365 | NULL, count); | ||
| 366 | pasted += count; | 361 | pasted += count; |
| 367 | } | 362 | } |
| 368 | remove_wait_queue(&vc->paste_wait, &wait); | 363 | remove_wait_queue(&vc->paste_wait, &wait); |
