Whamcloud - gitweb
LU-12355 llite: Lustre specific iov_for_each broken (removed) 24/35024/10
authorShaun Tancheff <stancheff@cray.com>
Thu, 25 Jul 2019 14:09:00 +0000 (09:09 -0500)
committerOleg Drokin <green@whamcloud.com>
Fri, 9 Aug 2019 04:40:04 +0000 (04:40 +0000)
Kernel 4.20 introduced iov_iter_type and broke iov_for_each

As iov_for_each is only used once so drop the macro entirely.
When iov_iter_type is available ignore invalid iter types.

Linux-commit: 8a363970d1dc38c4ec4ad575c862f776f468d057

Kernel 3.15 added type to iov_iter. Use the type to provide
a sensible replacement for iov_iter_type when it is available.

Linux-commit: 71d8e532b1549a478e6a6a8a44f309d050294d00

Cray-bug-id: LUS-6962
Change-Id: I97cdce1c85803ac2d4436d4eedf67a545ea2cdb8
Signed-off-by: Shaun Tancheff <stancheff@cray.com>
Reviewed-on: https://review.whamcloud.com/35024
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Petros Koutoupis <pkoutoupis@cray.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
libcfs/autoconf/lustre-libcfs.m4
libcfs/include/libcfs/linux/linux-misc.h
lustre/llite/vvp_io.c

index 9f72305..f34af72 100644 (file)
@@ -404,6 +404,28 @@ shrinker_count_objects, [
 ]) # LIBCFS_SHRINKER_COUNT
 
 #
 ]) # LIBCFS_SHRINKER_COUNT
 
 #
+# LIBCFS_IOV_ITER_HAS_TYPE
+#
+# kernel 3.15-rc4 commit 71d8e532b1549a478e6a6a8a44f309d050294d00
+# start adding the tag to iov_iter
+#
+AC_DEFUN([LIBCFS_IOV_ITER_HAS_TYPE], [
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_CHECK_COMPILE([if iov_iter has member type],
+iov_iter_has_type_member, [
+       #include <linux/uio.h>
+],[
+       struct iov_iter iter = { .type = ITER_KVEC };
+       (void)iter;
+],[
+       AC_DEFINE(HAVE_IOV_ITER_HAS_TYPE_MEMBER, 1,
+               [if iov_iter has member type])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+]) # LIBCFS_IOV_ITER_HAS_TYPE
+
+#
 # Kernel version 3.17 changed hlist_add_after to
 # hlist_add_behind
 #
 # Kernel version 3.17 changed hlist_add_after to
 # hlist_add_behind
 #
@@ -1214,6 +1236,29 @@ clear_and_wake_up_bit, [
 ]) # LIBCFS_CLEAR_AND_WAKE_UP_BIT
 
 #
 ]) # LIBCFS_CLEAR_AND_WAKE_UP_BIT
 
 #
+# LIBCFS_HAVE_IOV_ITER_TYPE
+#
+# kernel 4.20 commit 00e23707442a75b404392cef1405ab4fd498de6b
+# iov_iter: Use accessor functions to access an iterator's type and direction.
+#
+AC_DEFUN([LIBCFS_HAVE_IOV_ITER_TYPE], [
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_CHECK_COMPILE([if iov_iter_type exists],
+macro_iov_iter_type_exists, [
+       #include <linux/uio.h>
+],[
+       struct iov_iter iter = { .type = ITER_KVEC };
+       enum iter_type type = iov_iter_type(&iter);
+       (void)type;
+],[
+       AC_DEFINE(HAVE_IOV_ITER_TYPE, 1,
+               [if iov_iter_type exists])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+]) # LIBCFS_HAVE_IOV_ITER_TYPE
+
+#
 # LIBCFS_PROG_LINUX
 #
 # LibCFS linux kernel checks
 # LIBCFS_PROG_LINUX
 #
 # LibCFS linux kernel checks
@@ -1256,6 +1301,8 @@ LIBCFS_KTIME_AFTER
 LIBCFS_KTIME_BEFORE
 LIBCFS_KTIME_COMPARE
 LIBCFS_SHRINKER_COUNT
 LIBCFS_KTIME_BEFORE
 LIBCFS_KTIME_COMPARE
 LIBCFS_SHRINKER_COUNT
+# 3.15
+LIBCFS_IOV_ITER_HAS_TYPE
 # 3.17
 LIBCFS_HLIST_ADD_AFTER
 LIBCFS_TIMESPEC64
 # 3.17
 LIBCFS_HLIST_ADD_AFTER
 LIBCFS_TIMESPEC64
@@ -1320,6 +1367,8 @@ LIBCFS_TIMER_SETUP
 LIBCFS_WAIT_VAR_EVENT
 # 4.17
 LIBCFS_CLEAR_AND_WAKE_UP_BIT
 LIBCFS_WAIT_VAR_EVENT
 # 4.17
 LIBCFS_CLEAR_AND_WAKE_UP_BIT
+# 4.20
+LIBCFS_HAVE_IOV_ITER_TYPE
 # 5.0
 LIBCFS_MM_TOTALRAM_PAGES_FUNC
 ]) # LIBCFS_PROG_LINUX
 # 5.0
 LIBCFS_MM_TOTALRAM_PAGES_FUNC
 ]) # LIBCFS_PROG_LINUX
