* 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.
#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
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)
* 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;
]) # 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 <linux/fs.h>
+ ],[
+ 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 <linux/uio.h>
+ ],[
+ 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 <linux/mm.h>
+ ],[
+ 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
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
])
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
])
#include <uapi/linux/lustre/lustre_ioctl.h>
#include <lustre_swab.h>
+#include <libcfs/linux/linux-misc.h>
#include "cl_object.h"
#include "llite_internal.h"
* 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;
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
.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
.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
.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
/* 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;
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)
#else
rc = get_user_pages(tsk, mm, addr, 1, write, 1, &page, &vma);
#endif
- if (rc <= 0)
+ if (rc <= 0 || !vma)
break;
bytes = len;
#include "osd_scrub.h"
#include "osd_quota_fmt.h"
-#if IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY)
- #ifdef HAVE_LINUX_BLK_INTEGRITY_HEADER
- #include <linux/blk-integrity.h>
- #endif
+#ifdef HAVE_LINUX_BLK_INTEGRITY_HEADER
+ #include <linux/blk-integrity.h>
#endif
struct inode;