diff --git a/Makerules b/Makerules
index 2000e543a1..166f0ab9dc 100644
--- a/Makerules
+++ b/Makerules
@@ -1504,8 +1504,7 @@ $(stdio_lim:h=st): $(..)stdio-common/stdio_lim.h.in $(..)Rules \
 		   $(common-objpfx)config.make
 	$(make-target-directory)
 	{ echo '#include "$(..)posix/bits/posix1_lim.h"';		\
-	  echo '#define _LIBC 1';					\
-	  echo '#include "$(..)misc/sys/uio.h"'; } |			\
+	} |								\
 	$(CC) -E -dM -MD -MP -MF $(@:st=dT) -MT '$(@:st=h) $(@:st=d)' 	\
 	      $(CPPUNDEFS) $(+includes) -xc - -o $(@:st=hT)
 	sed $(sed-remove-objpfx) $(sed-remove-dotdot)			\
@@ -1513,21 +1512,14 @@ $(stdio_lim:h=st): $(..)stdio-common/stdio_lim.h.in $(..)Rules \
 	mv -f $(@:st=dt) $(@:st=d)
 	fopen_max=`sed -n 's/^#define OPEN_MAX //1p' $(@:st=hT)`; 	\
 	filename_max=`sed -n 's/^#define PATH_MAX //1p' $(@:st=hT)`;	\
-	iov_max=`sed -n 's/^#define UIO_MAXIOV //p' $(@:st=hT)`;	\
 	fopen_max=$${fopen_max:-16};					\
 	filename_max=$${filename_max:-1024};				\
-	if [ -z "$$iov_max" ]; then					\
-	  define_iov_max="# undef IOV_MAX";				\
-	else								\
-	  define_iov_max="# define IOV_MAX $$iov_max";			\
-	fi;								\
 	sed -e "s/@FOPEN_MAX@/$$fopen_max/"				\
 	    -e "s/@FILENAME_MAX@/$$filename_max/"			\
 	    -e "s/@L_tmpnam@/$(L_tmpnam)/"				\
 	    -e "s/@TMP_MAX@/$(TMP_MAX)/"				\
 	    -e "s/@L_ctermid@/$(L_ctermid)/"				\
 	    -e "s/@L_cuserid@/$(L_cuserid)/"				\
-	    -e "s/@define_IOV_MAX@/$$define_iov_max/"			\
 	    $< > $(@:st=h.new)
 	$(move-if-change) $(@:st=h.new) $(@:st=h)
 # Remove these last so that they can be examined if something went wrong.
diff --git a/bits/uio.h b/bits/uio_lim.h
similarity index 79%
rename from bits/uio.h
rename to bits/uio_lim.h
index 96a3a71d42..f6919f093c 100644
--- a/bits/uio.h
+++ b/bits/uio_lim.h
@@ -15,9 +15,11 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifndef _SYS_UIO_H
-# error "Never include <bits/uio.h> directly; use <sys/uio.h> instead."
+#ifndef _BITS_UIO_LIM_H
+#define _BITS_UIO_LIM_H 1
+
+/* Maximum length of the 'struct iovec' array in a single call to
+   readv or writev.  If there is no limit, the macro is not defined.  */
+#undef __IOV_MAX
+
 #endif
-
-
-#include <bits/types/struct_iovec.h>
diff --git a/include/bits/xopen_lim.h b/include/bits/xopen_lim.h
index 2ae7cb3652..4c5e62f71b 100644
--- a/include/bits/xopen_lim.h
+++ b/include/bits/xopen_lim.h
@@ -29,9 +29,6 @@
 #ifndef _XOPEN_LIM_H
 #define _XOPEN_LIM_H	1
 
-#define __need_IOV_MAX
-#include <bits/stdio_lim.h>
-
 /* We do not provide fixed values for
 
    ARG_MAX	Maximum length of argument to the `exec' function
@@ -60,10 +57,16 @@
 */
 
 
-/* Maximum number of `iovec' structures that one process has available
-   for use with `readv' or writev'.  */
+/* Maximum number of `iovec' structures that may be used in a single call
+   to `readv', `writev', etc.  */
 #define	_XOPEN_IOV_MAX	_POSIX_UIO_MAXIOV
 
+#include <bits/uio_lim.h>
+#ifdef __IOV_MAX
+# define IOV_MAX __IOV_MAX
+#else
+# undef IOV_MAX
+#endif
 
 /* Maximum value of `digit' in calls to the `printf' and `scanf'
    functions.  We have no limit, so return a reasonable value.  */
