Linux: Test for missing generic_file_splice_read

In commit:
    'Linux 6.5: Replace generic_file_splice_read' (0e06eb78f2)
we check the version of Linux to determine to use the newer
filemap_splice_read() or the older generic_file_splice_read().

openSUSE 15.6 uses a Linux 6.4 kernel, but is also including the
Linux 6.5 commit:
    'splice: Remove generic_file_splice_read()' (c6585011bc)
When this commit included in Linux 6.4, the kernel module fails to
build.

In order to handle the case where Linux distributions are including the
(c6585011bc) commit in earlier kernels, we need to see if
generic_file_splice_read() is present; if not, we should use the newer
filemap_splice_read().

With the (0e06eb78f2) commit there was a preference for using
generic_file_splice_read() over filemap_splice_read() until Linux 6.5
(which contained additional updates surrounding filemap_splice_read()).
See the (0e06eb78f2) commit for additional details.

With this commit, we are still preferring generic_file_splice_read()
when it is available on kernels less than Linux 6.5.

Change-Id: Idfc75e474d4e21a9375ee115dad0929bad482e27
Reviewed-on: https://gerrit.openafs.org/15846
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
This commit is contained in:
Cheyenne Wills 2024-09-09 10:04:20 -06:00 committed by Michael Meffie
parent 6e5cbd7ccb
commit 8d4d197f0a
2 changed files with 28 additions and 1 deletions

View File

@ -1013,7 +1013,7 @@ struct file_operations afs_file_fops = {
# else
.splice_write = generic_file_splice_write,
# endif
# if LINUX_VERSION_CODE >= KERNEL_VERSION(6,5,0)
# if defined(HAVE_LINUX_NO_GENERIC_FILE_SPLICE_READ)
.splice_read = filemap_splice_read,
# else
.splice_read = generic_file_splice_read,

View File

@ -264,6 +264,33 @@ AC_CHECK_LINUX_FUNC([filemap_alloc_folio],
[[static struct folio *folio;
folio = filemap_alloc_folio(0, 0);]])
dnl Linux 6.3 introduced filemap_splice_read(), which is a replacement for
dnl generic_file_splice_read(). But filemap_splice_read() at this point was not
dnl fully supported for use with all filesystems.
dnl
dnl Linux 6.5 removed generic_file_splice_read(), and changed
dnl filemap_splice_read() to be supported for all filesystems.
dnl
dnl To decide which function to use, we cannot simply check for
dnl filemap_splice_read(), since we need to avoid using filemap_splice_read()
dnl until it was fixed in Linux 6.5. We cannot simply check the Linux version
dnl number, since some downstream kernels fix filemap_splice_read() and remove
dnl generic_file_splice_read() before Linux 6.5 (e.g., openSUSE 15.6).
dnl
dnl To decide what function to use, we check if generic_file_splice_read() is
dnl missing. If generic_file_splice_read() is missing, use
dnl filemap_splice_read(); otherwise, use generic_file_splice_read().
dnl
dnl To check if generic_file_splice_read() is missing, define our own
dnl generic_file_splice_read() function with a conflicting signature. If we can
dnl define it, the real generic_file_splice_read() must be missing.
AC_CHECK_LINUX_FUNC([no_generic_file_splice_read],
[[#include <linux/fs.h>
char *generic_file_splice_read(char *p);
char *generic_file_splice_read(char *p) { return p + 1; }]],
[[static char buff[10], *ap;
ap = generic_file_splice_read(buff); ]])
dnl Consequences - things which get set as a result of the
dnl above tests
AS_IF([test "x$ac_cv_linux_func_d_alloc_anon" = "xno"],