File linux-6_17.patch of Package zfs-rolling
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 <linux/dcache.h>
+ ], [
+ 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 <linux/dcache.h>
+ ], [
+ 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);
}