diff --git a/misc/Makefile b/misc/Makefile
index 91e425b76f..90875e9af7 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -23,7 +23,8 @@ subdir	:= misc
 
 include ../Makeconfig
 
-headers	:= sys/uio.h bits/uio.h sys/ioctl.h bits/ioctls.h bits/ioctl-types.h \
+headers	:= sys/uio.h sys/uio_ext.h bits/uio_lim.h \
+	   sys/ioctl.h bits/ioctls.h bits/ioctl-types.h \
 	   sys/ptrace.h sys/file.h sys/dir.h sys/cdefs.h \
 	   ar.h a.out.h libgen.h stab.h bits/stab.def sgtty.h \
 	   ttyent.h paths.h sys/reboot.h \
diff --git a/misc/sys/uio.h b/misc/sys/uio.h
index e80f0136c9..9ad7615a4f 100644
--- a/misc/sys/uio.h
+++ b/misc/sys/uio.h
@@ -19,15 +19,17 @@
 #define _SYS_UIO_H	1
 
 #include <features.h>
-
 #include <sys/types.h>
+#include <bits/types/struct_iovec.h>
+#include <bits/uio_lim.h>
+#ifdef __IOV_MAX
+# define UIO_MAXIOV __IOV_MAX
+#else
+# undef UIO_MAXIOV
+#endif
 
 __BEGIN_DECLS
 
-/* This file defines `struct iovec'.  */
-#include <bits/uio.h>
-
-
 /* Read data from file descriptor FD, and put the result in the
    buffers described by IOVEC, which is a vector of COUNT 'struct iovec's.
    The buffers are filled in the order specified.
@@ -119,4 +121,10 @@ extern ssize_t pwritev64 (int __fd, const struct iovec *__iovec, int __count,
 
 __END_DECLS
 
+/* Some operating systems provide system-specific extensions to this
+   header.  */
+#ifdef __USE_GNU
+# include <sys/uio_ext.h>
+#endif
+
 #endif /* sys/uio.h */
diff --git a/stdio-common/stdio_lim.h.in b/stdio-common/stdio_lim.h.in
index 510bf008aa..5288907469 100644
--- a/stdio-common/stdio_lim.h.in
+++ b/stdio-common/stdio_lim.h.in
@@ -15,28 +15,25 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#if !defined _STDIO_H && !defined __need_FOPEN_MAX && !defined __need_IOV_MAX
+#ifndef _BITS_STDIO_LIM_H
+#define _BITS_STDIO_LIM_H 1
+
+#ifndef _STDIO_H
 # error "Never include <bits/stdio_lim.h> directly; use <stdio.h> instead."
 #endif
 
-#ifdef _STDIO_H
-# define L_tmpnam @L_tmpnam@
-# define TMP_MAX @TMP_MAX@
-# define FILENAME_MAX @FILENAME_MAX@
+#define L_tmpnam @L_tmpnam@
+#define TMP_MAX @TMP_MAX@
+#define FILENAME_MAX @FILENAME_MAX@
 
-# ifdef __USE_POSIX
-#  define L_ctermid @L_ctermid@
-#  if !defined __USE_XOPEN2K || defined __USE_GNU
-#   define L_cuserid @L_cuserid@
-#  endif
+#ifdef __USE_POSIX
+# define L_ctermid @L_ctermid@
+# if !defined __USE_XOPEN2K || defined __USE_GNU
+#  define L_cuserid @L_cuserid@
 # endif
 #endif
 
-#if defined __need_FOPEN_MAX || defined _STDIO_H
-# undef  FOPEN_MAX
-# define FOPEN_MAX @FOPEN_MAX@
-#endif
+#undef  FOPEN_MAX
+#define FOPEN_MAX @FOPEN_MAX@
 
-#if defined __need_IOV_MAX && !defined IOV_MAX
-@define_IOV_MAX@
-#endif
+#endif /* bits/stdio_lim.h */
diff --git a/sysdeps/generic/sys/uio_ext.h b/sysdeps/generic/sys/uio_ext.h
new file mode 100644
index 0000000000..bd49003a7c
--- /dev/null
+++ b/sysdeps/generic/sys/uio_ext.h
@@ -0,0 +1,25 @@
+/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_UIO_EXT_H
+#define _SYS_UIO_EXT_H 1
+
+#include <sys/uio.h>
+
+/* This operating system does not extend sys/uio.h.  */
+
+#endif /* sys/uio_ext.h */
diff --git a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h
index 59d663196a..71cbb5090c 100644
--- a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h
+++ b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h
@@ -35,7 +35,7 @@
 */
 
 #ifdef __USE_GNU
