From 2bb54b6383d57ac61092593b9e6d9c80801263f5 Mon Sep 17 00:00:00 2001 From: Shaun Tancheff Date: Wed, 7 Feb 2024 10:23:00 +0700 Subject: [PATCH] LU-17081 build: compatibility for 6.5 kernels Linux commit v6.4-rc2-29-gc6585011bc1d splice: Remove generic_file_splice_read() Prefer filemap_splice_read and provide alternates for older kernels. Linux commit v6.4-rc2-30-g3fc40265ae2b iov_iter: Kill ITER_PIPE ITER_PIPE and iov_iter_is_pipe() are removed, provide a replacement for iov_iter_is_pipe Linux commit v6.4-rc4-53-g54d020692b34 mm/gup: remove unused vmas parameter from get_user_pages() Use vma_lookup() to acquire the vma following get_user_pages() Linux commit v6.4-rc7-1884-gdc97391e6610 sock: Remove ->sendpage*() in favour of sendmsg(MSG_SPLICE_PAGES) Use sendmsg when MSG_SPLICE_PAGES is defined. Provide a wrapper using sendpage() for older kernels. HPE-bug-id: LUS-11811 Signed-off-by: Shaun Tancheff Change-Id: I95a0954a602c8db08d30b38a50dcd50107c8f268 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52258 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Jian Yu Reviewed-by: Petros Koutoupis Reviewed-by: xinliang Reviewed-by: Oleg Drokin --- libcfs/include/libcfs/linux/linux-misc.h | 10 +++- lnet/klnds/socklnd/socklnd_lib.c | 30 ++++++++---- lustre/autoconf/lustre-core.m4 | 82 ++++++++++++++++++++++++++++++++ lustre/llite/file.c | 29 +++++------ lustre/obdclass/jobid.c | 10 ++-- lustre/osd-ldiskfs/osd_internal.h | 6 +-- 6 files changed, 135 insertions(+), 32 deletions(-) diff --git a/libcfs/include/libcfs/linux/linux-misc.h b/libcfs/include/libcfs/linux/linux-misc.h index 9e4c787..5936c78 100644 --- a/libcfs/include/libcfs/linux/linux-misc.h +++ b/libcfs/include/libcfs/linux/linux-misc.h @@ -48,7 +48,11 @@ * iter_is_iovec() and iov_iter_is_* are available, supply the missing * functionality for older kernels. */ -#ifndef HAVE_IOV_ITER_TYPE +#ifdef HAVE_IOV_ITER_TYPE +#ifndef HAVE_ENUM_ITER_PIPE +#define iov_iter_is_pipe(iter) 0 +#endif +#else /* * Since 3.15-rc4 commit 71d8e532b1549a478e6a6a8a44f309d050294d00 * The iov iterator has a type and can iterate over numerous vector types. @@ -58,7 +62,11 @@ #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) +#if defined HAVE_ENUM_ITER_PIPE #define iov_iter_is_pipe(iter) ((iter)->type & ITER_PIPE) +#else +#define iov_iter_is_pipe(iter) 0 +#endif #define iov_iter_is_discard(iter) ((iter)->type & ITER_DISCARD) #else #define iter_is_iovec(iter) 1 diff --git a/lnet/klnds/socklnd/socklnd_lib.c b/lnet/klnds/socklnd/socklnd_lib.c index 605777a..6409639 100644 --- a/lnet/klnds/socklnd/socklnd_lib.c +++ b/lnet/klnds/socklnd/socklnd_lib.c @@ -109,6 +109,25 @@ ksocknal_lib_send_hdr(struct ksock_conn *conn, struct ksock_tx *tx, return rc; } +static int +ksocknal_lib_sendpage(struct socket *sock, struct bio_vec *kiov, int msgflg) +{ +#ifdef MSG_SPLICE_PAGES + struct msghdr msg = {.msg_flags = msgflg | MSG_SPLICE_PAGES}; + + iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, kiov, 1, kiov->bv_len); + + return sock_sendmsg(sock, &msg); +#else + struct sock *sk = sock->sk; + struct page *page = kiov->bv_page; + int offset = kiov->bv_offset; + int fragsize = kiov->bv_len; + + return sk->sk_prot->sendpage(sk, page, offset, fragsize, msgflg); +#endif +} + int ksocknal_lib_send_kiov(struct ksock_conn *conn, struct ksock_tx *tx, struct kvec *scratchiov) @@ -125,21 +144,16 @@ ksocknal_lib_send_kiov(struct ksock_conn *conn, struct ksock_tx *tx, * or leave them alone. */ if (tx->tx_msg.ksm_zc_cookies[0] != 0) { /* Zero copy is enabled */ - struct sock *sk = sock->sk; - struct page *page = kiov->bv_page; - int offset = kiov->bv_offset; - int fragsize = kiov->bv_len; int msgflg = MSG_DONTWAIT; CDEBUG(D_NET, "page %p + offset %x for %d\n", - page, offset, kiov->bv_len); + kiov->bv_page, kiov->bv_offset, kiov->bv_len); if (!list_empty(&conn->ksnc_tx_queue) || - fragsize < tx->tx_resid) + kiov->bv_len < tx->tx_resid) msgflg |= MSG_MORE; - rc = sk->sk_prot->sendpage(sk, page, - offset, fragsize, msgflg); + rc = ksocknal_lib_sendpage(sock, kiov, msgflg); } else { #if SOCKNAL_SINGLE_FRAG_TX || !SOCKNAL_RISK_KMAP_DEADLOCK struct kvec scratch; diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index dbc7b32..0fbef37 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -4068,6 +4068,78 @@ AC_DEFUN([LC_HAVE_CLASS_CREATE_MODULE_ARG], [ ]) # LC_HAVE_CLASS_CREATE_MODULE_ARG # +# LC_HAVE_FILEMAP_SPLICE_READ +# +# linux kernel v6.4-rc2-29-gc6585011bc1d +# splice: Remove generic_file_splice_read() +# +AC_DEFUN([LC_SRC_HAVE_FILEMAP_SPLICE_READ], [ + LB2_LINUX_TEST_SRC([filemap_splice_read], [ + #include + ],[ + struct file *in = NULL; + loff_t pos = 0; + struct pipe_inode_info *pipe = NULL; + ssize_t count __attribute__ ((unused)); + + count = filemap_splice_read(in, &pos, pipe, 0, 0); + ],[-Werror]) +]) +AC_DEFUN([LC_HAVE_FILEMAP_SPLICE_READ], [ + LB2_MSG_LINUX_TEST_RESULT([if 'filemap_splice_read' is available], + [filemap_splice_read], [ + AC_DEFINE(HAVE_FILEMAP_SPLICE_READ, 1, + ['filemap_splice_read' is available]) + ]) +]) # LC_HAVE_FILEMAP_SPLICE_READ + +# +# LC_HAVE_ENUM_ITER_PIPE +# +# linux kernel v6.4-rc2-30-g3fc40265ae2b +# iov_iter: Kill ITER_PIPE +# +AC_DEFUN([LC_SRC_HAVE_ENUM_ITER_PIPE], [ + LB2_LINUX_TEST_SRC([enum_iter_type_iter_pipe], [ + #include + ],[ + enum iter_type iter_type = ITER_PIPE; + + (void)iter_type; + ],[-Werror]) +]) +AC_DEFUN([LC_HAVE_ENUM_ITER_PIPE], [ + LB2_MSG_LINUX_TEST_RESULT([if enum iter_type has member 'iter_pipe'], + [enum_iter_type_iter_pipe], [ + AC_DEFINE(HAVE_ENUM_ITER_PIPE, 1, + [enum iter_type has member 'iter_pipe']) + ]) +]) # LC_HAVE_ENUM_ITER_PIPE + +# +# LC_HAVE_GET_USER_PAGES_WITHOUT_VMA +# +# linux kernel v6.4-rc2-30-g3fc40265ae2b +# iov_iter: Kill ITER_PIPE +# +AC_DEFUN([LC_SRC_HAVE_GET_USER_PAGES_WITHOUT_VMA], [ + LB2_LINUX_TEST_SRC([get_user_pages_without_vma], [ + #include + ],[ + struct page *pages __attribute__ ((unused)); + + (void)get_user_pages(0, 0, 0, &pages); + ],[-Werror]) +]) +AC_DEFUN([LC_HAVE_GET_USER_PAGES_WITHOUT_VMA], [ + LB2_MSG_LINUX_TEST_RESULT([if get_user_pages removed 'vma' parameter], + [get_user_pages_without_vma], [ + AC_DEFINE(HAVE_GET_USER_PAGES_WITHOUT_VMA, 1, + [get_user_pages removed 'vma' parameter]) + ]) +]) # LC_HAVE_GET_USER_PAGES_WITHOUT_VMA + +# # LC_PROG_LINUX # # Lustre linux kernel checks @@ -4332,6 +4404,11 @@ AC_DEFUN([LC_PROG_LINUX_SRC], [ LC_SRC_HAVE_IOVEC_WITH_IOV_MEMBER LC_SRC_HAVE_CLASS_CREATE_MODULE_ARG + # 6.5 + LC_SRC_HAVE_FILEMAP_SPLICE_READ + LC_SRC_HAVE_ENUM_ITER_PIPE + LC_SRC_HAVE_GET_USER_PAGES_WITHOUT_VMA + # kernel patch to extend integrity interface LC_SRC_BIO_INTEGRITY_PREP_FN ]) @@ -4617,6 +4694,11 @@ AC_DEFUN([LC_PROG_LINUX_RESULTS], [ LC_HAVE_IOVEC_WITH_IOV_MEMBER LC_HAVE_CLASS_CREATE_MODULE_ARG + # 6.5 + LC_HAVE_FILEMAP_SPLICE_READ + LC_HAVE_ENUM_ITER_PIPE + LC_HAVE_GET_USER_PAGES_WITHOUT_VMA + # kernel patch to extend integrity interface LC_BIO_INTEGRITY_PREP_FN ]) diff --git a/lustre/llite/file.c b/lustre/llite/file.c index b5ec1e0..da15b10 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -50,6 +50,7 @@ #include #include +#include #include "cl_object.h" #include "llite_internal.h" @@ -1799,7 +1800,7 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args, * to pipes */ is_parallel_dio = !iov_iter_is_pipe(args->u.normal.via_iter) && - !is_aio; + !is_aio; if (!ll_sbi_has_parallel_dio(sbi)) is_parallel_dio = false; @@ -5982,6 +5983,14 @@ int ll_inode_permission(struct mnt_idmap *idmap, struct inode *inode, int mask) RETURN(rc); } +#if defined(HAVE_FILEMAP_SPLICE_READ) +# define ll_splice_read filemap_splice_read +#elif !defined(HAVE_DEFAULT_FILE_SPLICE_READ_EXPORT) +# define ll_splice_read generic_file_splice_read +#else +# define ll_splice_read pcc_file_splice_read +#endif + /* -o localflock - only provides locally consistent flock locks */ static const struct file_operations ll_file_operations = { #ifdef HAVE_FILE_OPERATIONS_READ_WRITE_ITER @@ -6002,11 +6011,7 @@ static const struct file_operations ll_file_operations = { .release = ll_file_release, .mmap = ll_file_mmap, .llseek = ll_file_seek, -#ifndef HAVE_DEFAULT_FILE_SPLICE_READ_EXPORT - .splice_read = generic_file_splice_read, -#else - .splice_read = pcc_file_splice_read, -#endif + .splice_read = ll_splice_read, #ifdef HAVE_ITER_FILE_SPLICE_WRITE .splice_write = iter_file_splice_write, #endif @@ -6034,11 +6039,7 @@ static const struct file_operations ll_file_operations_flock = { .release = ll_file_release, .mmap = ll_file_mmap, .llseek = ll_file_seek, -#ifndef HAVE_DEFAULT_FILE_SPLICE_READ_EXPORT - .splice_read = generic_file_splice_read, -#else - .splice_read = pcc_file_splice_read, -#endif + .splice_read = ll_splice_read, #ifdef HAVE_ITER_FILE_SPLICE_WRITE .splice_write = iter_file_splice_write, #endif @@ -6069,11 +6070,7 @@ static const struct file_operations ll_file_operations_noflock = { .release = ll_file_release, .mmap = ll_file_mmap, .llseek = ll_file_seek, -#ifndef HAVE_DEFAULT_FILE_SPLICE_READ_EXPORT - .splice_read = generic_file_splice_read, -#else - .splice_read = pcc_file_splice_read, -#endif + .splice_read = ll_splice_read, #ifdef HAVE_ITER_FILE_SPLICE_WRITE .splice_write = iter_file_splice_write, #endif diff --git a/lustre/obdclass/jobid.c b/lustre/obdclass/jobid.c index 422d85c..5efc951 100644 --- a/lustre/obdclass/jobid.c +++ b/lustre/obdclass/jobid.c @@ -222,7 +222,7 @@ static int cfs_access_process_vm(struct task_struct *tsk, /* Just copied from kernel for the kernels which doesn't * have access_process_vm() exported */ - struct vm_area_struct *vma; + struct vm_area_struct *vma = NULL; struct page *page; void *old_buf = buf; @@ -239,7 +239,11 @@ static int cfs_access_process_vm(struct task_struct *tsk, int bytes, rc, offset; void *maddr; -#if defined(HAVE_GET_USER_PAGES_GUP_FLAGS) +#if defined(HAVE_GET_USER_PAGES_WITHOUT_VMA) + rc = get_user_pages(addr, 1, write ? FOLL_WRITE : 0, &page); + if (rc > 0) + vma = vma_lookup(mm, addr); +#elif defined(HAVE_GET_USER_PAGES_GUP_FLAGS) rc = get_user_pages(addr, 1, write ? FOLL_WRITE : 0, &page, &vma); #elif defined(HAVE_GET_USER_PAGES_6ARG) @@ -247,7 +251,7 @@ static int cfs_access_process_vm(struct task_struct *tsk, #else rc = get_user_pages(tsk, mm, addr, 1, write, 1, &page, &vma); #endif - if (rc <= 0) + if (rc <= 0 || !vma) break; bytes = len; diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index bc3ceaa..8733554 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -67,10 +67,8 @@ #include "osd_scrub.h" #include "osd_quota_fmt.h" -#if IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY) - #ifdef HAVE_LINUX_BLK_INTEGRITY_HEADER - #include - #endif +#ifdef HAVE_LINUX_BLK_INTEGRITY_HEADER + #include #endif struct inode; -- 1.8.3.1