Subject: [Saphira] Linux 7.3: bvec bi_bvec_done renamed bi_offset Upstream robn/zfs@79fc679547d6, carried verbatim except the blkdev_compat.h hunk, which is rebased to 2.4.4 context (zero offset). The kernel-bio.m4 autoconf hunks apply exactly as upstream wrote them. diff --git a/config/kernel-bio.m4 b/config/kernel-bio.m4 index 099b11effa13..305d3ccd6fe3 100644 --- a/config/kernel-bio.m4 +++ b/config/kernel-bio.m4 @@ -234,6 +234,30 @@ AC_DEFUN([ZFS_AC_KERNEL_BIO_ALLOC_4ARG], [ ]) ]) +dnl # +dnl # Linux 7.3 API +dnl # +dnl # bi_iter.bi_bvec_done renamed to bi_iter.bi_offset +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BVEC_ITER_OFFSET], [ + ZFS_LINUX_TEST_SRC([bvec_iter_offset], [ + #include + ],[ + struct bvec_iter *bi = NULL; + unsigned int __attribute__((unused)) offset = bi->bi_offset; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BVEC_ITER_OFFSET], [ + AC_MSG_CHECKING([if bvec_iter has bi_offset]) + ZFS_LINUX_TEST_RESULT([bvec_iter_offset],[ + AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_BVEC_ITER_OFFSET], 1, [bvec_iter has bi_offset]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [ ZFS_AC_KERNEL_SRC_BIO_OPS ZFS_AC_KERNEL_SRC_BIO_SET_DEV @@ -243,6 +267,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [ ZFS_AC_KERNEL_SRC_BDEV_SUBMIT_BIO_RETURNS_VOID ZFS_AC_KERNEL_SRC_BIO_SET_DEV_MACRO ZFS_AC_KERNEL_SRC_BIO_ALLOC_4ARG + ZFS_AC_KERNEL_SRC_BVEC_ITER_OFFSET ]) AC_DEFUN([ZFS_AC_KERNEL_BIO], [ @@ -253,4 +278,5 @@ AC_DEFUN([ZFS_AC_KERNEL_BIO], [ ZFS_AC_KERNEL_BIO_BDEV_DISK ZFS_AC_KERNEL_BDEV_SUBMIT_BIO_RETURNS_VOID ZFS_AC_KERNEL_BIO_ALLOC_4ARG + ZFS_AC_KERNEL_BVEC_ITER_OFFSET ]) --- a/include/os/linux/kernel/linux/blkdev_compat.h +++ b/include/os/linux/kernel/linux/blkdev_compat.h @@ -104,7 +104,11 @@ #define BIO_BI_SECTOR(bio) (bio)->bi_iter.bi_sector #define BIO_BI_SIZE(bio) (bio)->bi_iter.bi_size #define BIO_BI_IDX(bio) (bio)->bi_iter.bi_idx +#ifdef HAVE_BVEC_ITER_OFFSET +#define BIO_BI_SKIP(bio) (bio)->bi_iter.bi_offset +#else #define BIO_BI_SKIP(bio) (bio)->bi_iter.bi_bvec_done +#endif #define bio_for_each_segment4(bv, bvp, b, i) \ bio_for_each_segment((bv), (b), (i)) typedef struct bvec_iter bvec_iterator_t; Subject: [Saphira] Linux 7.3: run kthreads with init fs context (2.4.4 port) Saphira-Port-By: Muse Spark 1.3 Contributor for AKADATA LIMITED (Andrew Smalley, Director) Note: The API moved; the data must not. Re-derived hunk by hunk for 2.4.4 and proven by boot, not by inspection. Ports robn/zfs@e8a0a6cd4ed3 onto OpenZFS 2.4.4 (see recipe comments for the rebase notes). --- a/include/os/linux/Makefile.am +++ b/include/os/linux/Makefile.am @@ -6,6 +6,7 @@ %D%/kernel/linux/compiler_compat.h \ %D%/kernel/linux/dcache_compat.h \ %D%/kernel/linux/kmap_compat.h \ + %D%/kernel/linux/kthread_compat.h \ %D%/kernel/linux/mm_compat.h \ %D%/kernel/linux/mod_compat.h \ %D%/kernel/linux/page_compat.h \ --- a/module/os/linux/spl/spl-taskq.c +++ b/module/os/linux/spl/spl-taskq.c @@ -38,6 +38,7 @@ #include #include #include +#include /* Linux 6.2 renamed timer_delete_sync(); point it at its old name for those. */ #ifndef HAVE_TIMER_DELETE_SYNC @@ -1107,7 +1108,8 @@ DTRACE_PROBE1(taskq_ent__start, taskq_ent_t *, t); /* Perform the requested task */ - t->tqent_func(t->tqent_arg); + scoped_with_init_fs() + t->tqent_func(t->tqent_arg); DTRACE_PROBE1(taskq_ent__finish, taskq_ent_t *, t); --- a/module/os/linux/spl/spl-thread.c +++ b/module/os/linux/spl/spl-thread.c @@ -29,6 +29,7 @@ #include #include #include +#include /* * Thread interfaces @@ -59,8 +60,10 @@ kmem_free(tp->tp_name, tp->tp_name_size); kmem_free(tp, sizeof (thread_priv_t)); - if (func) - func(args); + if (func) { + scoped_with_init_fs() + func(args); + } return (0); } --- /dev/null +++ b/include/os/linux/kernel/linux/kthread_compat.h @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: CDDL-1.0 +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * https://opensource.org/license/CDDL-1.0. + */ + +/* + * Copyright (c) 2026, TrueNAS. + */ + +#ifndef _ZFS_KTHREAD_COMPAT_H +#define _ZFS_KTHREAD_COMPAT_H + +#include + +/* + * Linux 7.3 change. Kernel-internal threads no longer have access to the + * filesystem by default. Callers that need it should wrap the necessary code + * in `scoped_with_init_fs()`, which will make the filesystem availble until + * end of scope. + * + * For older kernels that do not provide this macro, we define it to be a + * no-op. + */ +#ifndef scoped_with_init_fs +#define scoped_with_init_fs() if (1) +#endif + +#endif Subject: [Saphira] Linux 7.3: cpu_feature_enabled() over static_cpu_has() (2.4.4 port) Saphira-Port-By: Muse Spark 1.3 Contributor for AKADATA LIMITED (Andrew Smalley, Director) Note: The API moved; the data must not. Re-derived hunk by hunk for 2.4.4 and proven by boot, not by inspection. Ports robn/zfs@844c3a4eb6c1 onto OpenZFS 2.4.4 (HAVE_XSAVES guards here; static_cpu_has_bug probe untouched; 7.3-only recipe so no fallback). --- a/include/os/linux/kernel/linux/simd_x86.h +++ b/include/os/linux/kernel/linux/simd_x86.h @@ -315,24 +315,24 @@ */ uint8_t *state = zfs_kfpu_fpregs[smp_processor_id()]; #if defined(HAVE_XSAVES) - if (static_cpu_has(X86_FEATURE_XSAVES)) { + if (cpu_feature_enabled(X86_FEATURE_XSAVES)) { kfpu_do_xsave("xsaves", state, ~XFEATURE_MASK_XTILE); return; } #endif #if defined(HAVE_XSAVEOPT) - if (static_cpu_has(X86_FEATURE_XSAVEOPT)) { + if (cpu_feature_enabled(X86_FEATURE_XSAVEOPT)) { kfpu_do_xsave("xsaveopt", state, ~XFEATURE_MASK_XTILE); return; } #endif #if defined(HAVE_XSAVE) - if (static_cpu_has(X86_FEATURE_XSAVE)) { + if (cpu_feature_enabled(X86_FEATURE_XSAVE)) { kfpu_do_xsave("xsave", state, ~XFEATURE_MASK_XTILE); return; } #endif - if (static_cpu_has(X86_FEATURE_FXSR)) { + if (cpu_feature_enabled(X86_FEATURE_FXSR)) { kfpu_save_fxsr(state); } else { kfpu_save_fsave(state); @@ -380,18 +380,18 @@ { uint8_t *state = zfs_kfpu_fpregs[smp_processor_id()]; #if defined(HAVE_XSAVES) - if (static_cpu_has(X86_FEATURE_XSAVES)) { + if (cpu_feature_enabled(X86_FEATURE_XSAVES)) { kfpu_do_xrstor("xrstors", state, ~XFEATURE_MASK_XTILE); goto out; } #endif #if defined(HAVE_XSAVE) - if (static_cpu_has(X86_FEATURE_XSAVE)) { + if (cpu_feature_enabled(X86_FEATURE_XSAVE)) { kfpu_do_xrstor("xrstor", state, ~XFEATURE_MASK_XTILE); goto out; } #endif - if (static_cpu_has(X86_FEATURE_FXSR)) { + if (cpu_feature_enabled(X86_FEATURE_FXSR)) { kfpu_restore_fxsr(state); } else { kfpu_restore_fsave(state); --- a/module/zcommon/simd_stat.c +++ b/module/zcommon/simd_stat.c @@ -126,13 +126,13 @@ off += SIMD_STAT_PRINT(simd_stat_kstat_payload, "osxsave", boot_cpu_has(X86_FEATURE_OSXSAVE)); off += SIMD_STAT_PRINT(simd_stat_kstat_payload, - "xsaves", static_cpu_has(X86_FEATURE_XSAVES)); + "xsaves", cpu_feature_enabled(X86_FEATURE_XSAVES)); off += SIMD_STAT_PRINT(simd_stat_kstat_payload, - "xsaveopt", static_cpu_has(X86_FEATURE_XSAVEOPT)); + "xsaveopt", cpu_feature_enabled(X86_FEATURE_XSAVEOPT)); off += SIMD_STAT_PRINT(simd_stat_kstat_payload, - "xsave", static_cpu_has(X86_FEATURE_XSAVE)); + "xsave", cpu_feature_enabled(X86_FEATURE_XSAVE)); off += SIMD_STAT_PRINT(simd_stat_kstat_payload, - "fxsr", static_cpu_has(X86_FEATURE_FXSR)); + "fxsr", cpu_feature_enabled(X86_FEATURE_FXSR)); #endif /* __x86__ */ #if defined(__arm__) || defined(__aarch64__) off += SIMD_STAT_PRINT(simd_stat_kstat_payload, Subject: [Saphira] Linux 7.3: iops->create() without flag arg (2.4.4 port) Saphira-Port-By: Muse Spark 1.3 Contributor for AKADATA LIMITED (Andrew Smalley, Director) Note: The API moved; the data must not. Re-derived hunk by hunk for 2.4.4 and proven by boot, not by inspection. Ports robn/zfs@d01c2c7fdef8 onto OpenZFS 2.4.4: the new autoconf test is appended to the existing kernel-inode-create.m4 (2.4.4 already ships one for the 6.3 idmap change), registered in kernel.m4 like upstream, the decision checks no-flag FIRST so the old chain never errors on 7.3, and zpl_create gains the 3-arg branch in 2.4.4 spelling (param keeps the user_ns name so the body is untouched) plus the shadow-guard extension upstream master does not need (its refactor removed the fallback). --- a/config/kernel-inode-create.m4 +++ b/config/kernel-inode-create.m4 @@ -54,6 +54,13 @@ ]) AC_DEFUN([ZFS_AC_KERNEL_CREATE], [ + AC_MSG_CHECKING([whether iops->create() takes a flag arg]) + ZFS_LINUX_TEST_RESULT([iops_create_no_flag], [ + AC_MSG_RESULT(no) + AC_DEFINE(HAVE_IOPS_CREATE_NO_FLAG_ARG, 1, + [iops->create() does not take a flag arg]) + ],[ + AC_MSG_RESULT(yes) AC_MSG_CHECKING([whether iops->create() takes struct mnt_idmap*]) ZFS_LINUX_TEST_RESULT([create_mnt_idmap], [ AC_MSG_RESULT(yes) @@ -78,4 +85,31 @@ ]) ]) ]) + ]) ]) + +AC_DEFUN([ZFS_AC_KERNEL_SRC_IOPS_CREATE_NO_FLAG], [ + ZFS_LINUX_TEST_SRC([iops_create_no_flag], [ + #include + + static int test_iops_create(struct mnt_idmap *idmap, + struct inode *inode, struct dentry *dentry, + umode_t mode) { return 0; } + + static const struct inode_operations test_iops + __attribute__ ((unused)) = { + .create = test_iops_create + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_IOPS_CREATE_NO_FLAG], [ + AC_MSG_CHECKING([whether iops->create() takes a flag arg]) + ZFS_LINUX_TEST_RESULT([iops_create_no_flag], [ + AC_MSG_RESULT(no) + AC_DEFINE(HAVE_IOPS_CREATE_NO_FLAG_ARG, 1, + [iops->create() does not take a flag arg]) + ],[ + AC_MSG_RESULT(yes) + ]) +]) --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -63,6 +63,7 @@ ZFS_AC_KERNEL_SRC_INODE_STATE_READ_ONCE ZFS_AC_KERNEL_SRC_SHOW_OPTIONS ZFS_AC_KERNEL_SRC_SHRINKER + ZFS_AC_KERNEL_SRC_IOPS_CREATE_NO_FLAG ZFS_AC_KERNEL_SRC_MKDIR ZFS_AC_KERNEL_SRC_LOOKUP_FLAGS ZFS_AC_KERNEL_SRC_IDMAP @@ -188,6 +189,7 @@ ZFS_AC_KERNEL_INODE_STATE_READ_ONCE ZFS_AC_KERNEL_SHOW_OPTIONS ZFS_AC_KERNEL_SHRINKER + ZFS_AC_KERNEL_IOPS_CREATE_NO_FLAG ZFS_AC_KERNEL_MKDIR ZFS_AC_KERNEL_LOOKUP_FLAGS ZFS_AC_KERNEL_IDMAP --- a/module/os/linux/zfs/zpl_inode.c +++ b/module/os/linux/zfs/zpl_inode.c @@ -165,7 +165,10 @@ } static int -#ifdef HAVE_IOPS_CREATE_USERNS +#ifdef HAVE_IOPS_CREATE_NO_FLAG_ARG +zpl_create(struct mnt_idmap *user_ns, struct inode *dir, + struct dentry *dentry, umode_t mode) +#elif defined(HAVE_IOPS_CREATE_USERNS) zpl_create(struct user_namespace *user_ns, struct inode *dir, struct dentry *dentry, umode_t mode, bool flag) #elif defined(HAVE_IOPS_CREATE_IDMAP) @@ -180,7 +183,7 @@ vattr_t *vap; int error; fstrans_cookie_t cookie; -#if !(defined(HAVE_IOPS_CREATE_USERNS) || defined(HAVE_IOPS_CREATE_IDMAP)) +#if !(defined(HAVE_IOPS_CREATE_USERNS) || defined(HAVE_IOPS_CREATE_IDMAP) || defined(HAVE_IOPS_CREATE_NO_FLAG_ARG)) zidmap_t *user_ns = kcred->user_ns; #endif Subject: [Saphira] Linux 7.3: treat 7.3 as mnt_idmap-era (2.4.4 port) Saphira-Port-By: Muse Spark 1.3 Contributor for AKADATA LIMITED (Andrew Smalley, Director) Note: The API moved; the data must not. Re-derived hunk by hunk for 2.4.4 and proven by boot, not by inspection. On 7.3 none of the old HAVE_IOPS_CREATE_* macros are defined (the 4-arg signatures are gone), so zidmap_t fell back to struct user_namespace while VFS now demands struct mnt_idmap: every idmap call site failed with incompatible-pointer-type. With HAVE_IOPS_CREATE_NO_FLAG_ARG the tree is mnt_idmap-based exactly like the IDMAP era, so the era checks cover it: zidmap_t typedef, zfs_get_init_idmap, and the four cred.h fast paths. HAVE_IDMAP_NO_USERNS (struct layout probe) resolves the inner flavor on its own. No upstream commit to credit: robn's branch targets master, whose refactor already removed this fallback chain. --- a/include/os/linux/spl/sys/types.h +++ b/include/os/linux/spl/sys/types.h @@ -58,7 +58,7 @@ typedef int minor_t; struct user_namespace; -#ifdef HAVE_IOPS_CREATE_IDMAP +#if defined(HAVE_IOPS_CREATE_IDMAP) || defined(HAVE_IOPS_CREATE_NO_FLAG_ARG) #include #ifdef HAVE_IDMAP_NO_USERNS #include --- a/module/os/linux/spl/spl-cred.c +++ b/module/os/linux/spl/spl-cred.c @@ -133,7 +133,7 @@ zidmap_t * zfs_get_init_idmap(void) { -#ifdef HAVE_IOPS_CREATE_IDMAP +#if defined(HAVE_IOPS_CREATE_IDMAP) || defined(HAVE_IOPS_CREATE_NO_FLAG_ARG) return ((zidmap_t *)&nop_mnt_idmap); #else return ((zidmap_t *)&init_user_ns); --- a/include/os/linux/spl/sys/cred.h +++ b/include/os/linux/spl/sys/cred.h @@ -78,7 +78,7 @@ struct user_namespace *fs_userns, uid_t uid) { struct user_namespace *owner; -#ifdef HAVE_IOPS_CREATE_IDMAP +#if defined(HAVE_IOPS_CREATE_IDMAP) || defined(HAVE_IOPS_CREATE_NO_FLAG_ARG) if (mnt_userns == zfs_init_idmap) return (uid); #endif @@ -102,7 +102,7 @@ struct user_namespace *fs_userns, gid_t gid) { struct user_namespace *owner; -#ifdef HAVE_IOPS_CREATE_IDMAP +#if defined(HAVE_IOPS_CREATE_IDMAP) || defined(HAVE_IOPS_CREATE_NO_FLAG_ARG) if (mnt_userns == zfs_init_idmap) return (gid); #endif @@ -126,7 +126,7 @@ struct user_namespace *fs_userns, uid_t uid) { struct user_namespace *owner; -#ifdef HAVE_IOPS_CREATE_IDMAP +#if defined(HAVE_IOPS_CREATE_IDMAP) || defined(HAVE_IOPS_CREATE_NO_FLAG_ARG) if (mnt_userns == zfs_init_idmap) return (uid); #endif @@ -151,7 +151,7 @@ struct user_namespace *fs_userns, gid_t gid) { struct user_namespace *owner; -#ifdef HAVE_IOPS_CREATE_IDMAP +#if defined(HAVE_IOPS_CREATE_IDMAP) || defined(HAVE_IOPS_CREATE_NO_FLAG_ARG) if (mnt_userns == zfs_init_idmap) return (gid); #endif