[Dovecot] Misbehavior with Dovecot and Mulberry

Jon Roma roma at uiuc.edu
Tue Sep 27 06:25:55 EEST 2005



Kenneth Porter <shiva at sewingwitch.com> wrote:

> --On Monday, September 26, 2005 7:58 PM -0500 Jon Roma <roma at uiuc.edu>
> wrote:
>
>> The Linux man page for writev(2) says that the vector count must be
>> between 0 and MAX_IOVEC.  MAX_IOVEC is defined as 10 in
>> <linux/sunrpc/xprt.h>, which doesn't seem a logical place for it.
>> Anyway, on RHEL 3, UIO_MAXIOV is defined in <linux/uio.h> and
>> <bits/uio.h> and IOV_MAX is defined in <bits/stdio_lim.h> -- and is
>> defined as 1024 in these definitions.  There's also a _POSIX_UIO_MAXIOV
>> defined at 16 in <bits/posix1_lim.h>.
>>
>> My suspicion is that the Linux man page is wrong with respect to the
>> preprocessor variable that matters.
>
> I poked around in glibc and kernel sources (FC2) and found UIO_MAXIOV and
> IOV_MAX are the two symbols in use and are set to 1024. Googling for
> these two symbols together turned up this interesting nugget:
>
> <http://lists.freebsd.org/pipermail/freebsd-standards/2004-February/00039
> 9.html>
>
> The search:
>
> <http://www.google.com/search?num=100&hl=en&lr=&safe=off&c2coff=1&q=uio_m
> axiov+iov_max&btnG=Search>
>
> The glibc code looks like in some circumstances it mallocs a temporary
> buffer to assemble the write and then issues a write() on the temporary.
> Additionally, each filesystem driver gets a chance to independently
> choose how to implement writev, with many passing it to a generic version
> of the function.

Kenneth:

Thank you for providing that bit of information, which helps clear things
up a bit.  Though I'm a long-time UNIX guy, I've not got that much in
the way of experience with Linux and the modern *BSD flavors.  So this
helps me get the feeling that I was on the right track.

Timo:

I found eight references to UIO_MAXIOV in src/lib/ostream-file.c and
changed all to IOV_MAX.  I cleaned, rebuilt, and installed -- happily,
the previously-reported EINVAL errors are now gone!

Trivial patch attached.


-------------- next part --------------
Index: src/lib/ostream-file.c===================================================================--- src/lib/ostream-file.c	(revision 2865)+++ src/lib/ostream-file.c	(working copy)@@ -17,8 +17,8 @@ #  include <sys/uio.h> #endif -#ifndef UIO_MAXIOV-#  define UIO_MAXIOV 16+#ifndef IOV_MAX+#  define IOV_MAX 16 #endif  /* try to keep the buffer size within 4k..128k. ReiserFS may actually return@@ -137,22 +137,22 @@ 		ret = write(fstream->fd, iov->iov_base, iov->iov_len); 	else { 		sent = 0;-		while (iov_size > UIO_MAXIOV) {+		while (iov_size > IOV_MAX) { 			size = 0;-			for (i = 0; i < UIO_MAXIOV; i++)+			for (i = 0; i < IOV_MAX; i++) 				size += iov[i].iov_len;  			ret = writev(fstream->fd, (const struct iovec *)iov,-				     UIO_MAXIOV);+				     IOV_MAX); 			if (ret != (ssize_t)size) 				break;  			sent += ret;-			iov += UIO_MAXIOV;-			iov_size -= UIO_MAXIOV;+			iov += IOV_MAX;+			iov_size -= IOV_MAX; 		} -		if (iov_size <= UIO_MAXIOV) {+		if (iov_size <= IOV_MAX) { 			ret = writev(fstream->fd, (const struct iovec *)iov, 				     iov_size); 		}


More information about the dovecot mailing list