]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
UBUNTU: SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)
authorColin Ian King <colin.king@canonical.com>
Mon, 26 Mar 2018 11:11:18 +0000 (12:11 +0100)
committerThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Mon, 26 Mar 2018 13:22:25 +0000 (10:22 -0300)
BugLink: https://bugs.launchpad.net/bugs/1754584
Fix mmap'd libaio read on non-prefaulted page deadlock. This is a hot fix
from ZFS upstream that ensure pages are pre-faulted in to avoid deadlock.
Performing a read with the target data in a mmap'd page that is map'd into
the same blocks that are being read causes a lock on the page and a further
lock on the same page when the page is being faulted in, causing deadlock.
The current workaround is to prefault the page(s) before the pages are
read.

This is no current upstream commit ID for this fix, as it landed late on
Friday and it's not commited to upstream ZFS. The fix has passed our ZFS
regression tests and fixes the issue, so I'd like to get this included
into Bionic sooner than later.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
19 files changed:
zfs/META
zfs/Makefile.in
zfs/aclocal.m4
zfs/config/user-libaio.m4 [new file with mode: 0644]
zfs/config/user.m4
zfs/config/zfs-build.m4
zfs/configure
zfs/include/Makefile.in
zfs/include/linux/Makefile.in
zfs/include/sys/Makefile.in
zfs/include/sys/crypto/Makefile.in
zfs/include/sys/fm/Makefile.in
zfs/include/sys/fm/fs/Makefile.in
zfs/include/sys/fs/Makefile.in
zfs/include/sys/sysevent/Makefile.in
zfs/include/sys/uio_impl.h
zfs/module/zcommon/zfs_uio.c
zfs/module/zfs/zfs_vnops.c
zfs/zfs_config.h.in

index 67f3b429d5c263666d84b2693a617756b6c959e2..049b610095a3db2de2409427d3f4b1fdc82100e9 100644 (file)
--- a/zfs/META
+++ b/zfs/META
@@ -2,7 +2,7 @@ Meta:         1
 Name:         zfs
 Branch:       1.0
 Version:      0.7.5
-Release:      1ubuntu8
+Release:      1ubuntu11
 Release-Tags: relext
 License:      CDDL
 Author:       OpenZFS on Linux
index 9dd300bcc845e08bf8ac0395dd108d4e6243510a..ed2c4302788d4dfa451431a4de6d34b1d34b18da 100644 (file)
@@ -195,6 +195,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
        $(top_srcdir)/config/toolchain-simd.m4 \
        $(top_srcdir)/config/user-dracut.m4 \
        $(top_srcdir)/config/user-frame-larger-than.m4 \
+       $(top_srcdir)/config/user-libaio.m4 \
        $(top_srcdir)/config/user-libattr.m4 \
        $(top_srcdir)/config/user-libblkid.m4 \
        $(top_srcdir)/config/user-libtirpc.m4 \
@@ -426,6 +427,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
 KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
 LIBATTR = @LIBATTR@
 LIBBLKID = @LIBBLKID@
 LIBOBJS = @LIBOBJS@
index 84d98a9b5f04e58e0439ffc0331f851a52c08fa4..7d89c6e7978f50af95ac11045a7634b8996614d6 100644 (file)
@@ -1303,6 +1303,7 @@ m4_include([config/mount-helper.m4])
 m4_include([config/toolchain-simd.m4])
 m4_include([config/user-dracut.m4])
 m4_include([config/user-frame-larger-than.m4])
+m4_include([config/user-libaio.m4])
 m4_include([config/user-libattr.m4])
 m4_include([config/user-libblkid.m4])
 m4_include([config/user-libtirpc.m4])
