From 247ae64877b38a0e9aae60fd496d253bfeba665d Mon Sep 17 00:00:00 2001 From: Shaun Tancheff Date: Mon, 5 May 2025 10:03:42 -0700 Subject: [PATCH] LU-17081 build: compatibility for 6.5 kernels MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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. Lustre-change: https://review.whamcloud.com/52258 Lustre-commit: 2bb54b6383d57ac61092593b9e6d9c80801263f5 Was-Change-Id: I95a0954a602c8db08d30b38a50dcd50107c8f268 LU-17193 build: fix gcc-12 compiler warnings Building on el9.2 hit a couple of new errors in configure, ex: ((struct inode_operations *)1)->fileattr_get() hits: error: array subscript 0 is outside array bounds of ‘struct inode_operations[0]’ A few instances of QCTL_COPY() should be QCTL_COPY_NO_PNAME() as the zero-length array to hold the pool name is not allocated in these cases. Lustre-change: https://review.whamcloud.com/52687 Lustre-commit: 1b0de05f81372eeda9a2a38142553ead7e88a431 Was-Change-Id: I72bda8b46c51dbd42fb42bf569ba29572526acfe LU-13485 libcfs: Remove unused iter_type check The iter_type member check is not used, remove it. Lustre-change: https://review.whamcloud.com/48091 Lustre-commit: c755373c567090c49589e5aa0d3134847d4b952e Was-Change-Id: I48d536a27738e73314feb88317d41d8479c72528 HPE-bug-id: LUS-11811 Signed-off-by: Shaun Tancheff Change-Id: I95a0954a602c8db08d30b38a50dcd50107c8f268 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/59097 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Yang Sheng Reviewed-by: Oleg Drokin --- libcfs/autoconf/lustre-libcfs.m4 | 25 -------- libcfs/include/libcfs/linux/linux-misc.h | 21 ++++++- lnet/klnds/socklnd/socklnd_lib.c | 30 ++++++--- lustre/autoconf/lustre-core.m4 | 88 ++++++++++++++++++++++++++- lustre/include/uapi/linux/lustre/lustre_idl.h | 20 +++--- lustre/llite/file.c | 29 ++++----- lustre/lmv/lmv_obd.c | 2 +- lustre/lov/lov_obd.c | 2 +- lustre/mdc/mdc_request.c | 2 +- lustre/obdclass/jobid.c | 10 ++- lustre/osd-ldiskfs/osd_internal.h | 6 +- 11 files changed, 164 insertions(+), 71 deletions(-) diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4 index b777240..9ed0e43 100644 --- a/libcfs/autoconf/lustre-libcfs.m4 +++ b/libcfs/autoconf/lustre-libcfs.m4 @@ -2105,29 +2105,6 @@ AC_DEFUN([LIBCFS_HAVE_TASK_IS_RUNNING], [ ]) # LIBCFS_HAVE_TASK_IS_RUNNING # -# LIBCFS_IOV_ITER_HAS_ITER_TYPE -# -# kernel 5.13 commit 8cd54c1c848031a87820e58d772166ffdf8c08c0 change -# ->type to ->iter_type -# -AC_DEFUN([LIBCFS_SRC_IOV_ITER_HAS_ITER_TYPE], [ - LB2_LINUX_TEST_SRC([iov_iter_has_iter_type_member], [ - #include - ],[ - struct iov_iter iter = { .iter_type = ITER_KVEC }; - (void)iter; - ], - [-Werror]) -]) -AC_DEFUN([LIBCFS_IOV_ITER_HAS_ITER_TYPE], [ - AC_MSG_CHECKING([if iov_iter has member type]) - LB2_LINUX_TEST_RESULT([iov_iter_has_iter_type_member], [ - AC_DEFINE(HAVE_IOV_ITER_HAS_ITER_TYPE_MEMBER, 1, - [if iov_iter has member iter_type]) - ]) -]) # LIBCFS_IOV_ITER_HAS_ITER_TYPE - -# # LIBCFS_LINUX_STDARG_HEADER # # Kernel 5.14-rc5 commit c0891ac15f0428ffa81b2e818d416bdf3cb74ab6 @@ -2407,7 +2384,6 @@ AC_DEFUN([LIBCFS_PROG_LINUX_SRC], [ LIBCFS_SRC_LINUX_FORTIFY_STRING_HEADER # 5.13 LIBCFS_SRC_HAVE_TASK_IS_RUNNING - LIBCFS_SRC_IOV_ITER_HAS_ITER_TYPE # 5.15 LIBCFS_SRC_PARAM_SET_UINT_MINMAX # 5.17 @@ -2550,7 +2526,6 @@ AC_DEFUN([LIBCFS_PROG_LINUX_RESULTS], [ LIBCFS_LINUX_FORTIFY_STRING_HEADER # 5.13 LIBCFS_HAVE_TASK_IS_RUNNING - LIBCFS_IOV_ITER_HAS_ITER_TYPE # 5.15 LIBCFS_PARAM_SET_UINT_MINMAX # 5.17 diff --git a/libcfs/include/libcfs/linux/linux-misc.h b/libcfs/include/libcfs/linux/linux-misc.h index f8b19e1..b567e7e 100644 --- a/libcfs/include/libcfs/linux/linux-misc.h +++ b/libcfs/include/libcfs/linux/linux-misc.h @@ -42,12 +42,31 @@ #include #include -#ifndef HAVE_IOV_ITER_TYPE +/* + * Since 4.20 commit 00e23707442a75b404392cef1405ab4fd498de6b + * iov_iter: Use accessor functions to access an iterator's type and direction. + * iter_is_iovec() and iov_iter_is_* are available, supply the missing + * functionality for older kernels. + */ +#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. + * Prior to this only iovec is supported, so all iov_iter_is_* are false. + */ #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) +#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 46cb3c6..5a87726 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 ef06abb..3f21854 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -2957,8 +2957,10 @@ AC_DEFUN([LC_SRC_HAVE_USER_NAMESPACE_ARG], [ LB2_LINUX_TEST_SRC([inode_ops_has_user_namespace_argument], [ #include ],[ - ((struct inode_operations *)1)->getattr((struct user_namespace *)NULL, - NULL, NULL, 0, 0); + struct inode_operations *iops = NULL; + struct user_namespace *user_ns = NULL; + + iops->getattr(user_ns, NULL, NULL, 0, 0); ],[-Werror]) ]) AC_DEFUN([LC_HAVE_USER_NAMESPACE_ARG], [ @@ -3714,6 +3716,78 @@ AC_DEFUN([LC_HAVE_LOCKS_LOCK_FILE_WAIT_IN_FILELOCK], [ ]) # LC_HAVE_LOCKS_LOCK_FILE_WAIT_IN_FILELOCK # +# 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], [ + AC_MSG_CHECKING([if 'filemap_splice_read' is available]) + LB2_LINUX_TEST_RESULT([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], [ + AC_MSG_CHECKING([if enum iter_type has member 'iter_pipe']) + LB2_LINUX_TEST_RESULT([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], [ + AC_MSG_CHECKING([if get_user_pages removed 'vma' parameter]) + LB2_LINUX_TEST_RESULT([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 @@ -3958,6 +4032,11 @@ AC_DEFUN([LC_PROG_LINUX_SRC], [ LC_SRC_HAVE_LOCKS_LOCK_FILE_WAIT_IN_FILELOCK LC_SRC_HAVE_U64_CAPABILITY + # 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 ]) @@ -4215,6 +4294,11 @@ AC_DEFUN([LC_PROG_LINUX_RESULTS], [ LC_HAVE_LOCKS_LOCK_FILE_WAIT_IN_FILELOCK LC_HAVE_U64_CAPABILITY + # 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/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index cfcbdab..ef6d11f 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -1509,11 +1509,7 @@ struct obd_quotactl { #define Q_COPY(out, in, member) (out)->member = (in)->member -/* NOTE: - * - in and out maybe a type of struct if_quotactl or struct obd_quotactl - * - in and out need not be of the same type. - */ -#define __QCTL_COPY(out, in, need_pname) \ +#define QCTL_COPY_NO_PNAME(out, in) \ do { \ Q_COPY(out, in, qc_cmd); \ Q_COPY(out, in, qc_type); \ @@ -1521,7 +1517,16 @@ do { \ Q_COPY(out, in, qc_stat); \ Q_COPY(out, in, qc_dqinfo); \ Q_COPY(out, in, qc_dqblk); \ - if (need_pname && LUSTRE_Q_CMD_IS_POOL(in->qc_cmd)) { \ +} while (0) + +/* NOTE: + * - in and out maybe a type of struct if_quotactl or struct obd_quotactl + * - in and out need not be of the same type. + */ +#define QCTL_COPY(out, in) \ +do { \ + QCTL_COPY_NO_PNAME(out, in); \ + if (LUSTRE_Q_CMD_IS_POOL(in->qc_cmd)) { \ size_t len = strnlen(in->qc_poolname, LOV_MAXPOOLNAME); \ \ memcpy(out->qc_poolname, in->qc_poolname, len); \ @@ -1529,9 +1534,6 @@ do { \ } \ } while (0) -#define QCTL_COPY(out, in) __QCTL_COPY(out, in, true) -#define QCTL_COPY_NO_PNAME(out, in) __QCTL_COPY(out, in, false) - /* Body of quota request used for quota acquire/release RPCs between quota * master (aka QMT) and slaves (ak QSD). */ struct quota_body { diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 82c7867..fd02819 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" @@ -1686,7 +1687,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; @@ -5700,6 +5701,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 @@ -5720,11 +5729,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 @@ -5752,11 +5757,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 @@ -5787,11 +5788,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/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index ebd142d..187bae8 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -905,7 +905,7 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp, QCTL_COPY(oqctl, qctl); rc = obd_quotactl(tgt->ltd_exp, oqctl); if (rc == 0) { - QCTL_COPY(qctl, oqctl); + QCTL_COPY_NO_PNAME(qctl, oqctl); qctl->qc_valid = QC_MDTIDX; qctl->obd_uuid = tgt->ltd_uuid; } diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 7c3153c..89ed3ef 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -1048,7 +1048,7 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, QCTL_COPY(oqctl, qctl); rc = obd_quotactl(tgt->ltd_exp, oqctl); if (rc == 0) { - QCTL_COPY(qctl, oqctl); + QCTL_COPY_NO_PNAME(qctl, oqctl); qctl->qc_valid = QC_OSTIDX; qctl->obd_uuid = tgt->ltd_uuid; } diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index b71bb81..163f11a1 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -2255,7 +2255,7 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, QCTL_COPY(oqctl, qctl); rc = obd_quotactl(exp, oqctl); if (rc == 0) { - QCTL_COPY(qctl, oqctl); + QCTL_COPY_NO_PNAME(qctl, oqctl); qctl->qc_valid = QC_MDTIDX; qctl->obd_uuid = obd->u.cli.cl_target_uuid; } diff --git a/lustre/obdclass/jobid.c b/lustre/obdclass/jobid.c index 207a88b..4edd308 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 72559bb..aeabe5d 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -66,10 +66,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