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);
 	}
 
openSUSE Build Service is sponsored by