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.

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>
(cherry picked from commit 8d4d197f0a3880e4dde3580ee9cd84bc20d587ee)

Change-Id: I900a30d8090b06e23c6b7f2daced3a9533a02d1b
Reviewed-on: https://gerrit.openafs.org/15858
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Tested-by: Michael Meffie <mmeffie@sinenomine.net>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
Tested-by: Cheyenne Wills <cwills@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
This commit is contained in:
Cheyenne Wills 2024-09-09 10:04:20 -06:00 committed by Benjamin Kaduk
parent d17a07767d
commit 7ce5fc35e6
2 changed files with 28 additions and 1 deletions

View File

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

View File

@ -273,6 +273,33 @@ AC_CHECK_LINUX_FUNC([filemap_alloc_folio],
[[static struct folio *folio; [[static struct folio *folio;
folio = filemap_alloc_folio(0, 0);]]) 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 Consequences - things which get set as a result of the
dnl above tests dnl above tests
AS_IF([test "x$ac_cv_linux_func_d_alloc_anon" = "xno"], AS_IF([test "x$ac_cv_linux_func_d_alloc_anon" = "xno"],