diff --git a/zfs/config/user-libaio.m4 b/zfs/config/user-libaio.m4
new file mode 100644 (file)
index 0000000..d7a7cb5
--- /dev/null
@@ -0,0 +1,14 @@
+dnl #
+dnl # Check for libaio - only used for libaiot test cases.
+dnl #
+AC_DEFUN([ZFS_AC_CONFIG_USER_LIBAIO], [
+       LIBAIO=
+
+       AC_CHECK_HEADER([libaio.h], [
+           user_libaio=yes
+           AC_SUBST([LIBAIO], ["-laio"])
+           AC_DEFINE([HAVE_LIBAIO], 1, [Define if you have libaio])
+       ], [
+           user_libaio=no
+       ])
+])
index 2b033f5a57c599bb4855e38a27790a5dc2200239..941fcf03c215e5411b8965d55ab69e7aa6ad6725 100644 (file)
@@ -13,6 +13,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
        ZFS_AC_CONFIG_USER_LIBTIRPC
        ZFS_AC_CONFIG_USER_LIBBLKID
        ZFS_AC_CONFIG_USER_LIBATTR
+       ZFS_AC_CONFIG_USER_LIBAIO
        ZFS_AC_CONFIG_USER_LIBUDEV
        ZFS_AC_CONFIG_USER_FRAME_LARGER_THAN
        ZFS_AC_CONFIG_USER_RUNSTATEDIR
index 7651dc2c12e4ae80518999ba2a3c9a580e302f51..1224682fe53f740fbc5b0b781fe1d108bfe0b913 100644 (file)
@@ -79,11 +79,11 @@ AC_DEFUN([ZFS_AC_CONFIG], [
        AM_CONDITIONAL([CONFIG_KERNEL],
            [test "$ZFS_CONFIG" = kernel -o "$ZFS_CONFIG" = all] &&
            [test "x$enable_linux_builtin" != xyes ])
-       AM_CONDITIONAL([WANT_DEVNAME2DEVID],
-           [test "x$user_libudev" = xyes ])
        AM_CONDITIONAL([CONFIG_QAT],
            [test "$ZFS_CONFIG" = kernel -o "$ZFS_CONFIG" = all] &&
            [test "x$qatsrc" != x ])
+       AM_CONDITIONAL([WANT_DEVNAME2DEVID], [test "x$user_libudev" = xyes ])
+       AM_CONDITIONAL([WANT_MMAP_LIBAIO], [test "x$user_libaio" = xyes ])
 ])
 
 dnl #
index aebe4bbe998445299047724b2d47aa6b10af3263..ea023e85cfacb58fa896bec5b0d2e8b2249a9e78 100755 (executable)
@@ -635,10 +635,12 @@ LIBOBJS
 DEBUG_ZFS
 DEBUG_STACKFLAGS
 DEBUG_CFLAGS
-CONFIG_QAT_FALSE
-CONFIG_QAT_TRUE
+WANT_MMAP_LIBAIO_FALSE
+WANT_MMAP_LIBAIO_TRUE
 WANT_DEVNAME2DEVID_FALSE
 WANT_DEVNAME2DEVID_TRUE
+CONFIG_QAT_FALSE
+CONFIG_QAT_TRUE
 CONFIG_KERNEL_FALSE
 CONFIG_KERNEL_TRUE
 CONFIG_USER_FALSE
@@ -648,6 +650,7 @@ ZONENAME
 NO_FORMAT_TRUNCATION
 FRAME_LARGER_THAN
 LIBUDEV
+LIBAIO
 LIBATTR
 LIBBLKID
 LIBTIRPC_CFLAGS
@@ -26908,6 +26911,27 @@ $as_echo "#define HAVE_LIBATTR 1" >>confdefs.h
 
 
 
+       LIBAIO=
+
+       ac_fn_c_check_header_mongrel "$LINENO" "libaio.h" "ac_cv_header_libaio_h" "$ac_includes_default"
+if test "x$ac_cv_header_libaio_h" = xyes; then :
+
+           user_libaio=yes
+           LIBAIO="-laio"
+
+
+$as_echo "#define HAVE_LIBAIO 1" >>confdefs.h
+
+
+else
+
+           user_libaio=no
+
+fi
+
+
+
+
        LIBUDEV=
 
        ac_fn_c_check_header_mongrel "$LINENO" "libudev.h" "ac_cv_header_libudev_h" "$ac_includes_default"
