View | Details | Raw Unified | Return to bug 15235
Collapse All | Expand All

(-)sys_pipe.c (-23 / +64 lines)
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.

Return to bug 15235