From ea74bb05c9a36bcf77698008d340202959be8091 Mon Sep 17 00:00:00 2001 From: Cheyenne Wills Date: Thu, 22 Sep 2022 13:04:59 -0600 Subject: [PATCH] Linux-6.0: Replace add_to_page_cache Linux 6.0 removed the add_to_page_cache function in the Linux commit: 'filemap: Remove add_to_page_cache() and add_to_page_cache_locked()' (2bb876b58d593d7f2522ec0f41f20a74fde76822) The replacement function, filemap_add_folio function is exported as GPL, but a non-GPL wrapper was provided in the Linux 5.15 commit: 'mm/filemap: Add filemap_add_folio()' (9dd3d069406cea073fc633e77bc59abbfde8c6c4) which changed the GPL exported function add_to_page_cache_lru to a non-GPL exported function. The function add_to_page_cache_lru functionally combines the add_to_page_cache with lru_cache_add. Within afs, all the calls to add_to_page_cache follow the pattern of calling the lru_cache_add via the wrapper afs_lru_cache_add immediately after (except in one case noted below). Add an autoconf check to see if add_to_page_cache_lru is available. Introduce a new wrapper function afs_add_to_page_cache_lru that handles calling either add_to_page_cache/afs_lru_cache_add or add_to_page_cache_lru. As noted above there is one function, afs_linux_bypass_readpages, that calls add_to_page_cache but does not immediately call afs_lru_cache_add. This function is only used in Linux kernels prior to 5.18, see the commit: 'Linux-5.18: replace readpages with readahead' (7a181415db) Since this code path is only built for a Linux kernel level where add_to_page_cache should also exists, we do not replace this call. NOTE: The add_to_page_cache_lru was moved into mm/folio-compat.c which has a comment indicating that callers of these functions should migrate to folio calls. However the replacement folio call that is needed by afs, filemap_add_folio, is exported as GPL. Change-Id: I10087ebeb8b08309e6c1bab4fc43f7e9f50bd105 --- src/afs/LINUX/osi_vnodeops.c | 30 ++++++++++++++++++++++-------- src/cf/linux-kernel-func.m4 | 10 ++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 621e4da38..bec30bb4c 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -148,6 +148,23 @@ afs_lru_cache_finalize(struct afs_lru_pages *alrupages) } #endif /* !HAVE_LINUX_LRU_ADD_FILE */ +static inline int +afs_add_to_page_cache_lru(struct afs_lru_pages *alrupages, struct page *page, + struct address_space *mapping, + pgoff_t index, gfp_t gfp) +{ +#if defined(HAVE_LINUX_ADD_TO_PAGE_CACHE_LRU) + return add_to_page_cache_lru(page, mapping, index, gfp); +#else + int code; + code = add_to_page_cache(page, mapping, index, gfp); + if (code == 0) { + afs_lru_cache_add(alrupages, page); + } + return code; +#endif +} + /* This function converts a positive error code from AFS into a negative * code suitable for passing into the Linux VFS layer. It checks that the * error code is within the permissable bounds for the ERR_PTR mechanism. @@ -2269,12 +2286,11 @@ afs_linux_read_cache(struct file *cachefp, struct page *page, goto out; } - code = add_to_page_cache(newpage, cachemapping, - pageindex, GFP_KERNEL); + code = afs_add_to_page_cache_lru(alrupages, newpage, cachemapping, + pageindex, GFP_KERNEL); if (code == 0) { cachepage = newpage; newpage = NULL; - afs_lru_cache_add(alrupages, cachepage); } else { put_page(newpage); newpage = NULL; @@ -3092,11 +3108,9 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, goto out; } - if (tdc && !add_to_page_cache(page, mapping, page->index, - GFP_KERNEL)) { - afs_lru_cache_add(&lrupages, page); - - /* Note that add_to_page_cache() locked 'page'. + if (tdc && !afs_add_to_page_cache_lru(&lrupages, page, mapping, page->index, + GFP_KERNEL)) { + /* Note that afs_add_to_page_cache_lru() locks the 'page'. * afs_linux_read_cache() is guaranteed to handle unlocking it. */ afs_linux_read_cache(cacheFp, page, tdc->f.chunk, &lrupages, task); } diff --git a/src/cf/linux-kernel-func.m4 b/src/cf/linux-kernel-func.m4 index 27a1d4141..d3abdf9ff 100644 --- a/src/cf/linux-kernel-func.m4 +++ b/src/cf/linux-kernel-func.m4 @@ -189,6 +189,16 @@ AC_CHECK_LINUX_FUNC([kthread_complete_and_exit], #include ], [kthread_complete_and_exit(0, 0);]) +dnl Linux 6.0 removed add_to_page_cache. It's replacement, filemap_add_folio, +dnl was added in 5.15 and is GPL-only, but has a NON-GPL wrapper called +dnl add_to_page_cache_lru. +dnl Note prior to 5.15, add_to_page_cache_lru was either not exported or +dnl or exported as GPL-only. +AC_CHECK_LINUX_FUNC([add_to_page_cache_lru], + [#include + #include ], + [add_to_page_cache_lru(NULL, NULL, 0, 0);]) + 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"], -- 2.37.3