[dovecot-cvs] dovecot/src/lib istream-mmap.c,1.3,1.4 ostream-file.c,1.8,1.9 sendfile-util.c,1.4,1.5 sendfile-util.h,1.1,1.2

cras at procontrol.fi cras at procontrol.fi
Tue Feb 11 18:37:49 EET 2003


Update of /home/cvs/dovecot/src/lib
In directory danu:/tmp/cvs-serv8682

Modified Files:
	istream-mmap.c ostream-file.c sendfile-util.c sendfile-util.h 
Log Message:
Bugfixes to handling >2GB files.



Index: istream-mmap.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/istream-mmap.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- istream-mmap.c	11 Jan 2003 19:55:56 -0000	1.3
+++ istream-mmap.c	11 Feb 2003 16:37:47 -0000	1.4
@@ -94,14 +94,14 @@
 static ssize_t io_stream_set_mmaped_pos(struct _istream *stream)
 {
 	struct mmap_istream *mstream = (struct mmap_istream *) stream;
+	uoff_t top;
 
 	i_assert((uoff_t)mstream->mmap_offset <=
 		 stream->istream.start_offset + stream->istream.v_limit);
 
-	stream->pos = stream->istream.start_offset + stream->istream.v_limit -
+	top = stream->istream.start_offset + stream->istream.v_limit -
 		mstream->mmap_offset;
-	if (stream->pos > stream->buffer_size)
-		stream->pos = stream->buffer_size;
+	stream->pos = I_MIN(top, stream->buffer_size);
 
 	return stream->pos - stream->skip;
 }
@@ -110,6 +110,7 @@
 {
 	struct mmap_istream *mstream = (struct mmap_istream *) stream;
 	size_t aligned_skip, limit_size;
+	uoff_t top;
 
 	if (stream->istream.start_offset + stream->istream.v_limit <=
 	    (uoff_t)mstream->mmap_offset + stream->pos) {
@@ -137,10 +138,9 @@
 			i_error("io_stream_read_mmaped(): munmap() failed: %m");
 	}
 
-	stream->buffer_size = stream->istream.start_offset +
-		stream->istream.v_size - mstream->mmap_offset;
-	if (stream->buffer_size > mstream->mmap_block_size)
-		stream->buffer_size = mstream->mmap_block_size;
+	top = stream->istream.start_offset + stream->istream.v_size -
+		mstream->mmap_offset;
+	stream->buffer_size = I_MIN(top, mstream->mmap_block_size);
 
 	i_assert((uoff_t)mstream->mmap_offset + stream->buffer_size <=
 		 stream->istream.start_offset + stream->istream.v_size);

Index: ostream-file.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/ostream-file.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- ostream-file.c	8 Feb 2003 13:53:07 -0000	1.8
+++ ostream-file.c	11 Feb 2003 16:37:47 -0000	1.9
@@ -203,7 +203,11 @@
 
 	i_assert(iov_size > 0);
 
-	ret = writev(fstream->fd, iov, iov_size);
+	if (iov_size == 1)
+		ret = write(fstream->fd, iov->iov_base, iov->iov_len);
+	else
+		ret = writev(fstream->fd, iov, iov_size);
+
 	if (ret < 0) {
 		if (errno == EAGAIN || errno == EINTR)
 			return 0;
@@ -501,13 +505,13 @@
 	}
 }
 
-static off_t io_stream_sendfile(struct _ostream *outstream,
-				struct istream *instream)
+static int io_stream_sendfile(struct _ostream *outstream,
+			      struct istream *instream)
 {
 	struct file_ostream *foutstream = (struct file_ostream *) outstream;
 	time_t timeout_time;
 	uoff_t start_offset;
-	uoff_t offset, send_size;
+	uoff_t offset, send_size, v_offset;
 	ssize_t ret;
 	int in_fd, first;
 
@@ -525,8 +529,10 @@
 	if (buffer_flush(foutstream) < 0)
 		return -1;
 
+	v_offset = instream->v_offset;
+
 	first = TRUE;
-	for (;;) {
+	do {
 		if (first)
 			first = FALSE;
 		else if (timeout_time > 0 && time(NULL) > timeout_time) {
@@ -536,11 +542,12 @@
 					foutstream->timeout_context);
 			}
 			outstream->ostream.stream_errno = EAGAIN;
-			return -1;
+			ret = -1;
+			break;
 		}
 
-		offset = instream->start_offset + instream->v_offset;
-		send_size = instream->v_limit - instream->v_offset;
+		offset = instream->start_offset + v_offset;
+		send_size = instream->v_limit - v_offset;
 
 		ret = safe_sendfile(foutstream->fd, in_fd, &offset,
 				    MAX_SSIZE_T(send_size));
@@ -552,26 +559,22 @@
 					   sendfile() isn't supported */
 					stream_closed(foutstream);
 				}
