Whamcloud - gitweb
LU-16327 llite: read_folio, release_folio, filler_t 99/49199/20
authorShaun Tancheff <shaun.tancheff@hpe.com>
Sun, 2 Apr 2023 11:45:49 +0000 (06:45 -0500)
committerOleg Drokin <green@whamcloud.com>
Tue, 11 Apr 2023 20:06:04 +0000 (20:06 +0000)
Linux commit v5.18-rc5-221-gb7446e7cf15f
  fs: Remove aop flags parameter from grab_cache_page_write_begin()
flags have been dropped from write_begin() and
grab_cache_page_write_begin()

Linux commit v5.18-rc5-241-g5efe7448a142
  fs: Introduce aops->read_folio
Provide a ll_read_folio handler around ll_readpage

Linux commit v5.18-rc5-280-ge9b5b23e957e
  fs: Change the type of filler_t
Affects read_cache_page, provides a wrapper for read_cache_page
and wrappers for filler functions

Linux commit v5.18-rc5-282-gfa29000b6b26
  fs: Add aops->release_folio
Provide an ll_release_folio function based on ll_releasepage

Test-Parameters: trivial
HPE-bug-id: LUS-11357
Signed-off-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Change-Id: Ibd4ec1133c80cd0eb8400c4cd07b50e421dd35c5
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/49199
Tested-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/autoconf/lustre-core.m4
lustre/include/lustre_compat.h
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/rw.c
lustre/llite/rw26.c
lustre/mdc/mdc_request.c

