|
Lines 799-825
Link Here
|
| 799 |
space = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt; |
799 |
space = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt; |
| 800 |
|
800 |
|
| 801 |
/* Writes of size <= PIPE_BUF must be atomic. */ |
801 |
/* Writes of size <= PIPE_BUF must be atomic. */ |
| 802 |
/* XXX perhaps they need to be contiguous to be atomic? */ |
|
|
| 803 |
if ((space < uio->uio_resid) && (orig_resid <= PIPE_BUF)) |
802 |
if ((space < uio->uio_resid) && (orig_resid <= PIPE_BUF)) |
| 804 |
space = 0; |
803 |
space = 0; |
| 805 |
|
804 |
|
| 806 |
if (space > 0 && (wpipe->pipe_buffer.cnt < PIPE_SIZE)) { |
805 |
if (space > 0 && (wpipe->pipe_buffer.cnt < PIPE_SIZE)) { |
| 807 |
/* |
|
|
| 808 |
* This set the maximum transfer as a segment of |
| 809 |
* the buffer. |
| 810 |
*/ |
| 811 |
int size = wpipe->pipe_buffer.size - wpipe->pipe_buffer.in; |
| 812 |
/* |
| 813 |
* space is the size left in the buffer |
| 814 |
*/ |
| 815 |
if (size > space) |
| 816 |
size = space; |
| 817 |
/* |
| 818 |
* now limit it to the size of the uio transfer |
| 819 |
*/ |
| 820 |
if (size > uio->uio_resid) |
| 821 |
size = uio->uio_resid; |
| 822 |
if ((error = pipelock(wpipe,1)) == 0) { |
806 |
if ((error = pipelock(wpipe,1)) == 0) { |
|
|
807 |
int size; /* Transfer size */ |
| 808 |
int segsize; /* first segment to transfer */ |
| 823 |
/* |
809 |
/* |
| 824 |
* It is possible for a direct write to |
810 |
* It is possible for a direct write to |
| 825 |
* slip in on us... handle it here... |
811 |
* slip in on us... handle it here... |
|
Lines 828-845
Link Here
|
| 828 |
pipeunlock(wpipe); |
814 |
pipeunlock(wpipe); |
| 829 |
goto retrywrite; |
815 |
goto retrywrite; |
| 830 |
} |
816 |
} |
| 831 |
error = uiomove( &wpipe->pipe_buffer.buffer[wpipe->pipe_buffer.in], |
817 |
/* |
| 832 |
size, uio); |
818 |
* If a process blocked in uiomove, our |
|
|
819 |
* value for space might be bad. |
| 820 |
*/ |
| 821 |
if (space > wpipe->pipe_buffer.size - |
| 822 |
wpipe->pipe_buffer.cnt) { |
| 823 |
pipeunlock(wpipe); |
| 824 |
goto retrywrite; |
| 825 |
} |
| 826 |
|
| 827 |
/* |
| 828 |
* Transfer size is minimum of uio transfer |
| 829 |
* and free space in pipe buffer. |
| 830 |
*/ |
| 831 |
if (space > uio->uio_resid) |
| 832 |
size = uio->uio_resid; |
| 833 |
else |
| 834 |
size = space; |
| 835 |
/* |
| 836 |
* First segment to transfer is minimum of |
| 837 |
* transfer size and contiguous space in |
| 838 |
* pipe buffer. If first segment to transfer |
| 839 |
* is less than the transfer size, we've got |
| 840 |
* a wraparound in the buffer. |
| 841 |
*/ |
| 842 |
segsize = wpipe->pipe_buffer.size - |
| 843 |
wpipe->pipe_buffer.in; |
| 844 |
if (segsize > size) |
| 845 |
segsize = size; |
| 846 |
|
| 847 |
/* Transfer first segment */ |
| 848 |
|
| 849 |
error = uiomove(&wpipe->pipe_buffer.buffer[wpipe->pipe_buffer.in], |
| 850 |
segsize, uio); |
| 851 |
|
| 852 |
if (error == 0 && segsize < size) { |
| 853 |
/* |
| 854 |
* Transfer remaining part now, to |
| 855 |
* support atomic writes. Wraparound |
| 856 |
* happened. |
| 857 |
*/ |
| 858 |
if (wpipe->pipe_buffer.in + segsize != |
| 859 |
wpipe->pipe_buffer.size) |
| 860 |
panic("Expected pipe buffer wraparound disappeared"); |
| 861 |
|
| 862 |
error = uiomove(&wpipe->pipe_buffer.buffer[0], |
| 863 |
size - segsize, uio); |
| 864 |
} |
| 865 |
if (error == 0) { |
| 866 |
wpipe->pipe_buffer.in += size; |
| 867 |
if (wpipe->pipe_buffer.in >= |
| 868 |
wpipe->pipe_buffer.size) { |
| 869 |
if (wpipe->pipe_buffer.in != size - segsize + wpipe->pipe_buffer.size) |
| 870 |
panic("Expected wraparound bad"); |
| 871 |
wpipe->pipe_buffer.in = size - segsize; |
| 872 |
} |
| 873 |
|
| 874 |
wpipe->pipe_buffer.cnt += size; |
| 875 |
if (wpipe->pipe_buffer.cnt > wpipe->pipe_buffer.size) |
| 876 |
panic("Pipe buffer overflow"); |
| 877 |
|
| 878 |
} |
| 833 |
pipeunlock(wpipe); |
879 |
pipeunlock(wpipe); |
| 834 |
} |
880 |
} |
| 835 |
if (error) |
881 |
if (error) |
| 836 |
break; |
882 |
break; |
| 837 |
|
883 |
|
| 838 |
wpipe->pipe_buffer.in += size; |
|
|
| 839 |
if (wpipe->pipe_buffer.in >= wpipe->pipe_buffer.size) |
| 840 |
wpipe->pipe_buffer.in = 0; |
| 841 |
|
| 842 |
wpipe->pipe_buffer.cnt += size; |
| 843 |
} else { |
884 |
} else { |
| 844 |
/* |
885 |
/* |
| 845 |
* If the "read-side" has been blocked, wake it up now. |
886 |
* If the "read-side" has been blocked, wake it up now. |