@@ -27936,6 +27960,27 @@ $as_echo "#define HAVE_LIBATTR 1" >>confdefs.h
 
 
 
+       LIBAIO=
+
+       ac_fn_c_check_header_mongrel "$LINENO" "libaio.h" "ac_cv_header_libaio_h" "$ac_includes_default"
+if test "x$ac_cv_header_libaio_h" = xyes; then :
+
+           user_libaio=yes
+           LIBAIO="-laio"
+
+
+$as_echo "#define HAVE_LIBAIO 1" >>confdefs.h
+
+
+else
+
+           user_libaio=no
+
+fi
+
+
+
+
        LIBUDEV=
 
        ac_fn_c_check_header_mongrel "$LINENO" "libudev.h" "ac_cv_header_libudev_h" "$ac_includes_default"
@@ -40914,6 +40959,15 @@ else
   CONFIG_KERNEL_FALSE=
 fi
 
+        if test "$ZFS_CONFIG" = kernel -o "$ZFS_CONFIG" = all &&
+           test "x$qatsrc" != x ; then
+  CONFIG_QAT_TRUE=
+  CONFIG_QAT_FALSE='#'
+else
+  CONFIG_QAT_TRUE='#'
+  CONFIG_QAT_FALSE=
+fi
+
         if test "x$user_libudev" = xyes ; then
   WANT_DEVNAME2DEVID_TRUE=
   WANT_DEVNAME2DEVID_FALSE='#'
@@ -40922,13 +40976,12 @@ else
   WANT_DEVNAME2DEVID_FALSE=
 fi
 
-        if test "$ZFS_CONFIG" = kernel -o "$ZFS_CONFIG" = all &&
-           test "x$qatsrc" != x ; then
-  CONFIG_QAT_TRUE=
-  CONFIG_QAT_FALSE='#'
+        if test "x$user_libaio" = xyes ; then
+  WANT_MMAP_LIBAIO_TRUE=
+  WANT_MMAP_LIBAIO_FALSE='#'
 else
-  CONFIG_QAT_TRUE='#'
-  CONFIG_QAT_FALSE=
+  WANT_MMAP_LIBAIO_TRUE='#'
+  WANT_MMAP_LIBAIO_FALSE=
 fi
 
 
@@ -41136,12 +41189,16 @@ if test -z "${CONFIG_KERNEL_TRUE}" && test -z "${CONFIG_KERNEL_FALSE}"; then
   as_fn_error $? "conditional \"CONFIG_KERNEL\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${CONFIG_QAT_TRUE}" && test -z "${CONFIG_QAT_FALSE}"; then
+  as_fn_error $? "conditional \"CONFIG_QAT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${WANT_DEVNAME2DEVID_TRUE}" && test -z "${WANT_DEVNAME2DEVID_FALSE}"; then
   as_fn_error $? "conditional \"WANT_DEVNAME2DEVID\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
-if test -z "${CONFIG_QAT_TRUE}" && test -z "${CONFIG_QAT_FALSE}"; then
-  as_fn_error $? "conditional \"CONFIG_QAT\" was never defined.
+if test -z "${WANT_MMAP_LIBAIO_TRUE}" && test -z "${WANT_MMAP_LIBAIO_FALSE}"; then
+  as_fn_error $? "conditional \"WANT_MMAP_LIBAIO\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 
index ae748a95e4bc582620291321f2135294d1432917..acd99dcf2e15beedccb78288be482d2d738ebc45 100644 (file)
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
        $(top_srcdir)/config/toolchain-simd.m4 \
        $(top_srcdir)/config/user-dracut.m4 \
        $(top_srcdir)/config/user-frame-larger-than.m4 \
