diff options
author | Michael Laß | 2022-06-01 19:18:57 +0200 |
---|---|---|
committer | Michael Laß | 2022-06-01 21:25:59 +0200 |
commit | b86ee59da99b5ea488154b889b304e209e11aaee (patch) | |
tree | 065b9f773b6474f58c4846d64303af77b2e47621 | |
parent | fdadd93e0a42bf652e43c003c894d3e3b7232b0f (diff) | |
download | aur-b86ee59da99b5ea488154b889b304e209e11aaee.tar.gz |
Make compatible with Linux 5.18
This is a non-trivial set of backports from master to allow building
against Linux 5.18. Use at your own risk.
-rw-r--r-- | .SRCINFO | 26 | ||||
-rw-r--r-- | 0001-Add-autoconf-archive-to-src-external.patch | 9 | ||||
-rw-r--r-- | 0002-Import-of-code-from-autoconf-archive.patch | 9 | ||||
-rw-r--r-- | 0003-Use-autoconf-archive-m4-from-src-external.patch | 9 | ||||
-rw-r--r-- | 0004-Linux-5.17-kernel-func-complete_and_exit-renamed.patch | 9 | ||||
-rw-r--r-- | 0005-Linux-5.17-Kernel-build-uses-Wcast-function-type.patch | 9 | ||||
-rw-r--r-- | 0006-Linux-5.18-replace-set_page_dirty-with-dirty_folio.patch | 64 | ||||
-rw-r--r-- | 0007-afs-remove-vestigial-externs-for-afs_xcbhash.patch | 125 | ||||
-rw-r--r-- | 0008-afs-introduce-afs_alloc_ncr-afs_free_ncr.patch | 255 | ||||
-rw-r--r-- | 0009-LINUX-Don-t-panic-on-some-file-open-errors.patch | 127 | ||||
-rw-r--r-- | 0010-afs-Introduce-afs_IsDCacheFresh.patch | 371 | ||||
-rw-r--r-- | 0011-afs-introduce-get_dcache_readahead.patch | 146 | ||||
-rw-r--r-- | 0012-Linux-5.18-replace-readpages-with-readahead.patch | 304 | ||||
-rw-r--r-- | PKGBUILD | 55 |
14 files changed, 1481 insertions, 37 deletions
@@ -1,7 +1,7 @@ pkgbase = openafs-modules pkgdesc = Kernel module for OpenAFS pkgver = 1.8.8.1 - pkgrel = 2 + pkgrel = 3 url = http://www.openafs.org install = openafs-modules.install arch = i686 @@ -20,11 +20,25 @@ pkgbase = openafs-modules source = 0003-Use-autoconf-archive-m4-from-src-external.patch source = 0004-Linux-5.17-kernel-func-complete_and_exit-renamed.patch source = 0005-Linux-5.17-Kernel-build-uses-Wcast-function-type.patch + source = 0006-Linux-5.18-replace-set_page_dirty-with-dirty_folio.patch + source = 0007-afs-remove-vestigial-externs-for-afs_xcbhash.patch + source = 0008-afs-introduce-afs_alloc_ncr-afs_free_ncr.patch + source = 0009-LINUX-Don-t-panic-on-some-file-open-errors.patch + source = 0010-afs-Introduce-afs_IsDCacheFresh.patch + source = 0011-afs-introduce-get_dcache_readahead.patch + source = 0012-Linux-5.18-replace-readpages-with-readahead.patch sha256sums = e7c4bed7075bcd6402e3f0c2d5b9dbe76ad2ee3c5fd5ddc3973a3356ca23ef44 - sha256sums = 67bad31f8a401f1fa4e851a1f8d2d772f6649573f81045cafae94c105bbff173 - sha256sums = 16ced06d3d4ffffa251e20aecd1ccb3fedb4585617b004b8ade0b4eab603b17d - sha256sums = 3b2aa3343fe4b9401b272fcf0252f4c3f108f1a1e5039718de38b803690c9d74 - sha256sums = c9623eac1e8faf2be133d69c6146eb68be800de0c3226acd99848348b5bfd2f4 - sha256sums = 17c71196bf5f1fc1c62bab8f03a102d7ca75fec56de94390851b10bd27efa3e9 + sha256sums = cbf078639b9b25d1e9ec191b9c340720f1fe5ebd1b7665c2ea762498fcf66fbf + sha256sums = f1feac79a69b9ecff4c7259842184e16ef1213e9fb5a2601c4963ea3dc12041c + sha256sums = 97410d4f5a7a09254ffa18411f242234aba483a0a7b989503ee831457c0ddb9f + sha256sums = 47faddb068dcbbea74c973c23aac7fe29b1482e984a37b5cfee283200da6b9e2 + sha256sums = 45fa5eaa7b0e7e7bc6c9e0b7c5d97e5fefc54f60c084d5e7deddbe2c0c4697e9 + sha256sums = d42fa0772193cd6a66e09ba9cdb81b77c636a266caaf0c465331ff7ca3925b1c + sha256sums = b47e4d5405961b7d40bd24e50c18740b9cd85a90e0e7f630101602efb2f12c2f + sha256sums = 9801be6de6399a2e0d899b0ed71bc5881ede5a926720d32377a24db31b035593 + sha256sums = ce21b7ed721d685fb0f1ddf068003410b585e09be7a96daeb1e8bb10378cf4b3 + sha256sums = 7a5410bce86f1471ae5d990b68f2b25fcff8d5f32d2b7fd9e29c098a91ef1cef + sha256sums = 4816b8502366995eb5e8e58e485db910269a118ea6ed67e8f16e6bc1aab53864 + sha256sums = b51739e2670d13a46f0936fd50ef4bfadf40e83b22a53d46dd7b0eb490ebb700 pkgname = openafs-modules diff --git a/0001-Add-autoconf-archive-to-src-external.patch b/0001-Add-autoconf-archive-to-src-external.patch index 18a3fa55aaec..262ab43c4351 100644 --- a/0001-Add-autoconf-archive-to-src-external.patch +++ b/0001-Add-autoconf-archive-to-src-external.patch @@ -1,7 +1,7 @@ -From 26434fb4376a5db1f38fca8807825fbabc81be7b Mon Sep 17 00:00:00 2001 +From 006616bd8e88b2d386a5ddc23973cf3e625cb80d Mon Sep 17 00:00:00 2001 From: Andrew Deason <adeason@sinenomine.net> Date: Sat, 4 Apr 2020 22:28:21 -0500 -Subject: [PATCH 1/5] Add autoconf-archive to src/external +Subject: [PATCH 01/12] Add autoconf-archive to src/external Add autoconf-archive to the src/external mechanism, so we can more easily import and update the AX_* m4 macros we pull in from @@ -13,12 +13,13 @@ include that in the list of files. While we're here, also include a few more macros for checking compiler flags, which will be used in subsequent commits. -Change-Id: I8c6288fc1d48a47837ca08f8b9207e0ada921af8 Reviewed-on: https://gerrit.openafs.org/14133 Reviewed-by: Cheyenne Wills <cwills@sinenomine.net> Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Benjamin Kaduk <kaduk@mit.edu> (cherry picked from commit a072c65bba86cbcd81157e354d3719ac41a2c97d) + +Change-Id: I785607be9abe85e43287c4880103a365e264473b --- src/external/autoconf-archive-author | 1 + src/external/autoconf-archive-files | 5 +++++ @@ -45,5 +46,5 @@ index 000000000..42c7c3852 +m4/ax_gcc_func_attribute.m4 m4/ax_gcc_func_attribute.m4 +m4/ax_require_defined.m4 m4/ax_require_defined.m4 -- -2.35.1 +2.36.1 diff --git a/0002-Import-of-code-from-autoconf-archive.patch b/0002-Import-of-code-from-autoconf-archive.patch index 731fd0a3c25d..7d5062799ef0 100644 --- a/0002-Import-of-code-from-autoconf-archive.patch +++ b/0002-Import-of-code-from-autoconf-archive.patch @@ -1,7 +1,7 @@ -From 3dd58d1b0d417fcda3b7679aa0f0691f55740c93 Mon Sep 17 00:00:00 2001 +From d3782b1d4e6fd81c5432e95112eb44305f07f272 Mon Sep 17 00:00:00 2001 From: Autoconf Archive Maintainers <autoconf-archive-maintainers@gnu.org> Date: Tue, 7 Apr 2020 10:23:16 -0500 -Subject: [PATCH 2/5] Import of code from autoconf-archive +Subject: [PATCH 02/12] Import of code from autoconf-archive This commit updates the code imported from autoconf-archive to 24358c8c5ca679949ef522964d94e4d1cd1f941a (v2019.01.06) @@ -13,12 +13,13 @@ New files are: m4/ax_gcc_func_attribute.m4 m4/ax_require_defined.m4 -Change-Id: I64e14d1b4d41ebfee82fa92da10239f73e28b4c9 Reviewed-on: https://gerrit.openafs.org/14138 Reviewed-by: Cheyenne Wills <cwills@sinenomine.net> Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Benjamin Kaduk <kaduk@mit.edu> (cherry picked from commit d8205bbb482554812fbe66afa3c337d991a247b6) + +Change-Id: Ibc18f5ddef8b63ba258fa666ada60577a845aa8f --- src/external/autoconf-archive-last | 1 + .../m4/ax_append_compile_flags.m4 | 46 ++++ @@ -496,5 +497,5 @@ index 000000000..17c3eab7d + m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) +])dnl AX_REQUIRE_DEFINED -- -2.35.1 +2.36.1 diff --git a/0003-Use-autoconf-archive-m4-from-src-external.patch b/0003-Use-autoconf-archive-m4-from-src-external.patch index b37a2977cb23..e4eeaed03e19 100644 --- a/0003-Use-autoconf-archive-m4-from-src-external.patch +++ b/0003-Use-autoconf-archive-m4-from-src-external.patch @@ -1,7 +1,7 @@ -From d82a2aa279ddf3ba36e753fe4f9d360ec3ee3206 Mon Sep 17 00:00:00 2001 +From ea2a0e128d71802f61b8da2e44de3c6325c5f328 Mon Sep 17 00:00:00 2001 From: Andrew Deason <adeason@sinenomine.net> Date: Sat, 4 Apr 2020 22:35:07 -0500 -Subject: [PATCH 3/5] Use autoconf-archive m4 from src/external +Subject: [PATCH 03/12] Use autoconf-archive m4 from src/external Switch to using the m4 macros from autoconf-archive in our src/external mechanism, instead of manually-copied versions in src/cf. @@ -12,12 +12,13 @@ also a few new macros pulled in, but they are currently unused. Increase our AC_PREREQ in configure.ac to 2.64, to match the AC_PREREQ in some of the new files. -Change-Id: I8acfe4df7b9a22d9b9e69004c3438034a2dacadb Reviewed-on: https://gerrit.openafs.org/14135 Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Cheyenne Wills <cwills@sinenomine.net> Reviewed-by: Benjamin Kaduk <kaduk@mit.edu> (cherry picked from commit ca847ddf35e336a8bc3159ce4b26f0162417bbd5) + +Change-Id: Ifa43b3869e426fada5bd925b0ae002a0f6436232 --- LICENSE | 15 +++++++++++++++ configure.ac | 2 +- @@ -80,5 +81,5 @@ index 3ada36c6b..3ae1987f0 100755 echo "No aclocal found on your system (looked for aclocal & aclocal-1.10)" exit 1 -- -2.35.1 +2.36.1 diff --git a/0004-Linux-5.17-kernel-func-complete_and_exit-renamed.patch b/0004-Linux-5.17-kernel-func-complete_and_exit-renamed.patch index 4c616e73cfd0..8abbb89b5bf0 100644 --- a/0004-Linux-5.17-kernel-func-complete_and_exit-renamed.patch +++ b/0004-Linux-5.17-kernel-func-complete_and_exit-renamed.patch @@ -1,7 +1,7 @@ -From 1f504c13f7203f7a2122f789ea1d70d8c3182e71 Mon Sep 17 00:00:00 2001 +From a714e865efe41aa1112f6f9c8479112660dacd6f Mon Sep 17 00:00:00 2001 From: Cheyenne Wills <cwills@sinenomine.net> Date: Thu, 27 Jan 2022 20:19:17 -0700 -Subject: [PATCH 4/5] Linux-5.17: kernel func complete_and_exit renamed +Subject: [PATCH 04/12] Linux-5.17: kernel func complete_and_exit renamed Handle the Linux kernel function rename made in commit "exit: Rename complete_and_exit to kthread_complete_and_exit" @@ -13,12 +13,13 @@ complete_and_exit. Replace calls to complete_and_exit with kthread_complete_and_exit. -Change-Id: If8db2d0abb1de8b08f511e9ff67612ef605cd603 Reviewed-on: https://gerrit.openafs.org/14882 Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Andrew Deason <adeason@sinenomine.net> Reviewed-by: Benjamin Kaduk <kaduk@mit.edu> (cherry picked from commit a651d4db7f86a24ea6784f6f27d5c8482667267b) + +Change-Id: Ibe96b92a84a8f876dda4019c221c37dabde93244 --- src/afs/LINUX/osi_compat.h | 4 ++++ src/afs/afs_call.c | 18 ++++++++++-------- @@ -136,5 +137,5 @@ index 0ca3e4463..cd4afe914 100644 dnl above tests AS_IF([test "x$ac_cv_linux_func_d_alloc_anon" = "xno"], -- -2.35.1 +2.36.1 diff --git a/0005-Linux-5.17-Kernel-build-uses-Wcast-function-type.patch b/0005-Linux-5.17-Kernel-build-uses-Wcast-function-type.patch index 5565973657ca..1cc8503ed996 100644 --- a/0005-Linux-5.17-Kernel-build-uses-Wcast-function-type.patch +++ b/0005-Linux-5.17-Kernel-build-uses-Wcast-function-type.patch @@ -1,7 +1,7 @@ -From e71816dc640462aab0870fc46cf1d56b63575f45 Mon Sep 17 00:00:00 2001 +From 449d1faf87e2841e80be38cf2b4a5cf5ff4df2d8 Mon Sep 17 00:00:00 2001 From: Cheyenne Wills <cwills@sinenomine.net> Date: Fri, 28 Jan 2022 14:10:46 -0700 -Subject: [PATCH 5/5] Linux-5.17: Kernel build uses -Wcast-function-type +Subject: [PATCH 05/12] Linux-5.17: Kernel build uses -Wcast-function-type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -35,12 +35,13 @@ Note: upstream heimdal has committed a fix for this in: hcrypto: Fix return type for null_Init, null_Update and null_Final (fc4b3ce49b) -Change-Id: I05b716867016a33ca02a791ed6bc5a7d846de608 Reviewed-on: https://gerrit.openafs.org/14881 Reviewed-by: Benjamin Kaduk <kaduk@mit.edu> Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Andrew Deason <adeason@sinenomine.net> (cherry picked from commit 6bdfa976731ce07f3236893ecf12abb9e169b882) + +Change-Id: Ibd354f663d5876c421a8b4e89b8943c9e3d59ebc --- CODING | 12 +++++++++++- src/cf/osconf.m4 | 4 ++++ @@ -123,5 +124,5 @@ index d98fa05ad..8e98afd56 100644 CFLAGS_rand-timer-kernel.o = -I$(TOP_SRCDIR)/external/heimdal/hcrypto CFLAGS_rand-kernel.o = -I$(TOP_SRCDIR)/external/heimdal/hcrypto -- -2.35.1 +2.36.1 diff --git a/0006-Linux-5.18-replace-set_page_dirty-with-dirty_folio.patch b/0006-Linux-5.18-replace-set_page_dirty-with-dirty_folio.patch new file mode 100644 index 000000000000..631d2e4b9afe --- /dev/null +++ b/0006-Linux-5.18-replace-set_page_dirty-with-dirty_folio.patch @@ -0,0 +1,64 @@ +From 081869eb8ba1733a044468203ab82affe258b359 Mon Sep 17 00:00:00 2001 +From: Cheyenne Wills <cwills@sinenomine.net> +Date: Wed, 30 Mar 2022 11:09:45 -0600 +Subject: [PATCH 06/12] Linux-5.18 replace set_page_dirty with dirty_folio + +The commits going into Linux 5.18: + + fs: Add aops->dirty_folio (6f31a5a261db) + fs: Convert __set_page_dirty_buffers to block_dirty_folio (e621900ad2) + fs: Remove aops ->set_page_dirty (3a3bae50af) + +replaces the address_space_operations structure member set_page_dirty +which with dirty_folio. The linux function __set_page_dirty_buffers is +replaced by block_dirty_folio. + +Nothing within afs uses or implements the set_page_dirty function, +however the structure member is required to be initialized. + +Add an autoconf test for the dirty_folio member and if present, set the +address_space_operations member dirty_folio to block_dirty_folio +instead of setting the set_page_dirty member. + +Change-Id: Iad6783308989f4a1390c1c94d2c571048bd4e771 +Reviewed-on: https://gerrit.openafs.org/14939 +Tested-by: BuildBot <buildbot@rampaginggeek.com> +Reviewed-by: Benjamin Kaduk <kaduk@mit.edu> +(cherry picked from commit 6aa129e743e882cf30c35afd67eabf82274c5fca) +--- + src/afs/LINUX/osi_vnodeops.c | 4 ++++ + src/cf/linux-kernel-struct.m4 | 2 ++ + 2 files changed, 6 insertions(+) + +diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c +index 00103a538..a0c78c04d 100644 +--- a/src/afs/LINUX/osi_vnodeops.c ++++ b/src/afs/LINUX/osi_vnodeops.c +@@ -3288,7 +3288,11 @@ static struct address_space_operations afs_file_aops = { + .readpage = afs_linux_readpage, + .readpages = afs_linux_readpages, + .writepage = afs_linux_writepage, ++#if defined(STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_DIRTY_FOLIO) ++ .dirty_folio = block_dirty_folio, ++#else + .set_page_dirty = __set_page_dirty_buffers, ++#endif + #if defined (STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_WRITE_BEGIN) + .write_begin = afs_linux_write_begin, + .write_end = afs_linux_write_end, +diff --git a/src/cf/linux-kernel-struct.m4 b/src/cf/linux-kernel-struct.m4 +index 003d34ab8..2d8cee655 100644 +--- a/src/cf/linux-kernel-struct.m4 ++++ b/src/cf/linux-kernel-struct.m4 +@@ -3,6 +3,8 @@ dnl Check for structure elements + AC_CHECK_LINUX_STRUCT([address_space], [backing_dev_info], [fs.h]) + AC_CHECK_LINUX_STRUCT([address_space_operations], + [write_begin], [fs.h]) ++dnl linux 5.18 replaced set_page_dirty with dirty_folio ++AC_CHECK_LINUX_STRUCT([address_space_operations], [dirty_folio], [fs.h]) + AC_CHECK_LINUX_STRUCT([backing_dev_info], [name], + [backing-dev.h]) + AC_CHECK_LINUX_STRUCT([cred], [session_keyring], [cred.h]) +-- +2.36.1 + diff --git a/0007-afs-remove-vestigial-externs-for-afs_xcbhash.patch b/0007-afs-remove-vestigial-externs-for-afs_xcbhash.patch new file mode 100644 index 000000000000..231d7b477038 --- /dev/null +++ b/0007-afs-remove-vestigial-externs-for-afs_xcbhash.patch @@ -0,0 +1,125 @@ +From 543eef55043a975c2ede3e8d9457c1456f9186e4 Mon Sep 17 00:00:00 2001 +From: Mark Vitale <mvitale@sinenomine.net> +Date: Wed, 23 Sep 2020 17:02:52 -0400 +Subject: [PATCH 07/12] afs: remove vestigial externs for afs_xcbhash + +Commit 64cc7f0ca7a44bb214396c829268a541ab286c69 "afs: Create +afs_StaleVCache" consolidated many references to afs_xcbhash into a new +function afs_StaleVCache. However, this left many references to 'extern +afs_wrlock_t afs_xcbhash' that are no longer needed. + +But actually, many of these have not been needed since +src/afs/afs_prototypes.h gained 'extern afs_rwlock_t afs_xcbhash' with +commit 8f2df21ffe59e9aa66219bf24656775b584c122d +"pull-prototypes-to-head-20020821" + +Remove the vestigial extern references. + +No functional change is incurred by this commit. + +Change-Id: Ie6cfb6d90c52951795378d3b42e041567d207305 +Reviewed-on: https://gerrit.openafs.org/14405 +Reviewed-by: Andrew Deason <adeason@sinenomine.net> +Tested-by: BuildBot <buildbot@rampaginggeek.com> +Reviewed-by: Benjamin Kaduk <kaduk@mit.edu> +(cherry picked from commit a3fc79633fb0601bf02508bd1e64652f403e4b7e) +--- + src/afs/VNOPS/afs_vnop_attrs.c | 1 - + src/afs/VNOPS/afs_vnop_dirops.c | 1 - + src/afs/VNOPS/afs_vnop_link.c | 2 -- + src/afs/VNOPS/afs_vnop_remove.c | 1 - + src/afs/VNOPS/afs_vnop_rename.c | 2 -- + src/afs/VNOPS/afs_vnop_symlink.c | 1 - + src/afs/afs_bypasscache.c | 2 -- + 7 files changed, 10 deletions(-) + +diff --git a/src/afs/VNOPS/afs_vnop_attrs.c b/src/afs/VNOPS/afs_vnop_attrs.c +index 645cf3c0a..0c2620ed0 100644 +--- a/src/afs/VNOPS/afs_vnop_attrs.c ++++ b/src/afs/VNOPS/afs_vnop_attrs.c +@@ -33,7 +33,6 @@ + #include "afs/nfsclient.h" + #include "afs/afs_osidnlc.h" + +-extern afs_rwlock_t afs_xcbhash; + struct afs_exporter *afs_nfsexporter; + extern struct vcache *afs_globalVp; + #if defined(AFS_HPUX110_ENV) +diff --git a/src/afs/VNOPS/afs_vnop_dirops.c b/src/afs/VNOPS/afs_vnop_dirops.c +index 596651324..4c67c4be4 100644 +--- a/src/afs/VNOPS/afs_vnop_dirops.c ++++ b/src/afs/VNOPS/afs_vnop_dirops.c +@@ -29,7 +29,6 @@ + #include "afs/afs_osidnlc.h" + + extern afs_rwlock_t afs_xvcache; +-extern afs_rwlock_t afs_xcbhash; + + /* don't set CDirty in here because RPC is called synchronously */ + +diff --git a/src/afs/VNOPS/afs_vnop_link.c b/src/afs/VNOPS/afs_vnop_link.c +index f57b7ad49..c74aa36e7 100644 +--- a/src/afs/VNOPS/afs_vnop_link.c ++++ b/src/afs/VNOPS/afs_vnop_link.c +@@ -24,8 +24,6 @@ + #include "afs/nfsclient.h" + #include "afs/afs_osidnlc.h" + +-extern afs_rwlock_t afs_xcbhash; +- + /* Note that we don't set CDirty here, this is OK because the link + * RPC is called synchronously. */ + +diff --git a/src/afs/VNOPS/afs_vnop_remove.c b/src/afs/VNOPS/afs_vnop_remove.c +index 33bc14218..eca9eed24 100644 +--- a/src/afs/VNOPS/afs_vnop_remove.c ++++ b/src/afs/VNOPS/afs_vnop_remove.c +@@ -28,7 +28,6 @@ + + + extern afs_rwlock_t afs_xvcache; +-extern afs_rwlock_t afs_xcbhash; + + + static void +diff --git a/src/afs/VNOPS/afs_vnop_rename.c b/src/afs/VNOPS/afs_vnop_rename.c +index 2d4b9c185..59a1d5032 100644 +--- a/src/afs/VNOPS/afs_vnop_rename.c ++++ b/src/afs/VNOPS/afs_vnop_rename.c +@@ -25,8 +25,6 @@ + #include "afs/nfsclient.h" + #include "afs/afs_osidnlc.h" + +-extern afs_rwlock_t afs_xcbhash; +- + /* Note that we don't set CDirty here, this is OK because the rename + * RPC is called synchronously. */ + +diff --git a/src/afs/VNOPS/afs_vnop_symlink.c b/src/afs/VNOPS/afs_vnop_symlink.c +index e88e09ecc..c9be5f6b7 100644 +--- a/src/afs/VNOPS/afs_vnop_symlink.c ++++ b/src/afs/VNOPS/afs_vnop_symlink.c +@@ -30,7 +30,6 @@ + #include "afs/afs_osidnlc.h" + + extern afs_rwlock_t afs_xvcache; +-extern afs_rwlock_t afs_xcbhash; + + /* Note: There is the bare bones beginning of symlink hints in the now + * defunct afs/afs_lookup.c file. Since they are not in use, making the call +diff --git a/src/afs/afs_bypasscache.c b/src/afs/afs_bypasscache.c +index 64da1ed19..c51bd25c7 100644 +--- a/src/afs/afs_bypasscache.c ++++ b/src/afs/afs_bypasscache.c +@@ -112,8 +112,6 @@ int cache_bypass_strategy = NEVER_BYPASS_CACHE; + afs_size_t cache_bypass_threshold = AFS_CACHE_BYPASS_DISABLED; /* file size > threshold triggers bypass */ + int cache_bypass_prefetch = 1; /* Should we do prefetching ? */ + +-extern afs_rwlock_t afs_xcbhash; +- + /* + * This is almost exactly like the PFlush() routine in afs_pioctl.c, + * but that routine is static. We are about to change a file from +-- +2.36.1 + diff --git a/0008-afs-introduce-afs_alloc_ncr-afs_free_ncr.patch b/0008-afs-introduce-afs_alloc_ncr-afs_free_ncr.patch new file mode 100644 index 000000000000..c6289b54415f --- /dev/null +++ b/0008-afs-introduce-afs_alloc_ncr-afs_free_ncr.patch @@ -0,0 +1,255 @@ +From 3a0dbbb40e89ae0f0ec901c5fa831a2c1a5ca9a3 Mon Sep 17 00:00:00 2001 +From: Cheyenne Wills <cwills@sinenomine.net> +Date: Wed, 1 Jun 2022 09:10:12 -0600 +Subject: [PATCH 08/12] afs: introduce afs_alloc_ncr/afs_free_ncr + +There is duplicated code for initializing a nocache_read_request +and also freeing the associated storage in certain cases. Create a set +of helper functions that allocates and frees a nocache_read_request and +its associated structures. + +afs_alloc_ncr allocates a nocache_read_request structure and if not +UKERNEL, will allocate and initialize the associated uio and iovec +structures. + +afs_free_ncr releases a noncache_read_request structure and the +associated uio and iovec structures if not UKERNEL. + +Update locations that allocate/free nocache_read_request structures to +use the new functions. + +Change-Id: I80c0b4eb036bcb1223b73f4c1de2c12be362de42 +--- + src/afs/LINUX/osi_vnodeops.c | 37 +++++++----------- + src/afs/UKERNEL/afs_usrops.c | 8 +++- + src/afs/afs_bypasscache.c | 73 +++++++++++++++++++++++++++++++----- + src/afs/afs_bypasscache.h | 3 +- + 4 files changed, 85 insertions(+), 36 deletions(-) + +diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c +index a0c78c04d..9b5d05471 100644 +--- a/src/afs/LINUX/osi_vnodeops.c ++++ b/src/afs/LINUX/osi_vnodeops.c +@@ -2537,7 +2537,6 @@ afs_linux_bypass_readpages(struct file *fp, struct address_space *mapping, + struct list_head *page_list, unsigned num_pages) + { + afs_int32 page_ix; +- struct uio *auio; + afs_offs_t offset; + struct iovec* iovecp; + struct nocache_read_request *ancr; +@@ -2552,20 +2551,10 @@ afs_linux_bypass_readpages(struct file *fp, struct address_space *mapping, + afs_int32 page_count = 0; + afs_int32 isize; + +- /* background thread must free: iovecp, auio, ancr */ +- iovecp = osi_Alloc(num_pages * sizeof(struct iovec)); +- +- auio = osi_Alloc(sizeof(struct uio)); +- auio->uio_iov = iovecp; +- auio->uio_iovcnt = num_pages; +- auio->uio_flag = UIO_READ; +- auio->uio_seg = AFS_UIOSYS; +- auio->uio_resid = num_pages * PAGE_SIZE; +- +- ancr = osi_Alloc(sizeof(struct nocache_read_request)); +- ancr->auio = auio; +- ancr->offset = auio->uio_offset; +- ancr->length = auio->uio_resid; ++ ancr = afs_alloc_ncr(num_pages); ++ if (ancr == NULL) ++ return afs_convert_code(ENOMEM); ++ iovecp = ancr->auio->uio_iov; + + afs_lru_cache_init(&lrupages); + +@@ -2587,7 +2576,7 @@ afs_linux_bypass_readpages(struct file *fp, struct address_space *mapping, + + if(page_ix == 0) { + offset = page_offset(pp); +- ancr->offset = auio->uio_offset = offset; ++ ancr->offset = ancr->auio->uio_offset = offset; + base_index = pp->index; + } + iovecp[page_ix].iov_len = PAGE_SIZE; +@@ -2626,14 +2615,13 @@ afs_linux_bypass_readpages(struct file *fp, struct address_space *mapping, + if(page_count) { + afs_lru_cache_finalize(&lrupages); + credp = crref(); ++ /* background thread frees the ancr */ + code = afs_ReadNoCache(avc, ancr, credp); + crfree(credp); + } else { + /* If there is nothing for the background thread to handle, + * it won't be freeing the things that we never gave it */ +- osi_Free(iovecp, num_pages * sizeof(struct iovec)); +- osi_Free(auio, sizeof(struct uio)); +- osi_Free(ancr, sizeof(struct nocache_read_request)); ++ afs_free_ncr(&ancr); + } + /* we do not flush, release, or unmap pages--that will be + * done for us by the background thread as each page comes in +@@ -2665,8 +2653,13 @@ afs_linux_bypass_readpage(struct file *fp, struct page *pp) + ClearPageError(pp); + + /* receiver frees */ +- auio = osi_Alloc(sizeof(struct uio)); +- iovecp = osi_Alloc(sizeof(struct iovec)); ++ ancr = afs_alloc_ncr(1); ++ if (ancr == NULL) { ++ SetPageError(pp); ++ return afs_convert_code(ENOMEM); ++ } ++ auio = ancr->auio; ++ iovecp = auio->uio_iov; + + /* address can be NULL, because we overwrite it with 'pp', below */ + setup_uio(auio, iovecp, NULL, page_offset(pp), +@@ -2676,8 +2669,6 @@ afs_linux_bypass_readpage(struct file *fp, struct page *pp) + get_page(pp); /* see above */ + auio->uio_iov->iov_base = (void*) pp; + /* the background thread will free this */ +- ancr = osi_Alloc(sizeof(struct nocache_read_request)); +- ancr->auio = auio; + ancr->offset = page_offset(pp); + ancr->length = PAGE_SIZE; + +diff --git a/src/afs/UKERNEL/afs_usrops.c b/src/afs/UKERNEL/afs_usrops.c +index 0e38fb84b..80403c5bd 100644 +--- a/src/afs/UKERNEL/afs_usrops.c ++++ b/src/afs/UKERNEL/afs_usrops.c +@@ -2398,12 +2398,16 @@ uafs_pread_nocache_r(int fd, char *buf, int len, off_t offset) + } + + /* these get freed in PrefetchNoCache, so... */ +- bparms = afs_osi_Alloc(sizeof(struct nocache_read_request)); ++ bparms = afs_alloc_ncr(0); ++ if (bparms == NULL) { ++ errno = ENOMEM; ++ return -1; ++ } + + code = afs_CreateReq(&bparms->areq, get_user_struct()->u_cred); + if (code) { + afs_DestroyReq(bparms->areq); +- afs_osi_Free(bparms, sizeof(struct nocache_read_request)); ++ afs_free_ncr(&bparms); + errno = code; + return -1; + } +diff --git a/src/afs/afs_bypasscache.c b/src/afs/afs_bypasscache.c +index c51bd25c7..e13a32e9d 100644 +--- a/src/afs/afs_bypasscache.c ++++ b/src/afs/afs_bypasscache.c +@@ -111,7 +111,68 @@ + int cache_bypass_strategy = NEVER_BYPASS_CACHE; + afs_size_t cache_bypass_threshold = AFS_CACHE_BYPASS_DISABLED; /* file size > threshold triggers bypass */ + int cache_bypass_prefetch = 1; /* Should we do prefetching ? */ ++/* ++ * Allocate and initialize nocache_read_request/uid/iovec ++ * Returns NULL if memory allocation error. ++ */ ++struct nocache_read_request * ++afs_alloc_ncr(unsigned num_pages) ++{ ++ struct nocache_read_request *ancr = NULL; ++#if !defined(UKERNEL) ++ struct uio *auio = NULL; ++ struct iovec *iovecp = NULL; ++#endif ++ ++ ancr = osi_Alloc(sizeof(*ancr)); ++ if (ancr == NULL) ++ goto error; + ++#if !defined(UKERNEL) ++ iovecp = osi_Alloc(num_pages * sizeof(*iovecp)); ++ if (iovecp == NULL) ++ goto error; ++ ++ auio = osi_Alloc(sizeof(*auio)); ++ if (auio == NULL) ++ goto error; ++ auio->uio_iov = iovecp; ++ auio->uio_iovcnt = num_pages; ++ auio->uio_flag = UIO_READ; ++ auio->uio_seg = AFS_UIOSYS; ++ auio->uio_offset = 0; ++ auio->uio_resid = num_pages * PAGE_SIZE; ++ ++ ancr->auio = auio; ++ ancr->offset = auio->uio_offset; ++ ancr->length = auio->uio_resid; ++#endif ++ ++ return ancr; ++ ++ error: ++#if !defined(UKERNEL) ++ osi_Free(iovecp, num_pages * sizeof(*iovecp)); ++ osi_Free(auio, sizeof(*auio)); ++#endif ++ osi_Free(ancr, sizeof(*ancr)); ++ return NULL; ++} ++/* ++ * Free a nocache_read_request and associated structures ++ */ ++void ++afs_free_ncr(struct nocache_read_request **ancr) ++{ ++ if (*ancr == NULL) ++ return; ++#if !defined(UKERNEL) ++ osi_Free((*ancr)->auio->uio_iov, (*ancr)->auio->uio_iovcnt * sizeof(struct iovec)); ++ osi_Free((*ancr)->auio, sizeof(struct uio)); ++#endif ++ osi_Free(*ancr, sizeof(struct nocache_read_request)); ++ *ancr = NULL; ++} + /* + * This is almost exactly like the PFlush() routine in afs_pioctl.c, + * but that routine is static. We are about to change a file from +@@ -517,10 +578,7 @@ cleanup: + AFS_GLOCK(); + afs_DestroyReq(areq); + AFS_GUNLOCK(); +- osi_Free(bparms->auio->uio_iov, +- bparms->auio->uio_iovcnt * sizeof(struct iovec)); +- osi_Free(bparms->auio, sizeof(struct uio)); +- osi_Free(bparms, sizeof(struct nocache_read_request)); ++ afs_free_ncr(&bparms); + return code; + } + +@@ -647,12 +705,7 @@ done: + + afs_DestroyReq(areq); + osi_Free(tcallspec, sizeof(struct tlocal1)); +- osi_Free(bparms, sizeof(struct nocache_read_request)); +-#ifndef UKERNEL +- /* in UKERNEL, the "pages" are passed in */ +- osi_Free(iovecp, auio->uio_iovcnt * sizeof(struct iovec)); +- osi_Free(auio, sizeof(struct uio)); +-#endif ++ afs_free_ncr(&bparms); + return code; + } + #endif +diff --git a/src/afs/afs_bypasscache.h b/src/afs/afs_bypasscache.h +index 37c5669b3..0c7542dd6 100644 +--- a/src/afs/afs_bypasscache.h ++++ b/src/afs/afs_bypasscache.h +@@ -103,7 +103,8 @@ enum cache_bypass_strategies + extern int cache_bypass_prefetch; + extern int cache_bypass_strategy; + extern afs_size_t cache_bypass_threshold; +- ++struct nocache_read_request *afs_alloc_ncr(unsigned num_pages); ++void afs_free_ncr(struct nocache_read_request **ancr); + void afs_TransitionToBypass(struct vcache *, afs_ucred_t *, int); + void afs_TransitionToCaching(struct vcache *, afs_ucred_t *, int); + +-- +2.36.1 + diff --git a/0009-LINUX-Don-t-panic-on-some-file-open-errors.patch b/0009-LINUX-Don-t-panic-on-some-file-open-errors.patch new file mode 100644 index 000000000000..9c2e2149ecfb --- /dev/null +++ b/0009-LINUX-Don-t-panic-on-some-file-open-errors.patch @@ -0,0 +1,127 @@ +From 932347ddb95eca41ee4365b8ea32d282c692eaba Mon Sep 17 00:00:00 2001 +From: Cheyenne Wills <cwills@sinenomine.net> +Date: Thu, 2 Jul 2020 13:39:27 -0600 +Subject: [PATCH 09/12] LINUX: Don't panic on some file open errors + +Commit 'LINUX: Return NULL for afs_linux_raw_open error' (f6af4a155) +updated afs_linux_raw_open to return NULL on some errors, but still +panics if obtaining the dentry fails. + +Commit 'afs: Verify osi_UFSOpen worked' (c6b61a451) updated callers of +osi_UFSOpen to verify whether or not the open was successful. This +meant osi_UFSOpen (and routines it calls) could pass back an error +indication rather than panic when an error is encountered. + +Update afs_linux_raw_open to return a failure instead of panic if unable +to obtain a dentry. + +Update osi_UFSOpen to return a NULL instead of panic if unable to obtain +memory or fails to open the file. All callers of osi_UFSOpen handle a +fail return, though some will still issue a panic. + +Update afs_linux_readpage_fastpath and afs_linux_readpages to not panic +if afs_linux_raw_open fails. Instead of panic, return an error. + +For testing, an error can be forced by removing a file from the +cache directory. + +Note this work is based on a commit by pruiter@sinenomine.net + +Change-Id: Ic47e4868b4f81d99fbe3b2e4958778508ae4851f +Reviewed-on: https://gerrit.openafs.org/14242 +Reviewed-by: Andrew Deason <adeason@sinenomine.net> +Reviewed-by: Mark Vitale <mvitale@sinenomine.net> +Reviewed-by: Benjamin Kaduk <kaduk@mit.edu> +Tested-by: BuildBot <buildbot@rampaginggeek.com> +(cherry picked from commit af73b9a3b1fc625694807287c0897391feaad52d) +--- + src/afs/LINUX/osi_file.c | 15 +++++++++++---- + src/afs/LINUX/osi_vnodeops.c | 17 +++++++++++++---- + 2 files changed, 24 insertions(+), 8 deletions(-) + +diff --git a/src/afs/LINUX/osi_file.c b/src/afs/LINUX/osi_file.c +index 03777f563..004799c4c 100644 +--- a/src/afs/LINUX/osi_file.c ++++ b/src/afs/LINUX/osi_file.c +@@ -65,8 +65,12 @@ afs_linux_raw_open(afs_dcache_id_t *ainode) + + dp = afs_get_dentry_from_fh(afs_cacheSBp, ainode, cache_fh_len, cache_fh_type, + afs_fh_acceptable); +- if ((!dp) || IS_ERR(dp)) +- osi_Panic("Can't get dentry\n"); ++ if ((!dp) || IS_ERR(dp)) { ++ afs_warn("afs: Cannot get dentry for cache file (code %d). Trying to continue, " ++ "but AFS accesses may return errors or panic the system\n", ++ (int) PTR_ERR(dp)); ++ return NULL; ++ } + tip = dp->d_inode; + tip->i_flags |= S_NOATIME; /* Disable updating access times. */ + +@@ -115,8 +119,11 @@ osi_UFSOpen(afs_dcache_id_t *ainode) + AFS_GUNLOCK(); + afile = kmalloc(sizeof(struct osi_file), GFP_NOFS); + if (!afile) { +- osi_Panic("osi_UFSOpen: Failed to allocate %d bytes for osi_file.\n", +- (int)sizeof(struct osi_file)); ++ afs_warn("afs: Failed to allocate memory for opening a cache file. " ++ "Trying to continue, but AFS access may return errors or panic " ++ "the system\n"); ++ AFS_GLOCK(); ++ return NULL; + } + memset(afile, 0, sizeof(struct osi_file)); + +diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c +index 9b5d05471..1631d3d3d 100644 +--- a/src/afs/LINUX/osi_vnodeops.c ++++ b/src/afs/LINUX/osi_vnodeops.c +@@ -2398,7 +2398,11 @@ afs_linux_readpage_fastpath(struct file *fp, struct page *pp, int *codep) + /* XXX - I suspect we should be locking the inodes before we use them! */ + AFS_GUNLOCK(); + cacheFp = afs_linux_raw_open(&tdc->f.inode); +- osi_Assert(cacheFp); ++ if (cacheFp == NULL) { ++ /* Problem getting the inode */ ++ AFS_GLOCK(); ++ goto out; ++ } + if (!cacheFp->f_dentry->d_inode->i_mapping->a_ops->readpage) { + cachefs_noreadpage = 1; + AFS_GLOCK(); +@@ -2785,8 +2789,10 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, + afs_PutDCache(tdc); + AFS_GUNLOCK(); + tdc = NULL; +- if (cacheFp) ++ if (cacheFp) { + filp_close(cacheFp, NULL); ++ cacheFp = NULL; ++ } + } + + if (!tdc) { +@@ -2803,7 +2809,10 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, + AFS_GUNLOCK(); + if (tdc) { + cacheFp = afs_linux_raw_open(&tdc->f.inode); +- osi_Assert(cacheFp); ++ if (cacheFp == NULL) { ++ /* Problem getting the inode */ ++ goto out; ++ } + if (!cacheFp->f_dentry->d_inode->i_mapping->a_ops->readpage) { + cachefs_noreadpage = 1; + goto out; +@@ -2824,7 +2833,7 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, + afs_lru_cache_finalize(&lrupages); + + out: +- if (tdc) ++ if (cacheFp) + filp_close(cacheFp, NULL); + + afs_pagecopy_put_task(task); +-- +2.36.1 + diff --git a/0010-afs-Introduce-afs_IsDCacheFresh.patch b/0010-afs-Introduce-afs_IsDCacheFresh.patch new file mode 100644 index 000000000000..eb9a3669eae8 --- /dev/null +++ b/0010-afs-Introduce-afs_IsDCacheFresh.patch @@ -0,0 +1,371 @@ +From 2fcade1caea1e81f8b5b54c5c08e363649a4664c Mon Sep 17 00:00:00 2001 +From: Andrew Deason <adeason@sinenomine.net> +Date: Thu, 17 Jan 2019 15:45:36 -0600 +Subject: [PATCH 10/12] afs: Introduce afs_IsDCacheFresh + +Numerous places in libafs check the DV of a dcache against the DV of +the vcache for the same file, in order to check if the dcache is up to +date and can be used. Consolidate all of these checks into a new +function, afs_IsDCacheFresh, to make it easier for future commits to +alter this logic. + +This commit should have no visible impact; it is just code +reorganization. + +Change-Id: Iedc02b0f5d7d0542ab00ff1effdde03c2a851df4 +Reviewed-on: https://gerrit.openafs.org/13435 +Reviewed-by: Benjamin Kaduk <kaduk@mit.edu> +Tested-by: Andrew Deason <adeason@sinenomine.net> +(cherry picked from commit 0d8ce846ab2e6c45166a61f04eb3af271cbd27db) +--- + src/afs/LINUX/osi_export.c | 8 ++++---- + src/afs/LINUX/osi_vnodeops.c | 8 ++++---- + src/afs/SOLARIS/osi_vnodeops.c | 6 +++--- + src/afs/VNOPS/afs_vnop_create.c | 4 ++-- + src/afs/VNOPS/afs_vnop_lookup.c | 8 ++++---- + src/afs/VNOPS/afs_vnop_read.c | 4 ++-- + src/afs/VNOPS/afs_vnop_readdir.c | 4 ++-- + src/afs/VNOPS/afs_vnop_remove.c | 2 +- + src/afs/VNOPS/afs_vnop_rename.c | 2 +- + src/afs/afs_dcache.c | 30 ++++++++++++++++++++++++------ + src/afs/afs_prototypes.h | 1 + + 11 files changed, 48 insertions(+), 29 deletions(-) + +diff --git a/src/afs/LINUX/osi_export.c b/src/afs/LINUX/osi_export.c +index a3175b5d5..926bd0df9 100644 +--- a/src/afs/LINUX/osi_export.c ++++ b/src/afs/LINUX/osi_export.c +@@ -349,7 +349,7 @@ redo: + */ + while ((adp->f.states & CStatd) + && (tdc->dflags & DFFetching) +- && hsame(adp->f.m.DataVersion, tdc->f.versionNo)) { ++ && afs_IsDCacheFresh(tdc, adp)) { + ReleaseReadLock(&tdc->lock); + ReleaseSharedLock(&adp->lock); + afs_osi_Sleep(&tdc->validPos); +@@ -357,7 +357,7 @@ redo: + ObtainReadLock(&tdc->lock); + } + if (!(adp->f.states & CStatd) +- || !hsame(adp->f.m.DataVersion, tdc->f.versionNo)) { ++ || !afs_IsDCacheFresh(tdc, adp)) { + ReleaseReadLock(&tdc->lock); + ReleaseSharedLock(&adp->lock); + afs_PutDCache(tdc); +@@ -770,7 +770,7 @@ redo: + */ + while ((vcp->f.states & CStatd) + && (tdc->dflags & DFFetching) +- && hsame(vcp->f.m.DataVersion, tdc->f.versionNo)) { ++ && afs_IsDCacheFresh(tdc, vcp)) { + ReleaseReadLock(&tdc->lock); + ReleaseReadLock(&vcp->lock); + afs_osi_Sleep(&tdc->validPos); +@@ -778,7 +778,7 @@ redo: + ObtainReadLock(&tdc->lock); + } + if (!(vcp->f.states & CStatd) +- || !hsame(vcp->f.m.DataVersion, tdc->f.versionNo)) { ++ || !afs_IsDCacheFresh(tdc, vcp)) { + ReleaseReadLock(&tdc->lock); + ReleaseReadLock(&vcp->lock); + afs_PutDCache(tdc); +diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c +index 1631d3d3d..9f164f395 100644 +--- a/src/afs/LINUX/osi_vnodeops.c ++++ b/src/afs/LINUX/osi_vnodeops.c +@@ -447,7 +447,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) + */ + while ((avc->f.states & CStatd) + && (tdc->dflags & DFFetching) +- && hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { ++ && afs_IsDCacheFresh(tdc, avc)) { + ReleaseReadLock(&tdc->lock); + ReleaseWriteLock(&avc->lock); + afs_osi_Sleep(&tdc->validPos); +@@ -455,7 +455,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) + ObtainReadLock(&tdc->lock); + } + if (!(avc->f.states & CStatd) +- || !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { ++ || !afs_IsDCacheFresh(tdc, avc)) { + ReleaseReadLock(&tdc->lock); + ReleaseWriteLock(&avc->lock); + afs_PutDCache(tdc); +@@ -2386,7 +2386,7 @@ afs_linux_readpage_fastpath(struct file *fp, struct page *pp, int *codep) + ObtainReadLock(&tdc->lock); + + /* Is the dcache we've been given currently up to date */ +- if (!hsame(avc->f.m.DataVersion, tdc->f.versionNo) || ++ if (!afs_IsDCacheFresh(tdc, avc) || + (tdc->dflags & DFFetching)) + goto out; + +@@ -2799,7 +2799,7 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, + AFS_GLOCK(); + if ((tdc = afs_FindDCache(avc, offset))) { + ObtainReadLock(&tdc->lock); +- if (!hsame(avc->f.m.DataVersion, tdc->f.versionNo) || ++ if (!afs_IsDCacheFresh(tdc, avc) || + (tdc->dflags & DFFetching)) { + ReleaseReadLock(&tdc->lock); + afs_PutDCache(tdc); +diff --git a/src/afs/SOLARIS/osi_vnodeops.c b/src/afs/SOLARIS/osi_vnodeops.c +index fde268401..76b55b351 100644 +--- a/src/afs/SOLARIS/osi_vnodeops.c ++++ b/src/afs/SOLARIS/osi_vnodeops.c +@@ -350,7 +350,7 @@ afs_GetOnePage(struct vnode *vp, u_offset_t off, u_int alen, u_int *protp, + + /* Check to see whether the cache entry is still valid */ + if (!(avc->f.states & CStatd) +- || !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { ++ || !afs_IsDCacheFresh(tdc, avc)) { + ReleaseReadLock(&tdc->lock); + ReleaseReadLock(&avc->lock); + afs_PutDCache(tdc); +@@ -882,12 +882,12 @@ afs_nfsrdwr(struct vcache *avc, struct uio *auio, enum uio_rw arw, + AFS_GLOCK(); + dcp_newpage = afs_FindDCache(avc, pageBase); + if (dcp_newpage +- && hsame(avc->f.m.DataVersion, dcp_newpage->f.versionNo)) { ++ && afs_IsDCacheFresh(dcp_newpage, avc)) { + ObtainWriteLock(&avc->lock, 251); + ObtainWriteLock(&avc->vlock, 576); + ObtainReadLock(&dcp_newpage->lock); + if ((avc->activeV == 0) +- && hsame(avc->f.m.DataVersion, dcp_newpage->f.versionNo) ++ && afs_IsDCacheFresh(dcp_newpage, avc) + && !(dcp_newpage->dflags & (DFFetching))) { + AFS_GUNLOCK(); + segmap_pagecreate(segkmap, raddr, rsize, 1); +diff --git a/src/afs/VNOPS/afs_vnop_create.c b/src/afs/VNOPS/afs_vnop_create.c +index fe37eed36..70b531a6a 100644 +--- a/src/afs/VNOPS/afs_vnop_create.c ++++ b/src/afs/VNOPS/afs_vnop_create.c +@@ -149,7 +149,7 @@ afs_create(OSI_VC_DECL(adp), char *aname, struct vattr *attrs, + * received a callback while we were waiting for the write lock. + */ + if (!(adp->f.states & CStatd) +- || (tdc && !hsame(adp->f.m.DataVersion, tdc->f.versionNo))) { ++ || (tdc && !afs_IsDCacheFresh(tdc, adp))) { + ReleaseWriteLock(&adp->lock); + if (tdc) { + ReleaseSharedLock(&tdc->lock); +@@ -543,7 +543,7 @@ afs_LocalHero(struct vcache *avc, struct dcache *adc, + if (adc) { + /* does what's in the dcache *now* match what's in the vcache *now*, + * and do we have a valid callback? if not, our local copy is not "ok" */ +- ok = (hsame(avc->f.m.DataVersion, adc->f.versionNo) && avc->callback ++ ok = (afs_IsDCacheFresh(adc, avc) && avc->callback + && (avc->f.states & CStatd) && avc->cbExpires >= osi_Time()); + } else { + ok = 0; +diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c +index b42d6db43..f47a505a7 100644 +--- a/src/afs/VNOPS/afs_vnop_lookup.c ++++ b/src/afs/VNOPS/afs_vnop_lookup.c +@@ -752,7 +752,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) + */ + while ((adp->f.states & CStatd) + && (dcp->dflags & DFFetching) +- && hsame(adp->f.m.DataVersion, dcp->f.versionNo)) { ++ && afs_IsDCacheFresh(dcp, adp)) { + afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT, ICL_TYPE_STRING, + __FILE__, ICL_TYPE_INT32, __LINE__, ICL_TYPE_POINTER, dcp, + ICL_TYPE_INT32, dcp->dflags); +@@ -763,7 +763,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) + ObtainReadLock(&dcp->lock); + } + if (!(adp->f.states & CStatd) +- || !hsame(adp->f.m.DataVersion, dcp->f.versionNo)) { ++ || !afs_IsDCacheFresh(dcp, adp)) { + ReleaseReadLock(&dcp->lock); + ReleaseReadLock(&adp->lock); + afs_PutDCache(dcp); +@@ -1685,7 +1685,7 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, afs_ucred_t *acr + if (!afs_InReadDir(adp)) { + while ((adp->f.states & CStatd) + && (tdc->dflags & DFFetching) +- && hsame(adp->f.m.DataVersion, tdc->f.versionNo)) { ++ && afs_IsDCacheFresh(tdc, adp)) { + ReleaseReadLock(&tdc->lock); + ReleaseReadLock(&adp->lock); + afs_osi_Sleep(&tdc->validPos); +@@ -1693,7 +1693,7 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, afs_ucred_t *acr + ObtainReadLock(&tdc->lock); + } + if (!(adp->f.states & CStatd) +- || !hsame(adp->f.m.DataVersion, tdc->f.versionNo)) { ++ || !afs_IsDCacheFresh(tdc, adp)) { + ReleaseReadLock(&tdc->lock); + ReleaseReadLock(&adp->lock); + afs_PutDCache(tdc); +diff --git a/src/afs/VNOPS/afs_vnop_read.c b/src/afs/VNOPS/afs_vnop_read.c +index dba411715..e5c664207 100644 +--- a/src/afs/VNOPS/afs_vnop_read.c ++++ b/src/afs/VNOPS/afs_vnop_read.c +@@ -190,7 +190,7 @@ afs_read(struct vcache *avc, struct uio *auio, afs_ucred_t *acred, + * 2 requests never return a null dcache entry, btw. + */ + if (!(tdc->dflags & DFFetching) +- && !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { ++ && !afs_IsDCacheFresh(tdc, avc)) { + /* have cache entry, it is not coming in now, + * and we'll need new data */ + tagain: +@@ -270,7 +270,7 @@ afs_read(struct vcache *avc, struct uio *auio, afs_ucred_t *acred, + } else { + /* no longer fetching, verify data version + * (avoid new GetDCache call) */ +- if (hsame(avc->f.m.DataVersion, tdc->f.versionNo) ++ if (afs_IsDCacheFresh(tdc, avc) + && ((len = tdc->validPos - filePos) > 0)) { + offset = filePos - AFS_CHUNKTOBASE(tdc->f.chunk); + } else { +diff --git a/src/afs/VNOPS/afs_vnop_readdir.c b/src/afs/VNOPS/afs_vnop_readdir.c +index cdc5af56d..8d41c3ef2 100644 +--- a/src/afs/VNOPS/afs_vnop_readdir.c ++++ b/src/afs/VNOPS/afs_vnop_readdir.c +@@ -702,7 +702,7 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred) + */ + while ((avc->f.states & CStatd) + && (tdc->dflags & DFFetching) +- && hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { ++ && afs_IsDCacheFresh(tdc, avc)) { + afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT, ICL_TYPE_STRING, + __FILE__, ICL_TYPE_INT32, __LINE__, ICL_TYPE_POINTER, tdc, + ICL_TYPE_INT32, tdc->dflags); +@@ -713,7 +713,7 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred) + ObtainReadLock(&tdc->lock); + } + if (!(avc->f.states & CStatd) +- || !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { ++ || !afs_IsDCacheFresh(tdc, avc)) { + ReleaseReadLock(&tdc->lock); + ReleaseReadLock(&avc->lock); + afs_PutDCache(tdc); +diff --git a/src/afs/VNOPS/afs_vnop_remove.c b/src/afs/VNOPS/afs_vnop_remove.c +index eca9eed24..06a84b060 100644 +--- a/src/afs/VNOPS/afs_vnop_remove.c ++++ b/src/afs/VNOPS/afs_vnop_remove.c +@@ -234,7 +234,7 @@ afs_remove(OSI_VC_DECL(adp), char *aname, afs_ucred_t *acred) + * received a callback while we were waiting for the write lock. + */ + if (!(adp->f.states & CStatd) +- || (tdc && !hsame(adp->f.m.DataVersion, tdc->f.versionNo))) { ++ || (tdc && !afs_IsDCacheFresh(tdc, adp))) { + ReleaseWriteLock(&adp->lock); + if (tdc) { + ReleaseSharedLock(&tdc->lock); +diff --git a/src/afs/VNOPS/afs_vnop_rename.c b/src/afs/VNOPS/afs_vnop_rename.c +index 59a1d5032..d61c80e29 100644 +--- a/src/afs/VNOPS/afs_vnop_rename.c ++++ b/src/afs/VNOPS/afs_vnop_rename.c +@@ -133,7 +133,7 @@ afsrename(struct vcache *aodp, char *aname1, struct vcache *andp, + */ + if (tdc1) { + if (!(aodp->f.states & CStatd) +- || !hsame(aodp->f.m.DataVersion, tdc1->f.versionNo)) { ++ || !afs_IsDCacheFresh(tdc1, aodp)) { + + ReleaseWriteLock(&aodp->lock); + if (!oneDir) { +diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c +index 6a18f80d5..ac9e52269 100644 +--- a/src/afs/afs_dcache.c ++++ b/src/afs/afs_dcache.c +@@ -1734,6 +1734,24 @@ afs_AllocDCache(struct vcache *avc, afs_int32 chunk, afs_int32 lock, + return tdc; + } + ++/*! ++ * Check if a dcache is "fresh". That is, if the dcache's DV matches the DV of ++ * the vcache for that file. ++ * ++ * \param adc The dcache to check ++ * \param avc The vcache for adc ++ * ++ * \return 1 if the dcache does match avc's DV; 0 otherwise. ++ */ ++int ++afs_IsDCacheFresh(struct dcache *adc, struct vcache *avc) ++{ ++ if (!hsame(adc->f.versionNo, avc->f.m.DataVersion)) { ++ return 0; ++ } ++ return 1; ++} ++ + /* + * afs_GetDCache + * +@@ -1772,7 +1790,7 @@ void + updateV2DC(int lockVc, struct vcache *v, struct dcache *d, int src) + { + if (!lockVc || 0 == NBObtainWriteLock(&v->lock, src)) { +- if (hsame(v->f.m.DataVersion, d->f.versionNo) && v->callback) ++ if (afs_IsDCacheFresh(d, v) && v->callback) + v->dchint = d; + if (lockVc) + ReleaseWriteLock(&v->lock); +@@ -1882,7 +1900,7 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte, + ReleaseReadLock(&afs_xdcache); + shortcut = 1; + +- if (hsame(tdc->f.versionNo, avc->f.m.DataVersion) ++ if (afs_IsDCacheFresh(tdc, avc) + && !(tdc->dflags & DFFetching)) { + + afs_stats_cmperf.dcacheHits++; +@@ -2119,7 +2137,7 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte, + if (AFS_CHUNKTOBASE(chunk) >= avc->f.m.Length && + #endif + #endif /* defined(AFS_AIX32_ENV) || defined(AFS_SGI_ENV) */ +- !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) ++ !afs_IsDCacheFresh(tdc, avc)) + doReallyAdjustSize = 1; + + if (doReallyAdjustSize || overWriteWholeChunk) { +@@ -2183,7 +2201,7 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte, + * avc->lock(W) if !setLocks || slowPass + * tdc->lock(S) + */ +- if (!hsame(avc->f.m.DataVersion, tdc->f.versionNo) && !overWriteWholeChunk) { ++ if (!afs_IsDCacheFresh(tdc, avc) && !overWriteWholeChunk) { + /* + * Version number mismatch. + */ +@@ -2253,7 +2271,7 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte, + */ + + /* Watch for standard race condition around osi_FlushText */ +- if (hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { ++ if (afs_IsDCacheFresh(tdc, avc)) { + updateV2DC(setLocks, avc, tdc, 569); /* set hint */ + afs_stats_cmperf.dcacheHits++; + ConvertWToSLock(&tdc->lock); +@@ -3592,7 +3610,7 @@ afs_ObtainDCacheForWriting(struct vcache *avc, afs_size_t filePos, + tdc = afs_FindDCache(avc, filePos); + if (tdc) { + ObtainWriteLock(&tdc->lock, 658); +- if (!hsame(tdc->f.versionNo, avc->f.m.DataVersion) ++ if (!afs_IsDCacheFresh(tdc, avc) + || (tdc->dflags & DFFetching)) { + ReleaseWriteLock(&tdc->lock); + afs_PutDCache(tdc); +diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h +index b9fd0782b..c8ed43fa7 100644 +--- a/src/afs/afs_prototypes.h ++++ b/src/afs/afs_prototypes.h +@@ -288,6 +288,7 @@ extern struct dcache *afs_ObtainDCacheForWriting(struct vcache *avc, + int noLock); + extern void afs_PopulateDCache(struct vcache *avc, afs_size_t apos, + struct vrequest *areq); ++extern int afs_IsDCacheFresh(struct dcache *adc, struct vcache *avc); + + /* afs_disconnected.c */ + +-- +2.36.1 + diff --git a/0011-afs-introduce-get_dcache_readahead.patch b/0011-afs-introduce-get_dcache_readahead.patch new file mode 100644 index 000000000000..0b58ed1a1406 --- /dev/null +++ b/0011-afs-introduce-get_dcache_readahead.patch @@ -0,0 +1,146 @@ +From 61b3bebcb0cade613e92be738c726cd0fc264658 Mon Sep 17 00:00:00 2001 +From: Cheyenne Wills <cwills@sinenomine.net> +Date: Wed, 1 Jun 2022 08:59:11 -0600 +Subject: [PATCH 11/12] afs: introduce get_dcache_readahead + +Relocate the block of code that obtains the dcache for a readahead +operation from the afs_linux_readpages function into its own static +function. + +Change-Id: Iaaf9523532e292a1f2426d5ced65ddfbceb5d060 +--- + src/afs/LINUX/osi_vnodeops.c | 111 +++++++++++++++++++++++------------ + 1 file changed, 75 insertions(+), 36 deletions(-) + +diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c +index 9f164f395..893f8afff 100644 +--- a/src/afs/LINUX/osi_vnodeops.c ++++ b/src/afs/LINUX/osi_vnodeops.c +@@ -2733,6 +2733,78 @@ afs_linux_readpage(struct file *fp, struct page *pp) + + return code; + } ++/* ++ * Updates the tdc and cacheFp parameters ++ * Returns: ++ * 0 - success ++ * -1 - problem getting inode or no mapping function ++ */ ++static int ++get_dcache_readahead(struct dcache **adc, struct file **acacheFp, ++ struct vcache *avc, loff_t offset) ++{ ++ struct dcache *tdc = *adc; ++ struct file *cacheFp = *acacheFp; ++ int code = 0; ++ ++ if (tdc != NULL && (tdc)->f.chunk != AFS_CHUNK(offset)) { ++ AFS_GLOCK(); ++ ReleaseReadLock(&tdc->lock); ++ afs_PutDCache(tdc); ++ AFS_GUNLOCK(); ++ tdc = NULL; ++ if (cacheFp != NULL) { ++ filp_close(cacheFp, NULL); ++ cacheFp = NULL; ++ } ++ } ++ ++ if (tdc != NULL) { ++ AFS_GLOCK(); ++ if ((tdc = afs_FindDCache(avc, offset))) { ++ ObtainReadLock(&tdc->lock); ++ if (!afs_IsDCacheFresh(tdc, avc) || ++ ((tdc)->dflags & DFFetching)) { ++ ReleaseReadLock(&tdc->lock); ++ afs_PutDCache(tdc); ++ tdc = NULL; ++ } ++ } ++ AFS_GUNLOCK(); ++ if (tdc != NULL) { ++ cacheFp = afs_linux_raw_open(&tdc->f.inode); ++ if (cacheFp == NULL) { ++ /* Problem getting the inode */ ++ code = -1; ++ goto out; ++ } ++ if (!(cacheFp)->f_dentry->d_inode->i_mapping->a_ops->readpage) { ++ cachefs_noreadpage = 1; ++ /* No mapping function */ ++ code = -1; ++ goto out; ++ } ++ } ++ } ++ ++ out: ++ if (code) { ++ if (cacheFp != NULL) { ++ filp_close(cacheFp, NULL); ++ cacheFp = NULL; ++ } ++ if (tdc != NULL) { ++ AFS_GLOCK(); ++ ReleaseReadLock(&tdc->lock); ++ afs_PutDCache(tdc); ++ AFS_GUNLOCK(); ++ tdc = NULL; ++ } ++ } ++ *adc = tdc; ++ *acacheFp = cacheFp; ++ return code; ++} + + /* Readpages reads a number of pages for a particular file. We use + * this to optimise the reading, by limiting the number of times upon which +@@ -2783,42 +2855,9 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, + list_del(&page->lru); + offset = page_offset(page); + +- if (tdc && tdc->f.chunk != AFS_CHUNK(offset)) { +- AFS_GLOCK(); +- ReleaseReadLock(&tdc->lock); +- afs_PutDCache(tdc); +- AFS_GUNLOCK(); +- tdc = NULL; +- if (cacheFp) { +- filp_close(cacheFp, NULL); +- cacheFp = NULL; +- } +- } +- +- if (!tdc) { +- AFS_GLOCK(); +- if ((tdc = afs_FindDCache(avc, offset))) { +- ObtainReadLock(&tdc->lock); +- if (!afs_IsDCacheFresh(tdc, avc) || +- (tdc->dflags & DFFetching)) { +- ReleaseReadLock(&tdc->lock); +- afs_PutDCache(tdc); +- tdc = NULL; +- } +- } +- AFS_GUNLOCK(); +- if (tdc) { +- cacheFp = afs_linux_raw_open(&tdc->f.inode); +- if (cacheFp == NULL) { +- /* Problem getting the inode */ +- goto out; +- } +- if (!cacheFp->f_dentry->d_inode->i_mapping->a_ops->readpage) { +- cachefs_noreadpage = 1; +- goto out; +- } +- } +- } ++ code = get_dcache_readahead(&tdc, &cacheFp, avc, offset); ++ if (code) ++ goto out; + + if (tdc && !add_to_page_cache(page, mapping, page->index, + GFP_KERNEL)) { +-- +2.36.1 + diff --git a/0012-Linux-5.18-replace-readpages-with-readahead.patch b/0012-Linux-5.18-replace-readpages-with-readahead.patch new file mode 100644 index 000000000000..b7c474c6f2da --- /dev/null +++ b/0012-Linux-5.18-replace-readpages-with-readahead.patch @@ -0,0 +1,304 @@ +From 7daef2e2bd350a1bee8bdbe6fdce3923c7867299 Mon Sep 17 00:00:00 2001 +From: Cheyenne Wills <cwills@sinenomine.net> +Date: Tue, 31 May 2022 14:43:33 -0600 +Subject: [PATCH 12/12] Linux-5.18: replace readpages with readahead + +The linux 5.18 the commit 'fs: Remove ->readpages address space +operation' (704528d8) removes the address_space_operations operation +"readpages" which is replaced with the "readahead" operation +that was introduced with the 5.8 commit 'mm: add readahead address +space operation' (8151b4c8). + +The address_space_operation function, readahead is called by the VM +to read pages. A filesystem provides an implementation to handle this +operation. + +When readahead is called, the list of pages have already been added to +the lru caches and are locked. The implementation of the readahead +function needs to handle decrementing the reference count, unlocking the +page and setting PageUptoDate when the IO has completed successfully. IO +errors are ignored by the vfs during readahead (errors will be detected +later in the vfs processing). We must simply unlock the page if an error +occurs. + (See Linux Documentation/filesystems/vfs.rst) + +Add an autoconf test to detect the presence of 'readahead' in the +address_space_operations structure. + +For the implementation of readahead (which is contained in Linux's +osi_vnodeops.c): + +Add new functions 'afs_linux_bypass_readahead' and 'afs_linux_readahead' +as replacements for 'afs_bypass_readpages' and 'afs_linux_readpages' +when the linux kernel supports the readahead operation. + +Don't manage the LRU for pages for the readahead case (e.g. don't +call the afs_lru_cache_* functions). + +Notes: + In afs_linux_bypass_readahead, the pages are already locked and are + already in the page cache, we just need to place the page into the + iovecp. The page's refcount will be decremented and will be unlocked + when processing the read request. + + In afs_linux_readahead, the lrupages is needed in case a page is added + to the cachefp's mapping in afs_linux_read_cache (which also handles + unlocking the page). Failure to unlock the page if there was no tdc + results in the read process waiting on that page. + +Change-Id: I6960a2fc14df85869c373f3e3afbf3ee5eb7228f +--- + src/afs/LINUX/osi_vnodeops.c | 190 +++++++++++++++++++++++++++++++++- + src/cf/linux-kernel-struct.m4 | 2 + + 2 files changed, 190 insertions(+), 2 deletions(-) + +diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c +index 893f8afff..1cc7cf8d6 100644 +--- a/src/afs/LINUX/osi_vnodeops.c ++++ b/src/afs/LINUX/osi_vnodeops.c +@@ -2536,6 +2536,92 @@ afs_linux_prefetch(struct file *fp, struct page *pp) + + } + ++#if defined(STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_READAHEAD) ++static void ++afs_linux_bypass_readahead(struct readahead_control *rac) ++{ ++ struct file *fp = rac->file; ++ unsigned num_pages = readahead_count(rac); ++ afs_int32 page_ix; ++ afs_offs_t offset; ++ struct iovec* iovecp; ++ struct nocache_read_request *ancr; ++ struct page *pp; ++ ++ afs_int32 code = 0; ++ ++ cred_t *credp; ++ struct inode *ip = FILE_INODE(fp); ++ struct vcache *avc = VTOAFS(ip); ++ afs_int32 base_index = 0; ++ afs_int32 page_count = 0; ++ afs_int32 isize; ++ ++ /* background thread must free: iovecp, auio, ancr */ ++ ancr = afs_alloc_ncr(num_pages); ++ if (!ancr) ++ goto error; ++ ++ iovecp = ancr->auio->uio_iov; ++ ++ for (page_ix = 0; page_ix < num_pages; ++page_ix) { ++ pp = readahead_page(rac); ++ if (pp == NULL) ++ break; ++ ++ isize = (i_size_read(fp->f_mapping->host) - 1) >> PAGE_SHIFT; ++ if (pp->index > isize) { ++ if(PageLocked(pp)) ++ unlock_page(pp); ++ continue; ++ } ++ ++ if (page_ix == 0) { ++ offset = page_offset(pp); ++ ancr->offset = ancr->auio->uio_offset = offset; ++ base_index = pp->index; ++ } ++ iovecp[page_ix].iov_len = PAGE_SIZE; ++ if (base_index != pp->index) { ++ if (PageLocked(pp)) ++ unlock_page(pp); ++ put_page(pp); ++ iovecp[page_ix].iov_base = NULL; ++ base_index++; ++ ancr->length -= PAGE_SIZE; ++ continue; ++ } ++ base_index++; ++ page_count++; ++ /* save the page for background map */ ++ iovecp[page_ix].iov_base = pp; ++ } ++ ++ /* If there were useful pages in the page list, schedule ++ * the read */ ++ if (page_count) { ++ credp = crref(); ++ code = afs_ReadNoCache(avc, ancr, credp); ++ crfree(credp); ++ } else { ++ /* If there is nothing for the background thread to handle, ++ * it won't be freeing the things that we never gave it */ ++ afs_free_ncr(&ancr); ++ } ++ /* we do not flush, release, or unmap pages--that will be ++ * done for us by the background thread as each page comes in ++ * from the fileserver */ ++ return; ++ ++ error: ++ while ((pp = readahead_page(rac)) != NULL) { ++ if (PageLocked(pp)) { ++ unlock_page(pp); ++ } ++ } ++ return; ++} ++#else /* STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_READAHEAD */ + static int + afs_linux_bypass_readpages(struct file *fp, struct address_space *mapping, + struct list_head *page_list, unsigned num_pages) +@@ -2632,7 +2718,7 @@ afs_linux_bypass_readpages(struct file *fp, struct address_space *mapping, + * from the fileserver */ + return afs_convert_code(code); + } +- ++#endif /* STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_READAHEAD */ + + static int + afs_linux_bypass_readpage(struct file *fp, struct page *pp) +@@ -2806,11 +2892,106 @@ get_dcache_readahead(struct dcache **adc, struct file **acacheFp, + return code; + } + +-/* Readpages reads a number of pages for a particular file. We use ++#if defined(STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_READAHEAD) ++/* ++ * Readahead reads a number of pages for a particular file. We use + * this to optimise the reading, by limiting the number of times upon which + * we have to lookup, lock and open vcaches and dcaches + */ ++static void ++afs_linux_readahead(struct readahead_control *rac) ++{ ++ struct page *page; ++ struct address_space *mapping = rac->mapping; ++ struct inode *inode = mapping->host; ++ struct vcache *avc = VTOAFS(inode); ++ struct dcache *tdc; ++ struct file *cacheFp = NULL; ++ int code = 0; ++ loff_t offset; ++ struct afs_lru_pages lrupages; ++ struct afs_pagecopy_task *task; ++ ++ if (afs_linux_bypass_check(inode)) { ++ afs_linux_bypass_readahead(rac); ++ return; ++ } ++ if (cacheDiskType == AFS_FCACHE_TYPE_MEM) ++ return; ++ ++ /* No readpage (ex: tmpfs) , skip */ ++ if (cachefs_noreadpage) ++ return; ++ ++ AFS_GLOCK(); ++ if ((code = afs_linux_VerifyVCache(avc, NULL))) { ++ AFS_GUNLOCK(); ++ return; ++ } ++ ++ ObtainWriteLock(&avc->lock, 912); ++ AFS_GUNLOCK(); ++ ++ task = afs_pagecopy_init_task(); + ++ tdc = NULL; ++ ++ afs_lru_cache_init(&lrupages); ++ ++ while ((page = readahead_page(rac)) != NULL) { ++ offset = page_offset(page); ++ ++ code = get_dcache_readahead(&tdc, &cacheFp, avc, offset); ++ if (code) ++ goto error; ++ ++ if (tdc != NULL) { ++ /* Note that add_to_page_cache() locked 'page'. ++ * afs_linux_read_cache() is guaranteed to handle unlocking it. */ ++ afs_linux_read_cache(cacheFp, page, tdc->f.chunk, &lrupages, task); ++ } else if (PageLocked(page)) { ++ unlock_page(page); ++ } ++ put_page(page); ++ } ++ afs_lru_cache_finalize(&lrupages); ++ ++ done: ++ if (cacheFp) ++ filp_close(cacheFp, NULL); ++ ++ afs_pagecopy_put_task(task); ++ ++ AFS_GLOCK(); ++ if (tdc != NULL) { ++ ReleaseReadLock(&tdc->lock); ++ afs_PutDCache(tdc); ++ } ++ ++ ReleaseWriteLock(&avc->lock); ++ AFS_GUNLOCK(); ++ return; ++ ++ error: ++ /* ++ * Any error detected during readahead are ignored by the vfs. ++ * Simply unlock the page(s). ++ */ ++ if (PageLocked(page)) { ++ unlock_page(page); ++ } ++ while ((page = readahead_page(rac)) != NULL) { ++ if (PageLocked(page)) { ++ unlock_page(page); ++ } ++ } ++ goto done; ++} ++#else /* STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_READAHEAD */ ++/* Readpages reads a number of pages for a particular file. We use ++ * this to optimise the reading, by limiting the number of times upon which ++ * we have to lookup, lock and open vcaches and dcaches ++ */ + static int + afs_linux_readpages(struct file *fp, struct address_space *mapping, + struct list_head *page_list, unsigned int num_pages) +@@ -2887,6 +3068,7 @@ out: + AFS_GUNLOCK(); + return 0; + } ++#endif /* STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_READAHEAD */ + + /* Prepare an AFS vcache for writeback. Should be called with the vcache + * locked */ +@@ -3325,7 +3507,11 @@ static struct inode_operations afs_file_iops = { + + static struct address_space_operations afs_file_aops = { + .readpage = afs_linux_readpage, ++#if defined(STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_READAHEAD) ++ .readahead = afs_linux_readahead, ++#else + .readpages = afs_linux_readpages, ++#endif + .writepage = afs_linux_writepage, + #if defined(STRUCT_ADDRESS_SPACE_OPERATIONS_HAS_DIRTY_FOLIO) + .dirty_folio = block_dirty_folio, +diff --git a/src/cf/linux-kernel-struct.m4 b/src/cf/linux-kernel-struct.m4 +index 2d8cee655..597289bc8 100644 +--- a/src/cf/linux-kernel-struct.m4 ++++ b/src/cf/linux-kernel-struct.m4 +@@ -5,6 +5,8 @@ AC_CHECK_LINUX_STRUCT([address_space_operations], + [write_begin], [fs.h]) + dnl linux 5.18 replaced set_page_dirty with dirty_folio + AC_CHECK_LINUX_STRUCT([address_space_operations], [dirty_folio], [fs.h]) ++dnl linux 5.18 replaced readpages with readahead (introduced in 5.8) ++AC_CHECK_LINUX_STRUCT([address_space_operations], [readahead], [fs.h]) + AC_CHECK_LINUX_STRUCT([backing_dev_info], [name], + [backing-dev.h]) + AC_CHECK_LINUX_STRUCT([cred], [session_keyring], [cred.h]) +-- +2.36.1 + @@ -6,7 +6,7 @@ pkgname=openafs-modules _srcname=openafs pkgver=1.8.8.1 -pkgrel=2 +pkgrel=3 pkgdesc="Kernel module for OpenAFS" arch=('i686' 'x86_64' 'armv7h') url="http://www.openafs.org" @@ -16,18 +16,32 @@ makedepends=('libelf' 'linux-headers') conflicts=('openafs-features-libafs' 'openafs<1.6.6-2') options=(!emptydirs) source=("http://openafs.org/dl/openafs/${pkgver}/${_srcname}-${pkgver}-src.tar.bz2" - 0001-Add-autoconf-archive-to-src-external.patch - 0002-Import-of-code-from-autoconf-archive.patch - 0003-Use-autoconf-archive-m4-from-src-external.patch - 0004-Linux-5.17-kernel-func-complete_and_exit-renamed.patch - 0005-Linux-5.17-Kernel-build-uses-Wcast-function-type.patch) + 0001-Add-autoconf-archive-to-src-external.patch + 0002-Import-of-code-from-autoconf-archive.patch + 0003-Use-autoconf-archive-m4-from-src-external.patch + 0004-Linux-5.17-kernel-func-complete_and_exit-renamed.patch + 0005-Linux-5.17-Kernel-build-uses-Wcast-function-type.patch + 0006-Linux-5.18-replace-set_page_dirty-with-dirty_folio.patch + 0007-afs-remove-vestigial-externs-for-afs_xcbhash.patch + 0008-afs-introduce-afs_alloc_ncr-afs_free_ncr.patch + 0009-LINUX-Don-t-panic-on-some-file-open-errors.patch + 0010-afs-Introduce-afs_IsDCacheFresh.patch + 0011-afs-introduce-get_dcache_readahead.patch + 0012-Linux-5.18-replace-readpages-with-readahead.patch) install=openafs-modules.install sha256sums=('e7c4bed7075bcd6402e3f0c2d5b9dbe76ad2ee3c5fd5ddc3973a3356ca23ef44' - '67bad31f8a401f1fa4e851a1f8d2d772f6649573f81045cafae94c105bbff173' - '16ced06d3d4ffffa251e20aecd1ccb3fedb4585617b004b8ade0b4eab603b17d' - '3b2aa3343fe4b9401b272fcf0252f4c3f108f1a1e5039718de38b803690c9d74' - 'c9623eac1e8faf2be133d69c6146eb68be800de0c3226acd99848348b5bfd2f4' - '17c71196bf5f1fc1c62bab8f03a102d7ca75fec56de94390851b10bd27efa3e9') + 'cbf078639b9b25d1e9ec191b9c340720f1fe5ebd1b7665c2ea762498fcf66fbf' + 'f1feac79a69b9ecff4c7259842184e16ef1213e9fb5a2601c4963ea3dc12041c' + '97410d4f5a7a09254ffa18411f242234aba483a0a7b989503ee831457c0ddb9f' + '47faddb068dcbbea74c973c23aac7fe29b1482e984a37b5cfee283200da6b9e2' + '45fa5eaa7b0e7e7bc6c9e0b7c5d97e5fefc54f60c084d5e7deddbe2c0c4697e9' + 'd42fa0772193cd6a66e09ba9cdb81b77c636a266caaf0c465331ff7ca3925b1c' + 'b47e4d5405961b7d40bd24e50c18740b9cd85a90e0e7f630101602efb2f12c2f' + '9801be6de6399a2e0d899b0ed71bc5881ede5a926720d32377a24db31b035593' + 'ce21b7ed721d685fb0f1ddf068003410b585e09be7a96daeb1e8bb10378cf4b3' + '7a5410bce86f1471ae5d990b68f2b25fcff8d5f32d2b7fd9e29c098a91ef1cef' + '4816b8502366995eb5e8e58e485db910269a118ea6ed67e8f16e6bc1aab53864' + 'b51739e2670d13a46f0936fd50ef4bfadf40e83b22a53d46dd7b0eb490ebb700') # Heuristic to determine version of installed kernel # You can modify this if the heuristic fails @@ -51,6 +65,25 @@ prepare() { patch -p1 < "${srcdir}/0004-Linux-5.17-kernel-func-complete_and_exit-renamed.patch" patch -p1 < "${srcdir}/0005-Linux-5.17-Kernel-build-uses-Wcast-function-type.patch" + # Linux 5.18 (14939) + patch -p1 < "${srcdir}/0006-Linux-5.18-replace-set_page_dirty-with-dirty_folio.patch" + + # Backport from master to make later patches apply cleanly + patch -p1 < "${srcdir}/0007-afs-remove-vestigial-externs-for-afs_xcbhash.patch" + + # Prep. for Linux 5.18 patch (14954) + patch -p1 < "${srcdir}/0008-afs-introduce-afs_alloc_ncr-afs_free_ncr.patch" + + # Backports from master to make later patches apply cleanly + patch -p1 < "${srcdir}/0009-LINUX-Don-t-panic-on-some-file-open-errors.patch" + patch -p1 < "${srcdir}/0010-afs-Introduce-afs_IsDCacheFresh.patch" + + # Prep. for Linux 5.18 patch (14962) + patch -p1 < "${srcdir}/0011-afs-introduce-get_dcache_readahead.patch" + + # Linux 5.18 (14953) + patch -p1 < "${srcdir}/0012-Linux-5.18-replace-readpages-with-readahead.patch" + # Only needed when changes to configure were made ./regen.sh -q } |