From: Shaun Tancheff Date: Tue, 31 Jan 2023 19:57:14 +0000 (-0800) Subject: LU-16121 llite: invalidate_folio and dirty_folio X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=959ae45a9e863f3c558e3cf90ab9adb51a0cb97d;p=fs%2Flustre-release.git LU-16121 llite: invalidate_folio and dirty_folio linux commit v5.17-rc4-10-g128d1f8241d6 fs: Add invalidate_folio() aops method A struct folio is often analogous to a struct page however a struct folio can represent (contain) multiple pages. linux commit v5.17-rc4-38-g6f31a5a261db fs: Add aops->dirty_folio __set_page_dirty_nobuffers() is replaced with filemap_dirty_folio() Lustre-change: https://review.whamcloud.com/48366 Lustre-commit: f1604e680ba2b919c0c52c76c75a7e0dc27ec3c5 Test-Parameters: trivial HPE-bug-id: LUS-11197 Signed-off-by: Shaun Tancheff Change-Id: Iefe67615b333e066c49c4b884dad5bea3b3ae226 Reviewed-by: Jian Yu Reviewed-by: Petros Koutoupis Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/49850 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Yang Sheng Reviewed-by: Andreas Dilger --- diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index 30d34b4..142c7a1 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -2694,6 +2694,55 @@ AC_DEFUN([LC_PROG_LINUX_SRC], []) AC_DEFUN([LC_PROG_LINUX_RESULTS], []) # +# LC_HAVE_INVALIDATE_FOLIO +# +# linux commit v5.17-rc4-10-g128d1f8241d6 +# fs: Add invalidate_folio() aops method +# +AC_DEFUN([LC_HAVE_INVALIDATE_FOLIO], [ +tmp_flags="$EXTRA_KCFLAGS" +EXTRA_KCFLAGS="-Werror" +LB_CHECK_COMPILE([if have address_spaace_operaions->invalidate_folio() member], +address_spaace_operaions_invalidate_folio, [ + #include + ],[ + struct address_space_operations *aops = NULL; + struct folio *folio = NULL; + aops->invalidate_folio(folio, 0, PAGE_SIZE); + ],[ + AC_DEFINE(HAVE_INVALIDATE_FOLIO, 1, + [address_spaace_operaions->invalidate_folio() member exists]) + ]) +EXTRA_KCFLAGS="$tmp_flags" +]) # LC_HAVE_INVALIDATE_FOLIO + +# +# LC_HAVE_DIRTY_FOLIO +# +# linux commit v5.17-rc4-38-g6f31a5a261db +# fs: Add aops->dirty_folio +# ... replaces ->set_page_dirty() with ->dirty_folio() +# +AC_DEFUN([LC_HAVE_DIRTY_FOLIO], [ +tmp_flags="$EXTRA_KCFLAGS" +EXTRA_KCFLAGS="-Werror" +LB_CHECK_COMPILE([if have address_spaace_operaions->dirty_folio() member], +address_spaace_operaions_dirty_folio, [ + #include + ],[ + struct address_space_operations *aops = NULL; + struct address_space *mapping = NULL; + struct folio *folio = NULL; + bool dirty = aops->dirty_folio(mapping, folio); + (void) dirty; + ],[ + AC_DEFINE(HAVE_DIRTY_FOLIO, 1, + [address_spaace_operaions->dirty_folio() member exists]) + ]) +EXTRA_KCFLAGS="$tmp_flags" +]) # LC_HAVE_DIRTY_FOLIO + +# # LC_PROG_LINUX # # Lustre linux kernel checks @@ -2895,6 +2944,10 @@ AC_DEFUN([LC_PROG_LINUX], [ # 5.16 LC_HAVE_KIOCB_COMPLETE_2ARGS + # 5.18 + LC_HAVE_INVALIDATE_FOLIO + LC_HAVE_DIRTY_FOLIO + # kernel patch to extend integrity interface LC_BIO_INTEGRITY_PREP_FN diff --git a/lustre/llite/rw26.c b/lustre/llite/rw26.c index 60cc814..3991020 100644 --- a/lustre/llite/rw26.c +++ b/lustre/llite/rw26.c @@ -51,6 +51,59 @@ #include "llite_internal.h" #include +#ifdef HAVE_INVALIDATE_FOLIO +/** + * Implements Linux VM address_space::invalidate_folio() method. This method is + * called when the folio is truncated from a file, either as a result of + * explicit truncate, or when inode is removed from memory (as a result of + * final iput(), umount, or memory pressure induced icache shrinking). + * + * [0, off] bytes of the folio remain valid (this is for a case of non-page + * aligned truncate). Lustre leaves partially truncated folios in the cache, + * relying on struct inode::i_size to limit further accesses. + */ +static void ll_invalidate_folio(struct folio *folio, size_t offset, size_t len) +{ + struct inode *inode; + struct lu_env *env; + struct cl_page *page; + struct cl_object *obj; + + LASSERT(!folio_test_writeback(folio)); + LASSERT(folio_test_locked(folio)); + + if (!(offset == 0 && len == folio_size(folio)) && + !folio_test_large(folio)) + return; + + /* Drop the pages from the folio */ + env = cl_env_percpu_get(); + LASSERT(!IS_ERR(env)); + + inode = folio_inode(folio); + obj = ll_i2info(inode)->lli_clob; + if (obj != NULL) { + int n, npgs = folio_nr_pages(folio); + + for (n = 0; n < npgs; n++) { + struct page *vmpage = folio_page(folio, n); + + LASSERT(PageLocked(vmpage)); + LASSERT(!PageWriteback(vmpage)); + + page = cl_vmpage_page(vmpage, obj); + if (page != NULL) { + cl_page_delete(env, page); + cl_page_put(env, page); + } + } + } else { + LASSERT(!folio_get_private(folio)); + } + cl_env_percpu_put(env); +} +#else + /** * Implements Linux VM address_space::invalidatepage() method. This method is * called when the page is truncate from a file, either as a result of @@ -69,13 +122,13 @@ static void ll_invalidatepage(struct page *vmpage, #endif ) { - struct inode *inode; - struct lu_env *env; - struct cl_page *page; - struct cl_object *obj; + struct inode *inode; + struct lu_env *env; + struct cl_page *page; + struct cl_object *obj; - LASSERT(PageLocked(vmpage)); - LASSERT(!PageWriteback(vmpage)); + LASSERT(PageLocked(vmpage)); + LASSERT(!PageWriteback(vmpage)); /* * It is safe to not check anything in invalidatepage/releasepage @@ -103,7 +156,7 @@ static void ll_invalidatepage(struct page *vmpage, LASSERT(vmpage->private == 0); cl_env_percpu_put(env); - } + } if (OBD_FAIL_PRECHECK(OBD_FAIL_LLITE_PAGE_INVALIDATE_PAUSE)) { unlock_page(vmpage); @@ -112,6 +165,7 @@ static void ll_invalidatepage(struct page *vmpage, lock_page(vmpage); } } +#endif #ifdef HAVE_RELEASEPAGE_WITH_INT #define RELEASEPAGE_ARG_TYPE int @@ -924,16 +978,24 @@ static int ll_migratepage(struct address_space *mapping, #endif const struct address_space_operations ll_aops = { - .readpage = ll_readpage, - .direct_IO = ll_direct_IO, - .writepage = ll_writepage, - .writepages = ll_writepages, - .set_page_dirty = __set_page_dirty_nobuffers, - .write_begin = ll_write_begin, - .write_end = ll_write_end, - .invalidatepage = ll_invalidatepage, - .releasepage = (void *)ll_releasepage, +#ifdef HAVE_DIRTY_FOLIO + .dirty_folio = filemap_dirty_folio, +#else + .set_page_dirty = __set_page_dirty_nobuffers, +#endif +#ifdef HAVE_INVALIDATE_FOLIO + .invalidate_folio = ll_invalidate_folio, +#else + .invalidatepage = ll_invalidatepage, +#endif + .readpage = ll_readpage, + .releasepage = (void *)ll_releasepage, + .direct_IO = ll_direct_IO, + .writepage = ll_writepage, + .writepages = ll_writepages, + .write_begin = ll_write_begin, + .write_end = ll_write_end, #ifdef CONFIG_MIGRATION - .migratepage = ll_migratepage, + .migratepage = ll_migratepage, #endif };