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 /drivers/char | |
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>
Diffstat (limited to 'drivers/char')
-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, |