-				return -1;
+				break;
 			}
 
+			ret = 0;
 			if (!STREAM_IS_BLOCKING(foutstream)) {
 				/* don't block */
 				break;
 			}
-			ret = 0;
 		}
 
-		i_stream_skip(instream, (size_t)ret);
+		v_offset += ret;
 		outstream->ostream.offset += ret;
+	} while ((uoff_t)ret != send_size);
 
-		if ((uoff_t)ret == send_size) {
-			/* yes, all sent */
-			break;
-		}
-	}
-
-	return (off_t) (instream->v_offset - start_offset);
+	i_stream_seek(instream, instream->start_offset + v_offset);
+	return ret < 0 ? -1 : 0;
 }
 
 static off_t io_stream_copy(struct _ostream *outstream,
@@ -605,7 +608,7 @@
 		iov[pos].iov_len = size;
 
 		ret = o_stream_writev(foutstream, iov, iov_len);
-		if (ret < 0) {
+ 		if (ret < 0) {
 			/* error */
 			return -1;
 		}
@@ -648,6 +651,8 @@
 	i_assert(instream->v_limit <= OFF_T_MAX);
 	i_assert(instream->v_offset <= instream->v_limit);
 
+	outstream->ostream.stream_errno = 0;
+
 	if (instream->v_offset == instream->v_limit)
 		return 0;
 
@@ -657,7 +662,7 @@
 			return ret;
 
 		/* sendfile() not supported (with this fd), fallback to
-		   regular sending */
+		   regular sending. */
 		outstream->ostream.stream_errno = 0;
 		foutstream->no_sendfile = TRUE;
 	}

Index: sendfile-util.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/sendfile-util.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- sendfile-util.c	8 Feb 2003 13:52:51 -0000	1.4
+++ sendfile-util.c	11 Feb 2003 16:37:47 -0000	1.5
@@ -23,19 +23,23 @@
 	/* make sure given offset fits into off_t */
 	if (sizeof(off_t) * CHAR_BIT == 32) {
 		/* 32bit off_t */
-		if (*offset > 2147483647L) {
-			errno = EOVERFLOW;
+		if (*offset >= 2147483647L) {
+			errno = EINVAL;
 			return -1;
 		}
+		if (count > 2147483647L - *offset)
+			count = 2147483647L - *offset;
 	} else {
 		/* they're most likely the same size. if not, fix this
 		   code later */
 		i_assert(sizeof(off_t) == sizeof(uoff_t));
 
-		if (*offset > OFF_T_MAX) {
-			errno = EOVERFLOW;
+		if (*offset >= OFF_T_MAX) {
+			errno = EINVAL;
 			return -1;
 		}
+		if (count > OFF_T_MAX - *offset)
+			count = OFF_T_MAX - *offset;
 	}
 
 	safe_offset = (off_t)*offset;

Index: sendfile-util.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib/sendfile-util.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- sendfile-util.h	28 Aug 2002 00:11:51 -0000	1.1
+++ sendfile-util.h	11 Feb 2003 16:37:47 -0000	1.2
@@ -1,7 +1,9 @@
 #ifndef __SENDFILE_UTIL_H
 #define __SENDFILE_UTIL_H
 
-/* simple wrapper for sendfile(), allowing usage of 64bit off_t with it */
+/* Wrapper for various sendfile()-like calls. Returns -1 and errno=EINVAL if
+   it isn't supported for some reason (out_fd isn't a socket, offset is too
+   large, or there simply is no sendfile()). */
 ssize_t safe_sendfile(int out_fd, int in_fd, uoff_t *offset, size_t count);
 
 #endif




More information about the dovecot-cvs mailing list