diff --git a/linux-6_17.patch b/linux-6_17.patch new file mode 100644 index 0000000..e7971f8 --- /dev/null +++ b/linux-6_17.patch @@ -0,0 +1,212 @@ +diff -rubN zfs-2.3.4/config/kernel-dentry-operations.m4 zfs-2.3.4-patched/config/kernel-dentry-operations.m4 +--- zfs-2.3.4/config/kernel-dentry-operations.m4 1969-12-31 19:00:00.000000000 -0500 ++++ zfs-2.3.4-patched/config/kernel-dentry-operations.m4 2025-10-06 16:27:39.727925545 -0400 +@@ -0,0 +1,57 @@ ++dnl # ++dnl # 2.6.28 API change ++dnl # Added d_obtain_alias() helper function. ++dnl # ++AC_DEFUN([ZFS_AC_KERNEL_SRC_D_OBTAIN_ALIAS], [ ++ ZFS_LINUX_TEST_SRC([d_obtain_alias], [ ++ #include ++ ], [ ++ d_obtain_alias(NULL); ++ ]) ++]) ++ ++AC_DEFUN([ZFS_AC_KERNEL_D_OBTAIN_ALIAS], [ ++ AC_MSG_CHECKING([whether d_obtain_alias() is available]) ++ ZFS_LINUX_TEST_RESULT_SYMBOL([d_obtain_alias], ++ [d_obtain_alias], [fs/dcache.c], [ ++ AC_MSG_RESULT(yes) ++ ], [ ++ ZFS_LINUX_TEST_ERROR([d_obtain_alias()]) ++ ]) ++]) ++ ++dnl # ++dnl # 2.6.38 API change ++dnl # Added d_set_d_op() helper function. ++dnl # ++dnl # 6.17 API change ++dnl # d_set_d_op() removed. No direct replacement. ++dnl # ++AC_DEFUN([ZFS_AC_KERNEL_SRC_D_SET_D_OP], [ ++ ZFS_LINUX_TEST_SRC([d_set_d_op], [ ++ #include ++ ], [ ++ d_set_d_op(NULL, NULL); ++ ]) ++]) ++ ++AC_DEFUN([ZFS_AC_KERNEL_D_SET_D_OP], [ ++ AC_MSG_CHECKING([whether d_set_d_op() is available]) ++ ZFS_LINUX_TEST_RESULT([d_set_d_op], [ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_D_SET_D_OP, 1, ++ [Define if d_set_d_op() is available]) ++ ], [ ++ AC_MSG_RESULT(no) ++ ]) ++]) ++ ++AC_DEFUN([ZFS_AC_KERNEL_SRC_DENTRY], [ ++ ZFS_AC_KERNEL_SRC_D_OBTAIN_ALIAS ++ ZFS_AC_KERNEL_SRC_D_SET_D_OP ++]) ++ ++AC_DEFUN([ZFS_AC_KERNEL_DENTRY], [ ++ ZFS_AC_KERNEL_D_OBTAIN_ALIAS ++ ZFS_AC_KERNEL_D_SET_D_OP ++]) +diff -rubN zfs-2.3.4/config/kernel.m4 zfs-2.3.4-patched/config/kernel.m4 +--- zfs-2.3.4/config/kernel.m4 2025-08-25 16:40:13.389546595 -0400 ++++ zfs-2.3.4-patched/config/kernel.m4 2025-10-06 16:32:46.884390314 -0400 +@@ -70,6 +70,7 @@ + ZFS_AC_KERNEL_SRC_COMMIT_METADATA + ZFS_AC_KERNEL_SRC_SETATTR_PREPARE + ZFS_AC_KERNEL_SRC_INSERT_INODE_LOCKED ++ ZFS_AC_KERNEL_SRC_DENTRY + ZFS_AC_KERNEL_SRC_TRUNCATE_SETSIZE + ZFS_AC_KERNEL_SRC_SECURITY_INODE + ZFS_AC_KERNEL_SRC_FST_MOUNT +@@ -188,6 +189,7 @@ + ZFS_AC_KERNEL_COMMIT_METADATA + ZFS_AC_KERNEL_SETATTR_PREPARE + ZFS_AC_KERNEL_INSERT_INODE_LOCKED ++ ZFS_AC_KERNEL_DENTRY + ZFS_AC_KERNEL_TRUNCATE_SETSIZE + ZFS_AC_KERNEL_SECURITY_INODE + ZFS_AC_KERNEL_FST_MOUNT +diff -rubN zfs-2.3.4/include/os/linux/kernel/linux/dcache_compat.h zfs-2.3.4-patched/include/os/linux/kernel/linux/dcache_compat.h +--- zfs-2.3.4/include/os/linux/kernel/linux/dcache_compat.h 2025-08-25 16:40:13.404546825 -0400 ++++ zfs-2.3.4-patched/include/os/linux/kernel/linux/dcache_compat.h 2025-10-06 15:49:08.526072692 -0400 +@@ -61,32 +61,6 @@ + #endif + + /* +- * 2.6.30 API change, +- * The const keyword was added to the 'struct dentry_operations' in +- * the dentry structure. To handle this we define an appropriate +- * dentry_operations_t typedef which can be used. +- */ +-typedef const struct dentry_operations dentry_operations_t; +- +-/* +- * 2.6.38 API addition, +- * Added d_clear_d_op() helper function which clears some flags and the +- * registered dentry->d_op table. This is required because d_set_d_op() +- * issues a warning when the dentry operations table is already set. +- * For the .zfs control directory to work properly we must be able to +- * override the default operations table and register custom .d_automount +- * and .d_revalidate callbacks. +- */ +-static inline void +-d_clear_d_op(struct dentry *dentry) +-{ +- dentry->d_op = NULL; +- dentry->d_flags &= ~( +- DCACHE_OP_HASH | DCACHE_OP_COMPARE | +- DCACHE_OP_REVALIDATE | DCACHE_OP_DELETE); +-} +- +-/* + * Walk and invalidate all dentry aliases of an inode + * unless it's a mountpoint + */ +diff -rubN zfs-2.3.4/META zfs-2.3.4-patched/META +--- zfs-2.3.4/META 2025-08-25 16:57:18.433934348 -0400 ++++ zfs-2.3.4-patched/META 2025-10-06 16:42:51.914203831 -0400 +@@ -6,5 +6,5 @@ + Release-Tags: relext + License: CDDL + Author: OpenZFS +-Linux-Maximum: 6.16 ++Linux-Maximum: 6.17 + Linux-Minimum: 4.18 +diff -rubN zfs-2.3.4/module/os/linux/zfs/zpl_ctldir.c zfs-2.3.4-patched/module/os/linux/zfs/zpl_ctldir.c +--- zfs-2.3.4/module/os/linux/zfs/zpl_ctldir.c 2025-08-25 16:57:17.636548533 -0400 ++++ zfs-2.3.4-patched/module/os/linux/zfs/zpl_ctldir.c 2025-10-06 17:20:22.351153585 -0400 +@@ -202,7 +202,7 @@ + return (!!dentry->d_inode); + } + +-static dentry_operations_t zpl_dops_snapdirs = { ++static const struct dentry_operations zpl_dops_snapdirs = { + /* + * Auto mounting of snapshots is only supported for 2.6.37 and + * newer kernels. Prior to this kernel the ops->follow_link() +@@ -215,6 +215,51 @@ + .d_revalidate = zpl_snapdir_revalidate, + }; + ++/* ++ * For the .zfs control directory to work properly we must be able to override ++ * the default operations table and register custom .d_automount and ++ * .d_revalidate callbacks. ++ */ ++static void ++set_snapdir_dentry_ops(struct dentry *dentry, unsigned int extraflags) { ++ static const unsigned int op_flags = ++ DCACHE_OP_HASH | DCACHE_OP_COMPARE | ++ DCACHE_OP_REVALIDATE | DCACHE_OP_DELETE | ++ DCACHE_OP_PRUNE | DCACHE_OP_WEAK_REVALIDATE | DCACHE_OP_REAL; ++ ++#ifdef HAVE_D_SET_D_OP ++ /* ++ * d_set_d_op() will set the DCACHE_OP_ flags according to what it ++ * finds in the passed dentry_operations, so we don't have to. ++ * ++ * We clear the flags and the old op table before calling d_set_d_op() ++ * because issues a warning when the dentry operations table is already ++ * set. ++ */ ++ dentry->d_op = NULL; ++ dentry->d_flags &= ~op_flags; ++ d_set_d_op(dentry, &zpl_dops_snapdirs); ++ dentry->d_flags |= extraflags; ++#else ++ /* ++ * Since 6.17 there's no exported way to modify dentry ops, so we have ++ * to reach in and do it ourselves. This should be safe for our very ++ * narrow use case, which is to create or splice in an entry to give ++ * access to a snapshot. ++ * ++ * We need to set the op flags directly. We hardcode ++ * DCACHE_OP_REVALIDATE because that's the only operation we have; if ++ * we ever extend zpl_dops_snapdirs we will need to update the op flags ++ * to match. ++ */ ++ spin_lock(&dentry->d_lock); ++ dentry->d_op = &zpl_dops_snapdirs; ++ dentry->d_flags &= ~op_flags; ++ dentry->d_flags |= DCACHE_OP_REVALIDATE | extraflags; ++ spin_unlock(&dentry->d_lock); ++#endif ++} ++ + static struct dentry * + zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry, + unsigned int flags) +@@ -236,10 +281,7 @@ + return (ERR_PTR(error)); + + ASSERT(error == 0 || ip == NULL); +- d_clear_d_op(dentry); +- d_set_d_op(dentry, &zpl_dops_snapdirs); +- dentry->d_flags |= DCACHE_NEED_AUTOMOUNT; +- ++ set_snapdir_dentry_ops(dentry, DCACHE_NEED_AUTOMOUNT); + return (d_splice_alias(ip, dentry)); + } + +@@ -373,8 +415,7 @@ + + error = -zfsctl_snapdir_mkdir(dip, dname(dentry), vap, &ip, cr, 0); + if (error == 0) { +- d_clear_d_op(dentry); +- d_set_d_op(dentry, &zpl_dops_snapdirs); ++ set_snapdir_dentry_ops(dentry, 0); + d_instantiate(dentry, ip); + } + diff --git a/zfs.spec b/zfs.spec index c73dfba..932379d 100644 --- a/zfs.spec +++ b/zfs.spec @@ -39,6 +39,7 @@ Source2: https://github.com/zfsonlinux/zfs/releases/download/%name-%versi Source8: %name.keyring Source9: %name-preamble Patch1: kmod.diff +Patch2: linux-6_17.patch BuildRequires: %kernel_module_package_buildreqs %if 0%{?kmp_longterm} BuildRequires: kernel-syms-longterm