index 524bf40..bc3b5ee 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/fs.h>
 #include <linux/mutex.h>
 #include <linux/user_namespace.h>
 #include <linux/fs.h>
 #include <linux/mutex.h>
 #include <linux/user_namespace.h>
+#include <linux/uio.h>
 
 #ifdef HAVE_SYSCTL_CTLNAME
 #define INIT_CTL_NAME  .ctl_name = CTL_UNNUMBERED,
 
 #ifdef HAVE_SYSCTL_CTLNAME
 #define INIT_CTL_NAME  .ctl_name = CTL_UNNUMBERED,
 #define INIT_STRATEGY
 #endif
 
 #define INIT_STRATEGY
 #endif
 
+#ifndef HAVE_IOV_ITER_TYPE
+#ifdef HAVE_IOV_ITER_HAS_TYPE_MEMBER
+#define iter_is_iovec(iter)            ((iter)->type & ITER_IOVEC)
+#define iov_iter_is_kvec(iter)         ((iter)->type & ITER_KVEC)
+#define iov_iter_is_bvec(iter)         ((iter)->type & ITER_BVEC)
+#define iov_iter_is_pipe(iter)         ((iter)->type & ITER_PIPE)
+#define iov_iter_is_discard(iter)      ((iter)->type & ITER_DISCARD)
+#else
+#define iter_is_iovec(iter)            1
+#define iov_iter_is_kvec(iter)         0
+#define iov_iter_is_bvec(iter)         0
+#define iov_iter_is_pipe(iter)         0
+#define iov_iter_is_discard(iter)      0
+#endif
+#endif /* HAVE_IOV_ITER_TYPE */
+
 #ifndef HAVE_MODULE_PARAM_LOCKING
 static DEFINE_MUTEX(param_lock);
 #endif
 #ifndef HAVE_MODULE_PARAM_LOCKING
 static DEFINE_MUTEX(param_lock);
 #endif
index 3588d6a..294cfeb 100644 (file)
@@ -41,6 +41,7 @@
 #include <obd.h>
 #include "llite_internal.h"
 #include "vvp_internal.h"
 #include <obd.h>
 #include "llite_internal.h"
 #include "vvp_internal.h"
+#include <libcfs/linux/linux-misc.h>
 
 static struct vvp_io *cl2vvp_io(const struct lu_env *env,
                                const struct cl_io_slice *slice)
 
 static struct vvp_io *cl2vvp_io(const struct lu_env *env,
                                const struct cl_io_slice *slice)
@@ -439,6 +440,8 @@ static int vvp_mmap_locks(const struct lu_env *env,
        union ldlm_policy_data policy;
        struct iovec iov;
        struct iov_iter i;
        union ldlm_policy_data policy;
        struct iovec iov;
        struct iov_iter i;
+       unsigned long addr;
+       ssize_t count;
        int result = 0;
        ENTRY;
 
        int result = 0;
        ENTRY;
 
@@ -455,9 +458,15 @@ static int vvp_mmap_locks(const struct lu_env *env,
        if (mm == NULL)
                RETURN(0);
 
        if (mm == NULL)
                RETURN(0);
 
-       iov_for_each(iov, i, *(vio->vui_iter)) {
-               unsigned long addr = (unsigned long)iov.iov_base;
-               size_t count = iov.iov_len;
+       if (!iter_is_iovec(vio->vui_iter) && !iov_iter_is_kvec(vio->vui_iter))
+               RETURN(0);
+
+       for (i = *vio->vui_iter;
+            iov_iter_count(&i);
+            iov_iter_advance(&i, iov.iov_len)) {
+               iov = iov_iter_iovec(&i);
+               addr = (unsigned long)iov.iov_base;
+               count = iov.iov_len;
 
                 if (count == 0)
                         continue;
 
                 if (count == 0)
                         continue;