+       $(top_srcdir)/config/user-libaio.m4 \
        $(top_srcdir)/config/user-libattr.m4 \
        $(top_srcdir)/config/user-libblkid.m4 \
        $(top_srcdir)/config/user-libtirpc.m4 \
@@ -400,6 +401,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
 KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
 LIBATTR = @LIBATTR@
 LIBBLKID = @LIBBLKID@
 LIBOBJS = @LIBOBJS@
index 0f6c8c36afff558e6f1a0e947a333c9c82303673..1002d83470863c9b2f5fd092ce41345f8645a6c5 100644 (file)
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
        $(top_srcdir)/config/toolchain-simd.m4 \
        $(top_srcdir)/config/user-dracut.m4 \
        $(top_srcdir)/config/user-frame-larger-than.m4 \
+       $(top_srcdir)/config/user-libaio.m4 \
        $(top_srcdir)/config/user-libattr.m4 \
        $(top_srcdir)/config/user-libblkid.m4 \
        $(top_srcdir)/config/user-libtirpc.m4 \
@@ -345,6 +346,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
 KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
 LIBATTR = @LIBATTR@
 LIBBLKID = @LIBBLKID@
 LIBOBJS = @LIBOBJS@
index 25d1f71541d51b7539aad0f88621a506acbb5e53..c24010a0b96215e2d69ffad3163c1989a362863c 100644 (file)
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
        $(top_srcdir)/config/toolchain-simd.m4 \
        $(top_srcdir)/config/user-dracut.m4 \
        $(top_srcdir)/config/user-frame-larger-than.m4 \
+       $(top_srcdir)/config/user-libaio.m4 \
        $(top_srcdir)/config/user-libattr.m4 \
        $(top_srcdir)/config/user-libblkid.m4 \
        $(top_srcdir)/config/user-libtirpc.m4 \
@@ -606,6 +607,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
 KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
 LIBATTR = @LIBATTR@
 LIBBLKID = @LIBBLKID@
 LIBOBJS = @LIBOBJS@
index fa2f570a08ab213699fdf88605e4731c48e63449..79a03c57caaac0078be586a92128e633952be8d8 100644 (file)
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
        $(top_srcdir)/config/toolchain-simd.m4 \
        $(top_srcdir)/config/user-dracut.m4 \
        $(top_srcdir)/config/user-frame-larger-than.m4 \
+       $(top_srcdir)/config/user-libaio.m4 \
        $(top_srcdir)/config/user-libattr.m4 \
        $(top_srcdir)/config/user-libblkid.m4 \
        $(top_srcdir)/config/user-libtirpc.m4 \
@@ -342,6 +343,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
 KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
 LIBATTR = @LIBATTR@
 LIBBLKID = @LIBBLKID@
 LIBOBJS = @LIBOBJS@
index 85019a12269de925549121be553d1bfead97ce43..a73b969694ad6cad2d4ffdc410203bb1cf010b48 100644 (file)
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
        $(top_srcdir)/config/toolchain-simd.m4 \
        $(top_srcdir)/config/user-dracut.m4 \
        $(top_srcdir)/config/user-frame-larger-than.m4 \
+       $(top_srcdir)/config/user-libaio.m4 \
        $(top_srcdir)/config/user-libattr.m4 \
        $(top_srcdir)/config/user-libblkid.m4 \
        $(top_srcdir)/config/user-libtirpc.m4 \
@@ -382,6 +383,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
 KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
 LIBATTR = @LIBATTR@
 LIBBLKID = @LIBBLKID@
 LIBOBJS = @LIBOBJS@
index 42a85e5602d67babe44259b8b5f66da6fa453ffd..03e3298920834867cc4ac1d4dc13293f959644d0 100644 (file)
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
        $(top_srcdir)/config/toolchain-simd.m4 \
        $(top_srcdir)/config/user-dracut.m4 \
        $(top_srcdir)/config/user-frame-larger-than.m4 \
