Whamcloud - gitweb
LU-16121 llite: invalidate_folio and dirty_folio 66/48366/13
authorShaun Tancheff <shaun.tancheff@hpe.com>
Tue, 8 Nov 2022 15:26:46 +0000 (09:26 -0600)
committerOleg Drokin <green@whamcloud.com>
Fri, 13 Jan 2023 07:20:28 +0000 (07:20 +0000)
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()

Test-Parameters: trivial
HPE-bug-id: LUS-11197
Signed-off-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Change-Id: Iefe67615b333e066c49c4b884dad5bea3b3ae226
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/48366
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Jian Yu <yujian@whamcloud.com>
Reviewed-by: Petros Koutoupis <petros.koutoupis@hpe.com>
lustre/autoconf/lustre-core.m4
lustre/llite/rw26.c

index 8ccc779..1df9296 100644 (file)
@@ -2804,6 +2804,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 <linux/fs.h>
+       ],[
+               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 <linux/fs.h>
+       ],[
+               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
@@ -3012,6 +3061,10 @@ AC_DEFUN([LC_PROG_LINUX], [
        LC_HAVE_SECURITY_DENTRY_INIT_WITH_XATTR_NAME_ARG
        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
 
index a6e98a2..1c5a88a 100644 (file)
 #include "llite_internal.h"
 #include <lustre_compat.h>
 
+#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
@@ -68,13 +121,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
@@ -102,8 +155,9 @@ static void ll_invalidatepage(struct page *vmpage,
                        LASSERT(vmpage->private == 0);
 
                cl_env_percpu_put(env);
-        }
+       }
 }
+#endif
 
 #ifdef HAVE_RELEASEPAGE_WITH_INT
 #define RELEASEPAGE_ARG_TYPE int
@@ -916,16 +970,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
 };