Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

um: Use tty_port in SIGWINCH handler

The tty below tty_port might get destroyed by the tty layer
while we hold a reference to it.
So we have to carry tty_port around...

Signed-off-by: Richard Weinberger <richard@nod.at>

+22 -18
+1 -1
arch/um/drivers/chan.h
··· 37 37 extern int console_open_chan(struct line *line, struct console *co); 38 38 extern void deactivate_chan(struct chan *chan, int irq); 39 39 extern void reactivate_chan(struct chan *chan, int irq); 40 - extern void chan_enable_winch(struct chan *chan, struct tty_struct *tty); 40 + extern void chan_enable_winch(struct chan *chan, struct tty_port *port); 41 41 extern int enable_chan(struct line *line); 42 42 extern void close_chan(struct line *line); 43 43 extern int chan_window_size(struct line *line,
+2 -2
arch/um/drivers/chan_kern.c
··· 122 122 return err; 123 123 } 124 124 125 - void chan_enable_winch(struct chan *chan, struct tty_struct *tty) 125 + void chan_enable_winch(struct chan *chan, struct tty_port *port) 126 126 { 127 127 if (chan && chan->primary && chan->ops->winch) 128 - register_winch(chan->fd, tty); 128 + register_winch(chan->fd, port); 129 129 } 130 130 131 131 static void line_timer_cb(struct work_struct *work)
+6 -6
arch/um/drivers/chan_user.c
··· 216 216 } 217 217 } 218 218 219 - static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out, 219 + static int winch_tramp(int fd, struct tty_port *port, int *fd_out, 220 220 unsigned long *stack_out) 221 221 { 222 222 struct winch_data data; ··· 271 271 return err; 272 272 } 273 273 274 - void register_winch(int fd, struct tty_struct *tty) 274 + void register_winch(int fd, struct tty_port *port) 275 275 { 276 276 unsigned long stack; 277 277 int pid, thread, count, thread_fd = -1; ··· 281 281 return; 282 282 283 283 pid = tcgetpgrp(fd); 284 - if (is_skas_winch(pid, fd, tty)) { 285 - register_winch_irq(-1, fd, -1, tty, 0); 284 + if (is_skas_winch(pid, fd, port)) { 285 + register_winch_irq(-1, fd, -1, port, 0); 286 286 return; 287 287 } 288 288 289 289 if (pid == -1) { 290 - thread = winch_tramp(fd, tty, &thread_fd, &stack); 290 + thread = winch_tramp(fd, port, &thread_fd, &stack); 291 291 if (thread < 0) 292 292 return; 293 293 294 - register_winch_irq(thread_fd, fd, thread, tty, stack); 294 + register_winch_irq(thread_fd, fd, thread, port, stack); 295 295 296 296 count = write(thread_fd, &c, sizeof(c)); 297 297 if (count != sizeof(c))
+3 -3
arch/um/drivers/chan_user.h
··· 38 38 unsigned short *cols_out); 39 39 extern void generic_free(void *data); 40 40 41 - struct tty_struct; 42 - extern void register_winch(int fd, struct tty_struct *tty); 41 + struct tty_port; 42 + extern void register_winch(int fd, struct tty_port *port); 43 43 extern void register_winch_irq(int fd, int tty_fd, int pid, 44 - struct tty_struct *tty, unsigned long stack); 44 + struct tty_port *port, unsigned long stack); 45 45 46 46 #define __channel_help(fn, prefix) \ 47 47 __uml_help(fn, prefix "[0-9]*=<channel description>\n" \
+10 -6
arch/um/drivers/line.c
··· 305 305 return ret; 306 306 307 307 if (!line->sigio) { 308 - chan_enable_winch(line->chan_out, tty); 308 + chan_enable_winch(line->chan_out, port); 309 309 line->sigio = 1; 310 310 } 311 311 ··· 603 603 int fd; 604 604 int tty_fd; 605 605 int pid; 606 - struct tty_struct *tty; 606 + struct tty_port *port; 607 607 unsigned long stack; 608 608 struct work_struct work; 609 609 }; ··· 657 657 goto out; 658 658 } 659 659 } 660 - tty = winch->tty; 660 + tty = tty_port_tty_get(winch->port); 661 661 if (tty != NULL) { 662 662 line = tty->driver_data; 663 663 if (line != NULL) { ··· 665 665 &tty->winsize.ws_col); 666 666 kill_pgrp(tty->pgrp, SIGWINCH, 1); 667 667 } 668 + tty_kref_put(tty); 668 669 } 669 670 out: 670 671 if (winch->fd != -1) ··· 673 672 return IRQ_HANDLED; 674 673 } 675 674 676 - void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, 675 + void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port, 677 676 unsigned long stack) 678 677 { 679 678 struct winch *winch; ··· 688 687 .fd = fd, 689 688 .tty_fd = tty_fd, 690 689 .pid = pid, 691 - .tty = tty, 690 + .port = port, 692 691 .stack = stack }); 693 692 694 693 if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, ··· 717 716 { 718 717 struct list_head *ele, *next; 719 718 struct winch *winch; 719 + struct tty_struct *wtty; 720 720 721 721 spin_lock(&winch_handler_lock); 722 722 723 723 list_for_each_safe(ele, next, &winch_handlers) { 724 724 winch = list_entry(ele, struct winch, list); 725 - if (winch->tty == tty) { 725 + wtty = tty_port_tty_get(winch->port); 726 + if (wtty == tty) { 726 727 free_winch(winch); 727 728 break; 728 729 } 730 + tty_kref_put(wtty); 729 731 } 730 732 spin_unlock(&winch_handler_lock); 731 733 }