]) # 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
# 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
])
# 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
])
}
#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 */
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;
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",
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);
} else {
unlock_page(vmpage);
result = PTR_ERR(page);
- }
+ }
out:
if (ra.cra_release != NULL)
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
}
#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 *page;
- struct address_space *mapping;
+ struct lu_env *env;
+ struct cl_object *obj;
+ struct cl_page *page;
+ struct address_space *mapping;
int result = 0;
ENTRY;
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)
}
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;
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);
}
#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,
* 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;
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.
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),