diff options
| author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2012-08-09 08:31:00 -0400 |
|---|---|---|
| committer | Rusty Russell <rusty@rustcorp.com.au> | 2012-09-28 01:35:12 -0400 |
| commit | efe75d24a69fc39bb09d882ca2d5b90d4da02afe (patch) | |
| tree | 03424fc85d6ca93ca6522dd1f6b11efd52252191 | |
| parent | ec8fc870156b2b144f55b6a5a7d135018f04b30e (diff) | |
virtio/console: Wait until the port is ready on splice
Wait if the port is not connected or full on splice
like as write is doing.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Acked-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
| -rw-r--r-- | drivers/char/virtio_console.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 22b737353017..b2fc2abedc79 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
| @@ -724,6 +724,26 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf, | |||
| 724 | return fill_readbuf(port, ubuf, count, true); | 724 | return fill_readbuf(port, ubuf, count, true); |
| 725 | } | 725 | } |
| 726 | 726 | ||
| 727 | static int wait_port_writable(struct port *port, bool nonblock) | ||
| 728 | { | ||
| 729 | int ret; | ||
| 730 | |||
| 731 | if (will_write_block(port)) { | ||
| 732 | if (nonblock) | ||
| 733 | return -EAGAIN; | ||
| 734 | |||
| 735 | ret = wait_event_freezable(port->waitqueue, | ||
| 736 | !will_write_block(port)); | ||
| 737 | if (ret < 0) | ||
| 738 | return ret; | ||
| 739 | } | ||
| 740 | /* Port got hot-unplugged. */ | ||
| 741 | if (!port->guest_connected) | ||
| 742 | return -ENODEV; | ||
| 743 | |||
| 744 | return 0; | ||
| 745 | } | ||
| 746 | |||
| 727 | static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, | 747 | static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, |
| 728 | size_t count, loff_t *offp) | 748 | size_t count, loff_t *offp) |
| 729 | { | 749 | { |
| @@ -740,18 +760,9 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, | |||
| 740 | 760 | ||
| 741 | nonblock = filp->f_flags & O_NONBLOCK; | 761 | nonblock = filp->f_flags & O_NONBLOCK; |
| 742 | 762 | ||
| 743 | if (will_write_block(port)) { | 763 | ret = wait_port_writable(port, nonblock); |
| 744 | if (nonblock) | 764 | if (ret < 0) |
| 745 | return -EAGAIN; | 765 | return ret; |
| 746 | |||
| 747 | ret = wait_event_freezable(port->waitqueue, | ||
| 748 | !will_write_block(port)); | ||
| 749 | if (ret < 0) | ||
| 750 | return ret; | ||
| 751 | } | ||
| 752 | /* Port got hot-unplugged. */ | ||
| 753 | if (!port->guest_connected) | ||
| 754 | return -ENODEV; | ||
| 755 | 766 | ||
| 756 | count = min((size_t)(32 * 1024), count); | 767 | count = min((size_t)(32 * 1024), count); |
| 757 | 768 | ||
| @@ -851,6 +862,10 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe, | |||
| 851 | .u.data = &sgl, | 862 | .u.data = &sgl, |
| 852 | }; | 863 | }; |
| 853 | 864 | ||
| 865 | ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK); | ||
| 866 | if (ret < 0) | ||
| 867 | return ret; | ||
| 868 | |||
| 854 | sgl.n = 0; | 869 | sgl.n = 0; |
| 855 | sgl.len = 0; | 870 | sgl.len = 0; |
| 856 | sgl.sg = kmalloc(sizeof(struct scatterlist) * MAX_SPLICE_PAGES, | 871 | sgl.sg = kmalloc(sizeof(struct scatterlist) * MAX_SPLICE_PAGES, |