index 7f6e413..c80f0b5 100644 (file)
@@ -3273,25 +3273,124 @@ AC_DEFUN([LC_HAVE_DIRTY_FOLIO], [
 # linux commit v5.17-49-g8b9f3ac5b01d
 #   fs: introduce alloc_inode_sb() to allocate filesystems specific inode
 #
-AC_DEFUN([LC_HAVE_ALLOC_INODE_SB], [
-tmp_flags="$EXTRA_KCFLAGS"
-EXTRA_KCFLAGS="-Werror"
-LB_CHECK_COMPILE([if alloc_inode_sb() exists],
-alloc_inode_sb, [
+AC_DEFUN([LC_SRC_HAVE_ALLOC_INODE_SB], [
+       LB2_LINUX_TEST_SRC([alloc_inode_sb], [
                #include <linux/fs.h>
        ],[
                struct super_block *sb = NULL;
                struct kmem_cache *cache = NULL;
 
                (void)alloc_inode_sb(sb, cache, GFP_NOFS);
-       ],[
+       ],[-Werror])
+])
+AC_DEFUN([LC_HAVE_ALLOC_INODE_SB], [
+       AC_MSG_CHECKING([if alloc_inode_sb() exists])
+       LB2_LINUX_TEST_RESULT([alloc_inode_sb], [
                AC_DEFINE(HAVE_ALLOC_INODE_SB, 1,
                        [alloc_inode_sb() exists])
        ])
-EXTRA_KCFLAGS="$tmp_flags"
 ]) # LC_HAVE_ALLOC_INODE_SB
 
 #
+# LC_GRAB_CACHE_PAGE_WRITE_BEGIN_WITH_FLAGS
+#
+# Linux commit v5.18-rc5-221-gb7446e7cf15f
+#   fs: Remove aop flags parameter from grab_cache_page_write_begin()
+#
+AC_DEFUN([LC_SRC_GRAB_CACHE_PAGE_WRITE_BEGIN_WITH_FLAGS], [
+       LB2_LINUX_TEST_SRC([grab_cache_page_write_begin_with_flags], [
+               #include <linux/pagemap.h>
+       ],[
+               struct address_space *mapping = NULL;
+               (void)grab_cache_page_write_begin(mapping, 0, 1);
+       ],[-Werror])
+]) 
+AC_DEFUN([LC_GRAB_CACHE_PAGE_WRITE_BEGIN_WITH_FLAGS], [
+       AC_MSG_CHECKING([if grab_cache_page_write_begin() has flags argument])
+       LB2_LINUX_TEST_RESULT([grab_cache_page_write_begin_with_flags], [
+               AC_DEFINE(HAVE_GRAB_CACHE_PAGE_WRITE_BEGIN_WITH_FLAGS, 1,
+                       [grab_cache_page_write_begin() has flags argument])
+       ])
+]) # LC_GRAB_CACHE_PAGE_WRITE_BEGIN_WITH_FLAGS
+
+#
+# LC_HAVE_ADDRESS_SPACE_OPERATIONS_READ_FOLIO
+#
+# Linux commit v5.18-rc5-241-g5efe7448a142
+#   fs: Introduce aops->read_folio
+#
+AC_DEFUN([LC_SRC_HAVE_ADDRESS_SPACE_OPERATIONS_READ_FOLIO], [
+       LB2_LINUX_TEST_SRC([address_space_operations_read_folio], [
+               #include <linux/fs.h>
+       ],[
+               struct address_space_operations *aops = NULL;
+               struct file *file = NULL;
+               struct folio *folio = NULL;
+               int err = aops->read_folio(file, folio);
+               (void)err;
+       ],[-Werror])
+])
+AC_DEFUN([LC_HAVE_ADDRESS_SPACE_OPERATIONS_READ_FOLIO], [
+       AC_MSG_CHECKING([if struct address_space_operations() has read_folio()])
+       LB2_LINUX_TEST_RESULT([address_space_operations_read_folio], [
+               AC_DEFINE(HAVE_AOPS_READ_FOLIO, 1,
+                       [struct address_space_operations() has read_folio()])
+       ])
+]) # LC_HAVE_ADDRESS_SPACE_OPERATIONS_READ_FOLIO
+
+#
+# LC_HAVE_READ_CACHE_PAGE_FILLER_WITH_FILE
+#
+# Linux commit v5.18-rc5-280-ge9b5b23e957e
+#   fs: Change the type of filler_t
+#
+AC_DEFUN([LC_SRC_HAVE_READ_CACHE_PAGE_FILLER_WITH_FILE], [
+       LB2_LINUX_TEST_SRC([read_cache_page_filler_with_file], [
+               #include <linux/pagemap.h>
+               static inline int _filler(struct file *file, struct folio *f)
+               {
+                       return 0;
+               }
+       ],[
+               struct address_space *mapping = NULL;
+               struct file *file = NULL;
+               struct page *page = read_cache_page(mapping, 0, _filler, file);
+               (void)page;
+       ],[-Werror])
+])
+AC_DEFUN([LC_HAVE_READ_CACHE_PAGE_FILLER_WITH_FILE], [
+       AC_MSG_CHECKING([if read_cache_page() filler_t needs struct file])
+       LB2_LINUX_TEST_RESULT([read_cache_page_filler_with_file], [
+               AC_DEFINE(HAVE_READ_CACHE_PAGE_WANTS_FILE, 1,
+                       [read_cache_page() filler_t needs struct file])
+       ])
+]) # LC_HAVE_READ_CACHE_PAGE_FILLER_WITH_FILE
+
+#
+# LC_HAVE_ADDRESS_SPACE_OPERATIONS_RELEASE_FOLIO
+#
+# Linux commit v5.18-rc5-282-gfa29000b6b26
+#  fs: Add aops->release_folio
+#
+AC_DEFUN([LC_SRC_HAVE_ADDRESS_SPACE_OPERATIONS_RELEASE_FOLIO], [
+       LB2_LINUX_TEST_SRC([address_space_operations_release_folio], [
+               #include <linux/fs.h>
+       ],[
+               struct address_space_operations *aops = NULL;
+               struct folio *folio = NULL;
+               int err = aops->release_folio(folio, GFP_KERNEL);
+               (void)err;
+       ],[-Werror])
+])
+AC_DEFUN([LC_HAVE_ADDRESS_SPACE_OPERATIONS_RELEASE_FOLIO], [
+       AC_MSG_CHECKING([if struct address_space_operations() has release_folio()])
+       LB2_LINUX_TEST_RESULT([address_space_operations_release_folio], [
+               AC_DEFINE(HAVE_AOPS_RELEASE_FOLIO, 1,
+                       [struct address_space_operations() has release_folio()])
+       ])
+]) # LC_HAVE_ADDRESS_SPACE_OPERATIONS_RELEASE_FOLIO
+
+#
 # LC_PROG_LINUX
 #
 # Lustre linux kernel checks
@@ -3503,10 +3602,19 @@ AC_DEFUN([LC_PROG_LINUX_SRC], [
        LC_SRC_HAVE_SECURITY_DENTRY_INIT_WITH_XATTR_NAME_ARG
        LC_SRC_HAVE_KIOCB_COMPLETE_2ARGS
 
-       # 5.18
+       # 5.17
        LC_SRC_HAVE_INVALIDATE_FOLIO
        LC_SRC_HAVE_DIRTY_FOLIO
 
+       # 5.18
+       LC_SRC_HAVE_ALLOC_INODE_SB
+
+       # 5.19
+       LC_SRC_GRAB_CACHE_PAGE_WRITE_BEGIN_WITH_FLAGS
+       LC_SRC_HAVE_ADDRESS_SPACE_OPERATIONS_READ_FOLIO
+       LC_SRC_HAVE_READ_CACHE_PAGE_FILLER_WITH_FILE
+       LC_SRC_HAVE_ADDRESS_SPACE_OPERATIONS_RELEASE_FOLIO
+
        # kernel patch to extend integrity interface
        LC_SRC_BIO_INTEGRITY_PREP_FN
 ])
@@ -3740,6 +3848,12 @@ AC_DEFUN([LC_PROG_LINUX_RESULTS], [
        # 5.18
        LC_HAVE_ALLOC_INODE_SB
 
+       # 5.19
+       LC_GRAB_CACHE_PAGE_WRITE_BEGIN_WITH_FLAGS
+       LC_HAVE_ADDRESS_SPACE_OPERATIONS_READ_FOLIO
+       LC_HAVE_READ_CACHE_PAGE_FILLER_WITH_FILE
+       LC_HAVE_ADDRESS_SPACE_OPERATIONS_RELEASE_FOLIO
+
        # kernel patch to extend integrity interface
        LC_BIO_INTEGRITY_PREP_FN
 ])
index 4f2bd8a..696a9df 100644 (file)
@@ -620,4 +620,19 @@ static inline void cfs_delete_from_page_cache(struct page *page)
 }
 #endif
 
+static inline struct page *ll_read_cache_page(struct address_space *mapping,
+                                             pgoff_t index, filler_t *filler,
+                                             void *data)
+{
+#ifdef HAVE_READ_CACHE_PAGE_WANTS_FILE
+       struct file dummy_file;
+
+       dummy_file.f_ra.ra_pages = 32; /* unused, modified on ra error */
+       dummy_file.private_data = data;
+       return read_cache_page(mapping, index, filler, &dummy_file);
+#else
+       return read_cache_page(mapping, index, filler, data);
+#endif /* HAVE_READ_CACHE_PAGE_WANTS_FILE */
+}
+
 #endif /* _LUSTRE_COMPAT_H */
index 04138c5..9f83b2b 100644 (file)
@@ -491,6 +491,15 @@ static inline int ll_dom_readpage(void *data, struct page *page)
        return rc;
 }
 
+#ifdef HAVE_READ_CACHE_PAGE_WANTS_FILE
+static inline int ll_dom_read_folio(struct file *file, struct folio *folio0)
+{
+       return ll_dom_readpage(file->private_data, folio_page(folio0, 0));
+}
+#else
+#define ll_dom_read_folio      ll_dom_readpage
+#endif
+
 void ll_dom_finish_open(struct inode *inode, struct ptlrpc_request *req)
 {
        struct lu_env *env;
@@ -568,8 +577,8 @@ void ll_dom_finish_open(struct inode *inode, struct ptlrpc_request *req)
                if (lnb.lnb_len > PAGE_SIZE)
                        lnb.lnb_len = PAGE_SIZE;
 
-               vmpage = read_cache_page(mapping, index + start,
-                                        ll_dom_readpage, &lnb);
+               vmpage = ll_read_cache_page(mapping, index + start,
+                                           ll_dom_read_folio, &lnb);
                if (IS_ERR(vmpage)) {
                        CWARN("%s: cannot fill page %lu for "DFID
                              " with data: rc = %li\n",
index 569df1f..b0e7a31 100644 (file)
@@ -1157,6 +1157,9 @@ void ll_update_times(struct ptlrpc_request *request, struct inode *inode);
 int ll_writepage(struct page *page, struct writeback_control *wbc);
 int ll_writepages(struct address_space *, struct writeback_control *wbc);
 int ll_readpage(struct file *file, struct page *page);
+#ifdef HAVE_AOPS_READ_FOLIO
+int ll_read_folio(struct file *file, struct folio *folio);
+#endif
 int ll_io_read_page(const struct lu_env *env, struct cl_io *io,
                           struct cl_page *page, struct file *file);
 void ll_readahead_init(struct inode *inode, struct ll_readahead_state *ras);
index bad0150..e135b4b 100644 (file)
@@ -2036,7 +2036,7 @@ int ll_readpage(struct file *file, struct page *vmpage)
        } else {
                unlock_page(vmpage);
                result = PTR_ERR(page);
-        }
+       }
 
 out:
        if (ra.cra_release != NULL)
@@ -2044,3 +2044,10 @@ out:
 
        RETURN(result);
 }
+
+#ifdef HAVE_AOPS_READ_FOLIO
+int ll_read_folio(struct file *file, struct folio *folio)
+{
+       return ll_readpage(file, folio_page(folio, 0));
+}
+#endif
index 30da2b9..0480952 100644 (file)
@@ -166,17 +166,12 @@ static void ll_invalidatepage(struct page *vmpage,
 }
 #endif
 
-#ifdef HAVE_RELEASEPAGE_WITH_INT
-#define RELEASEPAGE_ARG_TYPE int
-#else
-#define RELEASEPAGE_ARG_TYPE gfp_t
-#endif
-static int ll_releasepage(struct page *vmpage, RELEASEPAGE_ARG_TYPE gfp_mask)
+static bool do_release_page(struct page *vmpage, gfp_t wait)
 {
-       struct lu_env           *env;
-       struct cl_object        *obj;
-       struct cl_page          *clpage;
-       struct address_space    *mapping;
+       struct lu_env *env;
+       struct cl_object *obj;
+       struct cl_page *clpage;
+       struct address_space *mapping;
        int result = 0;
 
        LASSERT(PageLocked(vmpage));
@@ -230,6 +225,28 @@ static int ll_releasepage(struct page *vmpage, RELEASEPAGE_ARG_TYPE gfp_mask)
        return result;
 }
 
+#ifdef HAVE_AOPS_RELEASE_FOLIO
+static bool ll_release_folio(struct folio *folio, gfp_t wait)
+{
+       struct page *vmpage = folio_page(folio, 0);
+
+       /* folio_nr_pages(folio) == 1 is fixed with grab_cache_page* */
+       BUG_ON(folio_nr_pages(folio) != 1);
+
+       return do_release_page(vmpage, wait);
+}
+#else /* !HAVE_AOPS_RELEASE_FOLIO */
+#ifdef HAVE_RELEASEPAGE_WITH_INT
+#define RELEASEPAGE_ARG_TYPE int
+#else
+#define RELEASEPAGE_ARG_TYPE gfp_t
+#endif
+static int ll_releasepage(struct page *vmpage, RELEASEPAGE_ARG_TYPE gfp_mask)
+{
+       return do_release_page(vmpage, gfp_mask);
+}
+#endif /* HAVE_AOPS_RELEASE_FOLIO */
+
 static ssize_t ll_get_user_pages(int rw, struct iov_iter *iter,
                                struct page ***pages, ssize_t *npages,
                                size_t maxsize)
@@ -706,7 +723,10 @@ static int ll_tiny_write_begin(struct page *vmpage, struct address_space *mappin
 }
 
 static int ll_write_begin(struct file *file, struct address_space *mapping,
-                         loff_t pos, unsigned len, unsigned flags,
+                         loff_t pos, unsigned int len,
+#ifdef HAVE_GRAB_CACHE_PAGE_WRITE_BEGIN_WITH_FLAGS
+                         unsigned int flags,
+#endif
                          struct page **pagep, void **fsdata)
 {
        struct ll_cl_context *lcc = NULL;
@@ -779,8 +799,11 @@ again:
                        GOTO(out, result);
 
                if (vmpage == NULL) {
-                       vmpage = grab_cache_page_write_begin(mapping, index,
-                                                            flags);
+                       vmpage = grab_cache_page_write_begin(mapping, index
+#ifdef HAVE_GRAB_CACHE_PAGE_WRITE_BEGIN_WITH_FLAGS
+                                                            , flags
+#endif
+                                                            );
                        if (vmpage == NULL)
                                GOTO(out, result = -ENOMEM);
                }
@@ -986,8 +1009,16 @@ const struct address_space_operations ll_aops = {
 #else
        .invalidatepage         = ll_invalidatepage,
 #endif
+#ifdef HAVE_AOPS_READ_FOLIO
+       .read_folio             = ll_read_folio,
+#else
        .readpage               = ll_readpage,
+#endif
+#ifdef HAVE_AOPS_RELEASE_FOLIO
+       .release_folio          = ll_release_folio,
+#else
        .releasepage            = (void *)ll_releasepage,
+#endif
        .direct_IO              = ll_direct_IO,
        .writepage              = ll_writepage,
        .writepages             = ll_writepages,
index 4442efb..dd69a1d 100644 (file)
@@ -1330,7 +1330,7 @@ struct readpage_param {
  * in PAGE_SIZE (if PAGE_SIZE greater than LU_PAGE_SIZE), and the
  * lu_dirpage for this integrated page will be adjusted.
  **/
-static int mdc_read_page_remote(void *data, struct page *page0)
+static int ll_mdc_read_page_remote(void *data, struct page *page0)
 {
        struct readpage_param *rp = data;
        struct page **page_pool;
@@ -1426,6 +1426,16 @@ static int mdc_read_page_remote(void *data, struct page *page0)
        RETURN(rc);
 }
 
+#ifdef HAVE_READ_CACHE_PAGE_WANTS_FILE
+static inline int mdc_read_folio_remote(struct file *file, struct folio *folio)
+{
+       return ll_mdc_read_page_remote(file->private_data,
+                                      folio_page(folio, 0));
+}
+#else
+#define mdc_read_folio_remote  ll_mdc_read_page_remote
+#endif
+
 /**
  * Read dir page from cache first, if it can not find it, read it from
  * server and add into the cache.
@@ -1508,10 +1518,10 @@ static int mdc_read_page(struct obd_export *exp, struct md_op_data *op_data,
 
        rp_param.rp_exp = exp;
        rp_param.rp_mod = op_data;
-       page = read_cache_page(mapping,
-                              hash_x_index(rp_param.rp_off,
-                                           rp_param.rp_hash64),
-                              mdc_read_page_remote, &rp_param);
+       page = ll_read_cache_page(mapping,
+                                 hash_x_index(rp_param.rp_off,
+                                              rp_param.rp_hash64),
+                                 mdc_read_folio_remote, &rp_param);
        if (IS_ERR(page)) {
                CDEBUG(D_INFO, "%s: read cache page: "DFID" at %llu: %ld\n",
                       exp->exp_obd->obd_name, PFID(&op_data->op_fid1),