diff --git a/config/kernel-vfs-filemap_dirty_folio.m4 b/config/kernel-vfs-filemap_dirty_folio.m4 new file mode 100644 index 000000000000..872879002928 --- /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 + #include + + 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 bb3fe2ebdd14..20a946aa6ca4 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -100,6 +100,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 @@ -213,6 +214,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 2958439ace82..796a86c25ab7 100644 --- a/module/os/linux/zfs/zfs_vnops_os.c +++ b/module/os/linux/zfs/zfs_vnops_os.c @@ -3594,7 +3594,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 1ed41b9c4c20..f6ba3ef31454 100644 --- a/module/os/linux/zfs/zpl_file.c +++ b/module/os/linux/zfs/zpl_file.c @@ -33,9 +33,13 @@ #include #include #include -#ifdef HAVE_VFS_SET_PAGE_DIRTY_NOBUFFERS +#if defined(HAVE_VFS_SET_PAGE_DIRTY_NOBUFFERS) || \ + defined(HAVE_VFS_FILEMAP_DIRTY_FOLIO) #include #endif +#ifdef HAVE_VFS_FILEMAP_DIRTY_FOLIO +#include +#endif /* * When using fallocate(2) to preallocate space, inflate the requested @@ -1058,6 +1062,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 = {