-# include <bits/uio.h>
+# include <bits/types/struct_iovec.h>
 #endif
 
 /* open/fcntl.  */
@@ -339,7 +339,7 @@ __BEGIN_DECLS
 #ifdef __USE_GNU
 
 /* Provide kernel hint to read ahead.  */
-extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
+extern __ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
     __THROW;
 
 
@@ -355,23 +355,23 @@ extern int sync_file_range (int __fd, __off64_t __offset, __off64_t __count,
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
-extern ssize_t vmsplice (int __fdout, const struct iovec *__iov,
-			 size_t __count, unsigned int __flags);
+extern __ssize_t vmsplice (int __fdout, const struct iovec *__iov,
+                           size_t __count, unsigned int __flags);
 
 /* Splice two files together.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
-extern ssize_t splice (int __fdin, __off64_t *__offin, int __fdout,
-		       __off64_t *__offout, size_t __len,
-		       unsigned int __flags);
+extern __ssize_t splice (int __fdin, __off64_t *__offin, int __fdout,
+                         __off64_t *__offout, size_t __len,
+                         unsigned int __flags);
 
 /* In-kernel implementation of tee for pipe buffers.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
-extern ssize_t tee (int __fdin, int __fdout, size_t __len,
-		    unsigned int __flags);
+extern __ssize_t tee (int __fdin, int __fdout, size_t __len,
+                      unsigned int __flags);
 
 /* Reserve storage for the data of the file associated with FD.
 
diff --git a/sysdeps/unix/sysv/linux/bits/uio_lim.h b/sysdeps/unix/sysv/linux/bits/uio_lim.h
new file mode 100644
index 0000000000..7c69b93d31
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/uio_lim.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 1996-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _BITS_UIO_LIM_H
+#define _BITS_UIO_LIM_H 1
+
+/* Maximum length of the 'struct iovec' array in a single call to
+   readv or writev.
+
+   This macro has different values in different kernel versions.  The
+   latest versions of the kernel use 1024 and this is good choice.  Since
+   the C library implementation of readv/writev is able to emulate the
+   functionality even if the currently running kernel does not support
+   this large value the readv/writev call will not fail because of this.  */
+#define __IOV_MAX	1024
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/bits/uio.h b/sysdeps/unix/sysv/linux/sys/uio_ext.h
similarity index 57%
rename from sysdeps/unix/sysv/linux/bits/uio.h
rename to sysdeps/unix/sysv/linux/sys/uio_ext.h
index 1583f0455b..3999e91e5a 100644
--- a/sysdeps/unix/sysv/linux/bits/uio.h
+++ b/sysdeps/unix/sysv/linux/sys/uio_ext.h
@@ -15,38 +15,10 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#if !defined _SYS_UIO_H && !defined _FCNTL_H
-# error "Never include <bits/uio.h> directly; use <sys/uio.h> instead."
-#endif
+#ifndef _SYS_UIO_EXT_H
+#define _SYS_UIO_EXT_H 1
 
-#ifndef _BITS_UIO_H
-#define _BITS_UIO_H	1
-
-#include <sys/types.h>
-
-
-/* We should normally use the Linux kernel header file to define this
-   type and macros but this calls for trouble because of the header
-   includes other kernel headers.  */
-
-/* Size of object which can be written atomically.
-
-   This macro has different values in different kernel versions.  The
-   latest versions of the kernel use 1024 and this is good choice.  Since
-   the C library implementation of readv/writev is able to emulate the
-   functionality even if the currently running kernel does not support
-   this large value the readv/writev call will not fail because of this.  */
-#define UIO_MAXIOV	1024
-
-
-#include <bits/types/struct_iovec.h>
-
-#endif
-
-
-#ifdef __USE_GNU
-# if defined _SYS_UIO_H && !defined _BITS_UIO_H_FOR_SYS_UIO_H
-#  define _BITS_UIO_H_FOR_SYS_UIO_H 1
+#include <sys/uio.h>
 
 __BEGIN_DECLS
 
@@ -68,5 +40,4 @@ extern ssize_t process_vm_writev (pid_t __pid, const struct iovec *__lvec,
 
 __END_DECLS
 
-# endif
-#endif
+#endif /* sys/uio_ext.h */
