aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/kernel-vfs-filemap_dirty_folio.m430
-rw-r--r--config/kernel.m42
-rw-r--r--module/os/linux/zfs/zfs_vnops_os.c4
-rw-r--r--module/os/linux/zfs/zpl_file.c9
4 files changed, 44 insertions, 1 deletions
diff --git a/config/kernel-vfs-filemap_dirty_folio.m4 b/config/kernel-vfs-filemap_dirty_folio.m4
new file mode 100644
index 000000000..872879002
--- /dev/null
+++ b/config/kernel-vfs-filemap_dirty_folio.m4
@@ -0,0 +1,30 @@
+dnl #
+dnl # Linux 5.18 uses filemap_dirty_folio in lieu of
+dnl # ___set_page_dirty_nobuffers
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_FILEMAP_DIRTY_FOLIO], [
+ ZFS_LINUX_TEST_SRC([vfs_has_filemap_dirty_folio], [
+ #include <linux/pagemap.h>
+ #include <linux/writeback.h>
+
+ static const struct address_space_operations
+ aops __attribute__ ((unused)) = {
+ .dirty_folio = filemap_dirty_folio,
+ };
+ ],[])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_VFS_FILEMAP_DIRTY_FOLIO], [
+ dnl #
+ dnl # Linux 5.18 uses filemap_dirty_folio in lieu of
+ dnl # ___set_page_dirty_nobuffers
+ dnl #
+ AC_MSG_CHECKING([filemap_dirty_folio exists])
+ ZFS_LINUX_TEST_RESULT([vfs_has_filemap_dirty_folio], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_VFS_FILEMAP_DIRTY_FOLIO, 1,
+ [filemap_dirty_folio exists])
+ ],[
+ AC_MSG_RESULT([no])
+ ])
+])
diff --git a/config/kernel.m4 b/config/kernel.m4
index 432089407..a70db91a8 100644
--- a/config/kernel.m4
+++ b/config/kernel.m4
@@ -101,6 +101,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
ZFS_AC_KERNEL_SRC_SET_NLINK
ZFS_AC_KERNEL_SRC_SGET
ZFS_AC_KERNEL_SRC_LSEEK_EXECUTE
+ ZFS_AC_KERNEL_SRC_VFS_FILEMAP_DIRTY_FOLIO
ZFS_AC_KERNEL_SRC_VFS_GETATTR
ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS
ZFS_AC_KERNEL_SRC_VFS_ITERATE
@@ -217,6 +218,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
ZFS_AC_KERNEL_SET_NLINK
ZFS_AC_KERNEL_SGET
ZFS_AC_KERNEL_LSEEK_EXECUTE
+ ZFS_AC_KERNEL_VFS_FILEMAP_DIRTY_FOLIO
ZFS_AC_KERNEL_VFS_GETATTR
ZFS_AC_KERNEL_VFS_FSYNC_2ARGS
ZFS_AC_KERNEL_VFS_ITERATE
diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c
index b65728f0d..2ba90d889 100644
--- a/module/os/linux/zfs/zfs_vnops_os.c
+++ b/module/os/linux/zfs/zfs_vnops_os.c
@@ -3556,7 +3556,11 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc)
dmu_tx_wait(tx);
dmu_tx_abort(tx);
+#ifdef HAVE_VFS_FILEMAP_DIRTY_FOLIO
+ filemap_dirty_folio(page_mapping(pp), page_folio(pp));
+#else
__set_page_dirty_nobuffers(pp);
+#endif
ClearPageError(pp);
end_page_writeback(pp);
zfs_rangelock_exit(lr);
diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c
index 3307c9c3a..78cf7e7ef 100644
--- a/module/os/linux/zfs/zpl_file.c
+++ b/module/os/linux/zfs/zpl_file.c
@@ -33,9 +33,13 @@
#include <sys/zfs_vfsops.h>
#include <sys/zfs_vnops.h>
#include <sys/zfs_project.h>
-#ifdef HAVE_VFS_SET_PAGE_DIRTY_NOBUFFERS
+#if defined(HAVE_VFS_SET_PAGE_DIRTY_NOBUFFERS) || \
+ defined(HAVE_VFS_FILEMAP_DIRTY_FOLIO)
#include <linux/pagemap.h>
#endif
+#ifdef HAVE_VFS_FILEMAP_DIRTY_FOLIO
+#include <linux/writeback.h>
+#endif
/*
* When using fallocate(2) to preallocate space, inflate the requested
@@ -1166,6 +1170,9 @@ const struct address_space_operations zpl_address_space_operations = {
#ifdef HAVE_VFS_SET_PAGE_DIRTY_NOBUFFERS
.set_page_dirty = __set_page_dirty_nobuffers,
#endif
+#ifdef HAVE_VFS_FILEMAP_DIRTY_FOLIO
+ .dirty_folio = filemap_dirty_folio,
+#endif
};
const struct file_operations zpl_file_operations = {