+       $(top_srcdir)/config/user-libaio.m4 \
        $(top_srcdir)/config/user-libattr.m4 \
        $(top_srcdir)/config/user-libblkid.m4 \
        $(top_srcdir)/config/user-libtirpc.m4 \
@@ -338,6 +339,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
 KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
 LIBATTR = @LIBATTR@
 LIBBLKID = @LIBBLKID@
 LIBOBJS = @LIBOBJS@
index d22d5fc458b1d36f6a4ef2a138f35bc6d9076138..8ea51c9fc7bff9bda2d73b09a632919351c980dd 100644 (file)
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
        $(top_srcdir)/config/toolchain-simd.m4 \
        $(top_srcdir)/config/user-dracut.m4 \
        $(top_srcdir)/config/user-frame-larger-than.m4 \
+       $(top_srcdir)/config/user-libaio.m4 \
        $(top_srcdir)/config/user-libattr.m4 \
        $(top_srcdir)/config/user-libblkid.m4 \
        $(top_srcdir)/config/user-libtirpc.m4 \
@@ -338,6 +339,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
 KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
 LIBATTR = @LIBATTR@
 LIBBLKID = @LIBBLKID@
 LIBOBJS = @LIBOBJS@
index 12c09129c2cd042769e0622ae294d1fa49777272..2a9b504753201b06f64a1a3b4a71ab6ac27caf94 100644 (file)
@@ -187,6 +187,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
        $(top_srcdir)/config/toolchain-simd.m4 \
        $(top_srcdir)/config/user-dracut.m4 \
        $(top_srcdir)/config/user-frame-larger-than.m4 \
+       $(top_srcdir)/config/user-libaio.m4 \
        $(top_srcdir)/config/user-libattr.m4 \
        $(top_srcdir)/config/user-libblkid.m4 \
        $(top_srcdir)/config/user-libtirpc.m4 \
@@ -342,6 +343,7 @@ KERNELCPPFLAGS = @KERNELCPPFLAGS@
 KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBAIO = @LIBAIO@
 LIBATTR = @LIBATTR@
 LIBBLKID = @LIBBLKID@
 LIBOBJS = @LIBOBJS@
index 37e283da0f8ba5f20ae3de8a035dca53f5aeffe6..01ca723c0612ef753ae3ea8a04aa15666e0a9290 100644 (file)
@@ -42,7 +42,7 @@
 #include <sys/uio.h>
 
 extern int uiomove(void *, size_t, enum uio_rw, uio_t *);
-extern void uio_prefaultpages(ssize_t, uio_t *);
+extern int uio_prefaultpages(ssize_t, enum uio_rw, uio_t *);
 extern int uiocopy(void *, size_t, enum uio_rw, uio_t *, size_t *);
 extern void uioskip(uio_t *, size_t);
 
index 7b4175bbeeeb4e3631f470e18353a1cc4637dff9..0001f9510a5df42c1d446506dbee9cf6a4c316f3 100644 (file)
@@ -148,64 +148,51 @@ uiomove(void *p, size_t n, enum uio_rw rw, struct uio *uio)
 }
 EXPORT_SYMBOL(uiomove);
 
-#define        fuword8(uptr, vptr)     get_user((*vptr), (uptr))
-
 /*
- * Fault in the pages of the first n bytes specified by the uio structure.
- * 1 byte in each page is touched and the uio struct is unmodified. Any
- * error will terminate the process as this is only a best attempt to get
- * the pages resident.
+ * Fault in the user space pages specified by the uio structure.  Note that
+ * when faulting in pages with UIO_READ they may have zeros written to them
+ * which is OK because we know they'll be overwritten.
  */
