From bb5b276d6036735cfacad9b27e8d0e50eb2ef819 Mon Sep 17 00:00:00 2001 From: Cheyenne Wills Date: Tue, 29 Aug 2023 14:58:10 -0600 Subject: [PATCH 5/9] linux: Replace fop iterate with fop iterate_shared The Linux 6.5 commit: 'vfs: get rid of old '->iterate' directory operation' (3e32715496) removed the filesystem_operations iterate method. The replacement method, iterate_shared, was introduced with the Linux 4.6 commit: 'introduce a parallel variant of ->iterate()' (6192269444) The above commits indicate that the iterate_shared is an "almost" drop-in replacement for iterate. The vfs documentation for iterate_shared has caveats on the implementation (serializing in-core per-inode or per-dentry modifications and using d_alloc_parallel if doing dcache pre-seeding). A wrapper is provided to assist filesystems with the migration from iterate to iterate_shared. Until it can be verified that afs_linux_readdir meets the above requirements, we will use the wrapper (ref 3e32715496 commit) Add configure tests for the iterate_shared file_operations member and for the wrap_directory_iterator function. Update osi_vnodeops.c to use iterate_shared and the wrapper if they are both available. Reviewed-on: https://gerrit.openafs.org/15528 Reviewed-by: Benjamin Kaduk Reviewed-by: Andrew Deason Tested-by: BuildBot (cherry picked from commit 7437f4d37719ea53711e06ac9675dad1abd6769e) Change-Id: Id00cfab2c0b51c2167fe19cd9cf7f136450ff174 Reviewed-on: https://gerrit.openafs.org/15558 Tested-by: BuildBot Reviewed-by: Mark Vitale Reviewed-by: Michael Meffie Reviewed-by: Stephan Wiesand (cherry picked from commit 6de0a646036283266e1d4aeb583e426005ca5ad4) --- src/afs/LINUX/osi_vnodeops.c | 19 +++++++++++++++---- src/cf/linux-kernel-func.m4 | 10 ++++++++++ src/cf/linux-kernel-struct.m4 | 1 + 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index dd8b39d5d..fb62752e6 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -54,14 +54,16 @@ # define D_SPLICE_ALIAS_RACE #endif +#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE_SHARED) && defined(HAVE_LINUX_WRAP_DIRECTORY_ITERATOR) +# define USE_FOP_ITERATE 1 +#elif defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) && !defined(FMODE_KABI_ITERATE) /* Workaround for RH 7.5 which introduced file operation iterate() but requires * each file->f_mode to be marked with FMODE_KABI_ITERATE. Instead OpenAFS will * continue to use file opearation readdir() in this case. */ -#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE) && !defined(FMODE_KABI_ITERATE) -#define USE_FOP_ITERATE 1 +# define USE_FOP_ITERATE 1 #else -#undef USE_FOP_ITERATE +# undef USE_FOP_ITERATE #endif /* Kernels from before 2.6.19 may not be able to return errors from @@ -909,10 +911,19 @@ out: crfree(credp); return afs_convert_code(code); } +#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE_SHARED) && defined(HAVE_LINUX_WRAP_DIRECTORY_ITERATOR) +# if defined(WRAP_DIR_ITER) +WRAP_DIR_ITER(afs_linux_readdir) /* Adds necessary locking for iterate_shared */ +# else +# error the Linux provided macro WRAP_DIR_ITER is not available +# endif +#endif struct file_operations afs_dir_fops = { .read = generic_read_dir, -#if defined(USE_FOP_ITERATE) +#if defined(STRUCT_FILE_OPERATIONS_HAS_ITERATE_SHARED) && defined(HAVE_LINUX_WRAP_DIRECTORY_ITERATOR) + .iterate_shared = shared_afs_linux_readdir, +#elif defined(USE_FOP_ITERATE) .iterate = afs_linux_readdir, #else .readdir = afs_linux_readdir, diff --git a/src/cf/linux-kernel-func.m4 b/src/cf/linux-kernel-func.m4 index 811954915..145725575 100644 --- a/src/cf/linux-kernel-func.m4 +++ b/src/cf/linux-kernel-func.m4 @@ -225,6 +225,16 @@ AC_CHECK_LINUX_FUNC([register_sysctl], #include ], [(void)register_sysctl(NULL, NULL);]) +dnl Linux 6.5 removed the file_operations method 'iterate'. Filesystems should +dnl using the iterate_shared method (introduced in linux 4.6). Linux 6.4 +dnl provides a wrapper that can be used for filesystems that haven't fully +dnl converted to meet the iterate_shared requirements. + +AC_CHECK_LINUX_FUNC([wrap_directory_iterator], + [#include + #include ], + [(void)wrap_directory_iterator(NULL, NULL, NULL);]) + 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"], diff --git a/src/cf/linux-kernel-struct.m4 b/src/cf/linux-kernel-struct.m4 index 8082308e8..52e10acb8 100644 --- a/src/cf/linux-kernel-struct.m4 +++ b/src/cf/linux-kernel-struct.m4 @@ -23,6 +23,7 @@ AC_CHECK_LINUX_STRUCT([inode], [i_mutex], [fs.h]) AC_CHECK_LINUX_STRUCT([inode], [i_security], [fs.h]) AC_CHECK_LINUX_STRUCT([file], [f_path], [fs.h]) AC_CHECK_LINUX_STRUCT([file_operations], [flock], [fs.h]) +AC_CHECK_LINUX_STRUCT([file_operations], [iterate_shared], [fs.h]) AC_CHECK_LINUX_STRUCT([file_operations], [iterate], [fs.h]) AC_CHECK_LINUX_STRUCT([file_operations], [read_iter], [fs.h]) AC_CHECK_LINUX_STRUCT([file_operations], [sendfile], [fs.h]) -- 2.42.1