-void
-uio_prefaultpages(ssize_t n, struct uio *uio)
+int
+uio_prefaultpages(ssize_t n, enum uio_rw rw, struct uio *uio)
 {
-       const struct iovec *iov;
-       ulong_t cnt, incr;
-       caddr_t p;
-       uint8_t tmp;
-       int iovcnt;
-       size_t skip;
+       const struct iovec *iov = uio->uio_iov;
+       size_t skip = uio->uio_skip;
+       int iovcnt = uio->uio_iovcnt;
+       uio_seg_t seg = uio->uio_segflg;
+       char __user *p;
+       ulong_t cnt;
+       int error;
 
-       /* no need to fault in kernel pages */
-       switch (uio->uio_segflg) {
-               case UIO_SYSSPACE:
-               case UIO_BVEC:
-                       return;
-               case UIO_USERSPACE:
-               case UIO_USERISPACE:
-                       break;
-               default:
-                       ASSERT(0);
-       }
+       /* No need to fault in kernel pages */
+       if (seg == UIO_SYSSPACE || seg == UIO_BVEC)
+               return (0);
 
-       iov = uio->uio_iov;
-       iovcnt = uio->uio_iovcnt;
-       skip = uio->uio_skip;
+       ASSERT(seg == UIO_USERSPACE || seg == UIO_USERISPACE);
 
-       for (; n > 0 && iovcnt > 0; iov++, iovcnt--, skip = 0) {
+       while ((n > 0) && (iovcnt > 0)) {
                cnt = MIN(iov->iov_len - skip, n);
-               /* empty iov */
-               if (cnt == 0)
-                       continue;
-               n -= cnt;
-               /*
-                * touch each page in this segment.
-                */
                p = iov->iov_base + skip;
-               while (cnt) {
-                       if (fuword8((uint8_t *)p, &tmp))
-                               return;
-                       incr = MIN(cnt, PAGESIZE);
-                       p += incr;
-                       cnt -= incr;
+
+               if (rw == UIO_READ)
+                       error = -fault_in_pages_writeable(p, cnt);
+               else
+                       error = -fault_in_pages_readable(p, cnt);
+
+               if (error)
+                       return (error);
+
+               skip += cnt;
+               if (skip == iov->iov_len) {
+                       skip = 0;
+                       iov++;
+                       iovcnt--;
                }
-               /*
-                * touch the last byte in case it straddles a page.
-                */
-               p--;
-               if (fuword8((uint8_t *)p, &tmp))
-                       return;
+
+               n -= cnt;
        }
+
+       return (0);
 }
 EXPORT_SYMBOL(uio_prefaultpages);
 
index 6a1dab5c984e9aef79c10a5745caf7ff1dd445fc..9338bb04172712265f724840084c1fb39736205c 100644 (file)
@@ -390,6 +390,10 @@ mappedread(struct inode *ip, int nbytes, uio_t *uio)
        int error = 0;
        void *pb;
 
+       error = uio_prefaultpages(nbytes, UIO_READ, uio);
+       if (error)
+               return (error);
+
        start = uio->uio_loffset;
        off = start & (PAGE_SIZE-1);
        for (start &= PAGE_MASK; len > 0; start += PAGE_SIZE) {
@@ -675,7 +679,7 @@ zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
                xuio = (xuio_t *)uio;
        else
 #endif
-               uio_prefaultpages(MIN(n, max_blksz), uio);
+               uio_prefaultpages(MIN(n, max_blksz), UIO_WRITE, uio);
 
        /*
         * If in append mode, set the io offset pointer to eof.
@@ -921,7 +925,7 @@ zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
                n -= nbytes;
 
                if (!xuio && n > 0)
-                       uio_prefaultpages(MIN(n, max_blksz), uio);
+                       uio_prefaultpages(MIN(n, max_blksz), UIO_WRITE, uio);
        }
 
        zfs_inode_update(zp);
index ac41b5a9dcee338918dc57a893ffed7ae05bd874..a87d6ac187b0c84af99df7735f19c7c92af23c99 100644 (file)
 /* kernel has large stacks */
 #undef HAVE_LARGE_STACKS
 
+/* Define if you have libaio */
+#undef HAVE_LIBAIO
+
 /* Define if you have libattr */
 #undef HAVE_LIBATTR