diff --git a/.SRCINFO b/.SRCINFO index df9a236..61f0f0c 100644 --- a/.SRCINFO +++ b/.SRCINFO @@ -1,7 +1,7 @@ pkgbase = zfs-dkms pkgdesc = Kernel modules for the Zettabyte File System. pkgver = 2.2.0 - pkgrel = 1 + pkgrel = 2 url = https://openzfs.org/ arch = x86_64 groups = archzfs-dkms @@ -19,6 +19,8 @@ pkgbase = zfs-dkms conflicts = spl-headers replaces = spl-dkms source = https://github.com/openzfs/zfs/releases/download/zfs-2.2.0/zfs-2.2.0.tar.gz + source = linux-6.6-compat.patch sha256sums = 42035fd059faa25a09cd511b24a57b8ad1285cb69127f2a0043b98562c5ec690 + sha256sums = c2da9ec5d15335fa35b3380d66ff1da1f1cb2e173ac7eb8fb0c9205de8d1fad0 pkgname = zfs-dkms diff --git a/PKGBUILD b/PKGBUILD index 6f7249b..dc21dca 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -9,18 +9,22 @@ pkgname="zfs-dkms" pkgdesc="Kernel modules for the Zettabyte File System." pkgver=2.2.0 -pkgrel=1 +pkgrel=2 makedepends=() arch=("x86_64") url="https://openzfs.org/" -source=("https://github.com/openzfs/zfs/releases/download/zfs-${pkgver}/zfs-${pkgver}.tar.gz") -sha256sums=("42035fd059faa25a09cd511b24a57b8ad1285cb69127f2a0043b98562c5ec690") +source=("https://github.com/openzfs/zfs/releases/download/zfs-${pkgver}/zfs-${pkgver}.tar.gz" "linux-6.6-compat.patch") +sha256sums=("42035fd059faa25a09cd511b24a57b8ad1285cb69127f2a0043b98562c5ec690" "c2da9ec5d15335fa35b3380d66ff1da1f1cb2e173ac7eb8fb0c9205de8d1fad0") license=("CDDL") depends=("zfs-utils=${pkgver}" "lsb-release" "dkms") provides=("zfs" "zfs-headers" "spl" "spl-headers") groups=("archzfs-dkms") conflicts=("zfs" "zfs-headers" "spl" "spl-headers") replaces=("spl-dkms") +prepare() { + cd "${srcdir}/zfs-${pkgver}" + patch -Np1 -i ${srcdir}/linux-6.6-compat.patch +} build() { cd "${srcdir}/zfs-${pkgver}" diff --git a/linux-6.6-compat.patch b/linux-6.6-compat.patch new file mode 100644 index 0000000..ca5e3ec --- /dev/null +++ b/linux-6.6-compat.patch @@ -0,0 +1,610 @@ +From 7e1151769f164cdf4200488b381773e6d7f2112f Mon Sep 17 00:00:00 2001 +From: Coleman Kane +Date: Mon, 11 Sep 2023 23:21:29 -0400 +Subject: [PATCH 1/3] Linux 6.6 compat: use inode_get/set_ctime*(...) + +In Linux commit 13bc24457850583a2e7203ded05b7209ab4bc5ef, direct access +to the i_ctime member of struct inode was removed. The new approach is +to use accessor methods that exclusively handle passing the timestamp +around by value. This change adds new tests for each of these functions +and introduces zpl_* equivalents in include/os/linux/zfs/sys/zpl.h. In +where the inode_get/set_ctime*() functions exist, these zpl_* calls will +be mapped to the new functions. On older kernels, these macros just wrap +direct-access calls. The code that operated on an address of ip->i_ctime +to call ZFS_TIME_DECODE() now will take a local copy using +zpl_inode_get_ctime(), and then pass the address of the local copy when +performing the ZFS_TIME_DECODE() call, in all cases, rather than +directly accessing the member. + +Signed-off-by: Coleman Kane +--- + config/kernel-inode-times.m4 | 43 ++++++++++++++++++++++++++++++ + include/os/linux/zfs/sys/zpl.h | 11 ++++++++ + module/os/linux/zfs/zfs_ctldir.c | 2 +- + module/os/linux/zfs/zfs_vnops_os.c | 12 ++++++--- + module/os/linux/zfs/zfs_znode.c | 18 ++++++++----- + module/os/linux/zfs/zpl_inode.c | 2 +- + module/os/linux/zfs/zpl_xattr.c | 7 ++--- + 7 files changed, 80 insertions(+), 15 deletions(-) + +diff --git a/config/kernel-inode-times.m4 b/config/kernel-inode-times.m4 +index 9c016c790081..412e13b47df5 100644 +--- a/config/kernel-inode-times.m4 ++++ b/config/kernel-inode-times.m4 +@@ -27,6 +27,31 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_TIMES], [ + memset(&ip, 0, sizeof(ip)); + ts = ip.i_mtime; + ]) ++ ++ dnl # ++ dnl # 6.6 API change ++ dnl # i_ctime no longer directly accessible, must use ++ dnl # inode_get_ctime(ip), inode_set_ctime*(ip) to ++ dnl # read/write. ++ dnl # ++ ZFS_LINUX_TEST_SRC([inode_get_ctime], [ ++ #include ++ ],[ ++ struct inode ip; ++ ++ memset(&ip, 0, sizeof(ip)); ++ inode_get_ctime(&ip); ++ ]) ++ ++ ZFS_LINUX_TEST_SRC([inode_set_ctime_to_ts], [ ++ #include ++ ],[ ++ struct inode ip; ++ struct timespec64 ts; ++ ++ memset(&ip, 0, sizeof(ip)); ++ inode_set_ctime_to_ts(&ip, ts); ++ ]) + ]) + + AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [ +@@ -47,4 +72,22 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [ + AC_DEFINE(HAVE_INODE_TIMESPEC64_TIMES, 1, + [inode->i_*time's are timespec64]) + ]) ++ ++ AC_MSG_CHECKING([whether inode_get_ctime() exists]) ++ ZFS_LINUX_TEST_RESULT([inode_get_ctime], [ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_INODE_GET_CTIME, 1, ++ [inode_get_ctime() exists in linux/fs.h]) ++ ],[ ++ AC_MSG_RESULT(no) ++ ]) ++ ++ AC_MSG_CHECKING([whether inode_set_ctime_to_ts() exists]) ++ ZFS_LINUX_TEST_RESULT([inode_set_ctime_to_ts], [ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_INODE_SET_CTIME_TO_TS, 1, ++ [inode_set_ctime_to_ts() exists in linux/fs.h]) ++ ],[ ++ AC_MSG_RESULT(no) ++ ]) + ]) +diff --git a/include/os/linux/zfs/sys/zpl.h b/include/os/linux/zfs/sys/zpl.h +index 0bd20f64897d..f4f1dcf95d4c 100644 +--- a/include/os/linux/zfs/sys/zpl.h ++++ b/include/os/linux/zfs/sys/zpl.h +@@ -263,4 +263,15 @@ extern long zpl_ioctl_fideduperange(struct file *filp, void *arg); + #define zpl_setattr_prepare(ns, dentry, ia) setattr_prepare(dentry, ia) + #endif + ++#ifdef HAVE_INODE_GET_CTIME ++#define zpl_inode_get_ctime(ip) inode_get_ctime(ip) ++#else ++#define zpl_inode_get_ctime(ip) (ip->i_ctime) ++#endif ++#ifdef HAVE_INODE_SET_CTIME_TO_TS ++#define zpl_inode_set_ctime_to_ts(ip, ts) inode_set_ctime_to_ts(ip, ts) ++#else ++#define zpl_inode_set_ctime_to_ts(ip, ts) (ip->i_ctime = ts) ++#endif ++ + #endif /* _SYS_ZPL_H */ +diff --git a/module/os/linux/zfs/zfs_ctldir.c b/module/os/linux/zfs/zfs_ctldir.c +index 02cb379ea840..94e25fa0ae8f 100644 +--- a/module/os/linux/zfs/zfs_ctldir.c ++++ b/module/os/linux/zfs/zfs_ctldir.c +@@ -522,7 +522,7 @@ zfsctl_inode_alloc(zfsvfs_t *zfsvfs, uint64_t id, + ip->i_blkbits = SPA_MINBLOCKSHIFT; + ip->i_atime = now; + ip->i_mtime = now; +- ip->i_ctime = now; ++ zpl_inode_set_ctime_to_ts(ip, now); + ip->i_fop = fops; + ip->i_op = ops; + #if defined(IOP_XATTR) +diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c +index b7d44f344daf..e2c23a81fd6c 100644 +--- a/module/os/linux/zfs/zfs_vnops_os.c ++++ b/module/os/linux/zfs/zfs_vnops_os.c +@@ -2439,8 +2439,8 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr, zidmap_t *mnt_ns) + + if (mask & (ATTR_CTIME | ATTR_SIZE)) { + ZFS_TIME_ENCODE(&vap->va_ctime, ctime); +- ZTOI(zp)->i_ctime = zpl_inode_timestamp_truncate(vap->va_ctime, +- ZTOI(zp)); ++ zpl_inode_set_ctime_to_ts(ZTOI(zp), ++ zpl_inode_timestamp_truncate(vap->va_ctime, ZTOI(zp))); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, + ctime, sizeof (ctime)); + } +@@ -3645,6 +3645,7 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc, + caddr_t va; + int err = 0; + uint64_t mtime[2], ctime[2]; ++ inode_timespec_t tmp_ctime; + sa_bulk_attr_t bulk[3]; + int cnt = 0; + struct address_space *mapping; +@@ -3809,7 +3810,8 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc, + + /* Preserve the mtime and ctime provided by the inode */ + ZFS_TIME_ENCODE(&ip->i_mtime, mtime); +- ZFS_TIME_ENCODE(&ip->i_ctime, ctime); ++ tmp_ctime = zpl_inode_get_ctime(ip); ++ ZFS_TIME_ENCODE(&tmp_ctime, ctime); + zp->z_atime_dirty = B_FALSE; + zp->z_seq++; + +@@ -3859,6 +3861,7 @@ zfs_dirty_inode(struct inode *ip, int flags) + zfsvfs_t *zfsvfs = ITOZSB(ip); + dmu_tx_t *tx; + uint64_t mode, atime[2], mtime[2], ctime[2]; ++ inode_timespec_t tmp_ctime; + sa_bulk_attr_t bulk[4]; + int error = 0; + int cnt = 0; +@@ -3905,7 +3908,8 @@ zfs_dirty_inode(struct inode *ip, int flags) + /* Preserve the mode, mtime and ctime provided by the inode */ + ZFS_TIME_ENCODE(&ip->i_atime, atime); + ZFS_TIME_ENCODE(&ip->i_mtime, mtime); +- ZFS_TIME_ENCODE(&ip->i_ctime, ctime); ++ tmp_ctime = zpl_inode_get_ctime(ip); ++ ZFS_TIME_ENCODE(&tmp_ctime, ctime); + mode = ip->i_mode; + + zp->z_mode = mode; +diff --git a/module/os/linux/zfs/zfs_znode.c b/module/os/linux/zfs/zfs_znode.c +index 52c8e51df659..f71026da83cb 100644 +--- a/module/os/linux/zfs/zfs_znode.c ++++ b/module/os/linux/zfs/zfs_znode.c +@@ -542,6 +542,7 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, + uint64_t links; + uint64_t z_uid, z_gid; + uint64_t atime[2], mtime[2], ctime[2], btime[2]; ++ inode_timespec_t tmp_ctime; + uint64_t projid = ZFS_DEFAULT_PROJID; + sa_bulk_attr_t bulk[12]; + int count = 0; +@@ -615,7 +616,8 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, + + ZFS_TIME_DECODE(&ip->i_atime, atime); + ZFS_TIME_DECODE(&ip->i_mtime, mtime); +- ZFS_TIME_DECODE(&ip->i_ctime, ctime); ++ ZFS_TIME_DECODE(&tmp_ctime, ctime); ++ zpl_inode_set_ctime_to_ts(ip, tmp_ctime); + ZFS_TIME_DECODE(&zp->z_btime, btime); + + ip->i_ino = zp->z_id; +@@ -1195,6 +1197,7 @@ zfs_rezget(znode_t *zp) + uint64_t gen; + uint64_t z_uid, z_gid; + uint64_t atime[2], mtime[2], ctime[2], btime[2]; ++ inode_timespec_t tmp_ctime; + uint64_t projid = ZFS_DEFAULT_PROJID; + znode_hold_t *zh; + +@@ -1289,7 +1292,8 @@ zfs_rezget(znode_t *zp) + + ZFS_TIME_DECODE(&ZTOI(zp)->i_atime, atime); + ZFS_TIME_DECODE(&ZTOI(zp)->i_mtime, mtime); +- ZFS_TIME_DECODE(&ZTOI(zp)->i_ctime, ctime); ++ ZFS_TIME_DECODE(&tmp_ctime, ctime); ++ zpl_inode_set_ctime_to_ts(ZTOI(zp), tmp_ctime); + ZFS_TIME_DECODE(&zp->z_btime, btime); + + if ((uint32_t)gen != ZTOI(zp)->i_generation) { +@@ -1397,7 +1401,7 @@ zfs_zinactive(znode_t *zp) + boolean_t + zfs_relatime_need_update(const struct inode *ip) + { +- inode_timespec_t now; ++ inode_timespec_t now, tmp_ctime; + + gethrestime(&now); + /* +@@ -1408,7 +1412,8 @@ zfs_relatime_need_update(const struct inode *ip) + if (zfs_compare_timespec(&ip->i_mtime, &ip->i_atime) >= 0) + return (B_TRUE); + +- if (zfs_compare_timespec(&ip->i_ctime, &ip->i_atime) >= 0) ++ tmp_ctime = zpl_inode_get_ctime(ip); ++ if (zfs_compare_timespec(&tmp_ctime, &ip->i_atime) >= 0) + return (B_TRUE); + + if ((hrtime_t)now.tv_sec - (hrtime_t)ip->i_atime.tv_sec >= 24*60*60) +@@ -1434,7 +1439,7 @@ void + zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2], + uint64_t ctime[2]) + { +- inode_timespec_t now; ++ inode_timespec_t now, tmp_ctime; + + gethrestime(&now); + +@@ -1451,7 +1456,8 @@ zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2], + + if (flag & ATTR_CTIME) { + ZFS_TIME_ENCODE(&now, ctime); +- ZFS_TIME_DECODE(&(ZTOI(zp)->i_ctime), ctime); ++ ZFS_TIME_DECODE(&tmp_ctime, ctime); ++ zpl_inode_set_ctime_to_ts(ZTOI(zp), tmp_ctime); + if (ZTOZSB(zp)->z_use_fuids) + zp->z_pflags |= ZFS_ARCHIVE; + } +diff --git a/module/os/linux/zfs/zpl_inode.c b/module/os/linux/zfs/zpl_inode.c +index 5f5ad186a61c..ef50f8687779 100644 +--- a/module/os/linux/zfs/zpl_inode.c ++++ b/module/os/linux/zfs/zpl_inode.c +@@ -774,7 +774,7 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) + return (-EMLINK); + + crhold(cr); +- ip->i_ctime = current_time(ip); ++ zpl_inode_set_ctime_to_ts(ip, current_time(ip)); + /* Must have an existing ref, so igrab() cannot return NULL */ + VERIFY3P(igrab(ip), !=, NULL); + +diff --git a/module/os/linux/zfs/zpl_xattr.c b/module/os/linux/zfs/zpl_xattr.c +index 96d85991811e..4e4f5210f85d 100644 +--- a/module/os/linux/zfs/zpl_xattr.c ++++ b/module/os/linux/zfs/zpl_xattr.c +@@ -513,7 +513,7 @@ zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value, + error = -zfs_write_simple(xzp, value, size, pos, NULL); + out: + if (error == 0) { +- ip->i_ctime = current_time(ip); ++ zpl_inode_set_ctime_to_ts(ip, current_time(ip)); + zfs_mark_inode_dirty(ip); + } + +@@ -1011,7 +1011,8 @@ zpl_set_acl_impl(struct inode *ip, struct posix_acl *acl, int type) + */ + if (ip->i_mode != mode) { + ip->i_mode = ITOZ(ip)->z_mode = mode; +- ip->i_ctime = current_time(ip); ++ zpl_inode_set_ctime_to_ts(ip, ++ current_time(ip)); + zfs_mark_inode_dirty(ip); + } + +@@ -1170,7 +1171,7 @@ zpl_init_acl(struct inode *ip, struct inode *dir) + return (PTR_ERR(acl)); + if (!acl) { + ITOZ(ip)->z_mode = (ip->i_mode &= ~current_umask()); +- ip->i_ctime = current_time(ip); ++ zpl_inode_set_ctime_to_ts(ip, current_time(ip)); + zfs_mark_inode_dirty(ip); + return (0); + } + +From c85006663f7c7a81c030d70a566c02aaa0637bcd Mon Sep 17 00:00:00 2001 +From: Coleman Kane +Date: Fri, 15 Sep 2023 00:36:39 -0400 +Subject: [PATCH 2/3] linux 6.6: generic_fillattr has a new u32 request_mask + added at arg2 + +In commit 0d72b92883c651a11059d93335f33d65c6eb653b, a new u32 argument +for the request_mask was added to generic_fillattr. This is the same +request_mask for statx that's present in the most recent API implemented +by zpl_getattr_impl. This commit conditionally adds it to the +zpl_generic_fillattr(...) macro, as well as the zfs_getattr_fast(...) +implementation, when configure determines it's present in the kernel's +generic_fillattr(...). + +Signed-off-by: Coleman Kane +--- + config/kernel-generic_fillattr.m4 | 39 +++++++++++++++++----- + include/os/linux/kernel/linux/vfs_compat.h | 6 ++++ + include/os/linux/zfs/sys/zfs_vnops_os.h | 5 +++ + module/os/linux/zfs/zfs_vnops_os.c | 9 +++++ + module/os/linux/zfs/zpl_ctldir.c | 11 +++++- + module/os/linux/zfs/zpl_inode.c | 4 ++- + 6 files changed, 63 insertions(+), 11 deletions(-) + +diff --git a/config/kernel-generic_fillattr.m4 b/config/kernel-generic_fillattr.m4 +index 02dee4d4c000..f5323f0dcb9f 100644 +--- a/config/kernel-generic_fillattr.m4 ++++ b/config/kernel-generic_fillattr.m4 +@@ -7,6 +7,10 @@ dnl # + dnl # 6.3 API + dnl # generic_fillattr() now takes struct mnt_idmap* as the first argument + dnl # ++dnl # 6.6 API ++dnl # generic_fillattr() now takes u32 as second argument, representing a ++dnl # request_mask for statx ++dnl # + AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR], [ + ZFS_LINUX_TEST_SRC([generic_fillattr_userns], [ + #include +@@ -25,22 +29,39 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR], [ + struct kstat *k = NULL; + generic_fillattr(idmap, in, k); + ]) ++ ++ ZFS_LINUX_TEST_SRC([generic_fillattr_mnt_idmap_reqmask], [ ++ #include ++ ],[ ++ struct mnt_idmap *idmap = NULL; ++ struct inode *in = NULL; ++ struct kstat *k = NULL; ++ generic_fillattr(idmap, 0, in, k); ++ ]) + ]) + + AC_DEFUN([ZFS_AC_KERNEL_GENERIC_FILLATTR], [ +- AC_MSG_CHECKING([whether generic_fillattr requires struct mnt_idmap*]) +- ZFS_LINUX_TEST_RESULT([generic_fillattr_mnt_idmap], [ ++ AC_MSG_CHECKING( ++ [whether generic_fillattr requires struct mnt_idmap* and request_mask]) ++ ZFS_LINUX_TEST_RESULT([generic_fillattr_mnt_idmap_reqmask], [ + AC_MSG_RESULT([yes]) +- AC_DEFINE(HAVE_GENERIC_FILLATTR_IDMAP, 1, +- [generic_fillattr requires struct mnt_idmap*]) ++ AC_DEFINE(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK, 1, ++ [generic_fillattr requires struct mnt_idmap* and u32 request_mask]) + ],[ +- AC_MSG_CHECKING([whether generic_fillattr requires struct user_namespace*]) +- ZFS_LINUX_TEST_RESULT([generic_fillattr_userns], [ ++ AC_MSG_CHECKING([whether generic_fillattr requires struct mnt_idmap*]) ++ ZFS_LINUX_TEST_RESULT([generic_fillattr_mnt_idmap], [ + AC_MSG_RESULT([yes]) +- AC_DEFINE(HAVE_GENERIC_FILLATTR_USERNS, 1, +- [generic_fillattr requires struct user_namespace*]) ++ AC_DEFINE(HAVE_GENERIC_FILLATTR_IDMAP, 1, ++ [generic_fillattr requires struct mnt_idmap*]) + ],[ +- AC_MSG_RESULT([no]) ++ AC_MSG_CHECKING([whether generic_fillattr requires struct user_namespace*]) ++ ZFS_LINUX_TEST_RESULT([generic_fillattr_userns], [ ++ AC_MSG_RESULT([yes]) ++ AC_DEFINE(HAVE_GENERIC_FILLATTR_USERNS, 1, ++ [generic_fillattr requires struct user_namespace*]) ++ ],[ ++ AC_MSG_RESULT([no]) ++ ]) + ]) + ]) + ]) +diff --git a/include/os/linux/kernel/linux/vfs_compat.h b/include/os/linux/kernel/linux/vfs_compat.h +index e156ed41c28c..aea8bd5ed22c 100644 +--- a/include/os/linux/kernel/linux/vfs_compat.h ++++ b/include/os/linux/kernel/linux/vfs_compat.h +@@ -461,10 +461,16 @@ zpl_is_32bit_api(void) + * 6.3 API change + * generic_fillattr() first arg is changed to struct mnt_idmap * + * ++ * 6.6 API change ++ * generic_fillattr() gets new second arg request_mask, a u32 type ++ * + */ + #ifdef HAVE_GENERIC_FILLATTR_IDMAP + #define zpl_generic_fillattr(idmap, ip, sp) \ + generic_fillattr(idmap, ip, sp) ++#elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK) ++#define zpl_generic_fillattr(idmap, rqm, ip, sp) \ ++ generic_fillattr(idmap, rqm, ip, sp) + #elif defined(HAVE_GENERIC_FILLATTR_USERNS) + #define zpl_generic_fillattr(user_ns, ip, sp) \ + generic_fillattr(user_ns, ip, sp) +diff --git a/include/os/linux/zfs/sys/zfs_vnops_os.h b/include/os/linux/zfs/sys/zfs_vnops_os.h +index 7a1db7deeec8..830c76e5743a 100644 +--- a/include/os/linux/zfs/sys/zfs_vnops_os.h ++++ b/include/os/linux/zfs/sys/zfs_vnops_os.h +@@ -56,7 +56,12 @@ extern int zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, + extern int zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd, + cred_t *cr, int flags); + extern int zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr); ++#ifdef HAVE_GENERIC_FILLATTR_IDMAP_REQMASK ++extern int zfs_getattr_fast(zidmap_t *, u32 request_mask, struct inode *ip, ++ struct kstat *sp); ++#else + extern int zfs_getattr_fast(zidmap_t *, struct inode *ip, struct kstat *sp); ++#endif + extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr, + zidmap_t *mnt_ns); + extern int zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, +diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c +index e2c23a81fd6c..1770e2372571 100644 +--- a/module/os/linux/zfs/zfs_vnops_os.c ++++ b/module/os/linux/zfs/zfs_vnops_os.c +@@ -1649,7 +1649,12 @@ zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr) + * RETURN: 0 (always succeeds) + */ + int ++#ifdef HAVE_GENERIC_FILLATTR_IDMAP_REQMASK ++zfs_getattr_fast(zidmap_t *user_ns, u32 request_mask, struct inode *ip, ++ struct kstat *sp) ++#else + zfs_getattr_fast(zidmap_t *user_ns, struct inode *ip, struct kstat *sp) ++#endif + { + znode_t *zp = ITOZ(ip); + zfsvfs_t *zfsvfs = ITOZSB(ip); +@@ -1662,7 +1667,11 @@ zfs_getattr_fast(zidmap_t *user_ns, struct inode *ip, struct kstat *sp) + + mutex_enter(&zp->z_lock); + ++#ifdef HAVE_GENERIC_FILLATTR_IDMAP_REQMASK ++ zpl_generic_fillattr(user_ns, request_mask, ip, sp); ++#else + zpl_generic_fillattr(user_ns, ip, sp); ++#endif + /* + * +1 link count for root inode with visible '.zfs' directory. + */ +diff --git a/module/os/linux/zfs/zpl_ctldir.c b/module/os/linux/zfs/zpl_ctldir.c +index 7786444fea35..8ee7fcecc7b7 100644 +--- a/module/os/linux/zfs/zpl_ctldir.c ++++ b/module/os/linux/zfs/zpl_ctldir.c +@@ -124,6 +124,8 @@ zpl_root_getattr_impl(const struct path *path, struct kstat *stat, + generic_fillattr(user_ns, ip, stat); + #elif defined(HAVE_GENERIC_FILLATTR_IDMAP) + generic_fillattr(user_ns, ip, stat); ++#elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK) ++ generic_fillattr(user_ns, request_mask, ip, stat); + #else + (void) user_ns; + #endif +@@ -435,6 +437,8 @@ zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat, + generic_fillattr(user_ns, ip, stat); + #elif defined(HAVE_GENERIC_FILLATTR_IDMAP) + generic_fillattr(user_ns, ip, stat); ++#elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK) ++ generic_fillattr(user_ns, request_mask, ip, stat); + #else + (void) user_ns; + #endif +@@ -609,6 +613,8 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat, + generic_fillattr(user_ns, path->dentry->d_inode, stat); + #elif defined(HAVE_GENERIC_FILLATTR_IDMAP) + generic_fillattr(user_ns, path->dentry->d_inode, stat); ++#elif defined(HAVE_GENERIC_FILLATTR_IDMAP_REQMASK) ++ generic_fillattr(user_ns, request_mask, ip, stat); + #else + (void) user_ns; + #endif +@@ -623,7 +629,10 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat, + + error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp); + if (error == 0) { +-#if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR)) ++#ifdef HAVE_GENERIC_FILLATTR_IDMAP_REQMASK ++ error = -zfs_getattr_fast(user_ns, request_mask, ZTOI(dzp), ++ stat); ++#elif (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR)) + error = -zfs_getattr_fast(user_ns, ZTOI(dzp), stat); + #else + error = -zfs_getattr_fast(kcred->user_ns, ZTOI(dzp), stat); +diff --git a/module/os/linux/zfs/zpl_inode.c b/module/os/linux/zfs/zpl_inode.c +index ef50f8687779..96f65b9e94e2 100644 +--- a/module/os/linux/zfs/zpl_inode.c ++++ b/module/os/linux/zfs/zpl_inode.c +@@ -435,7 +435,9 @@ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask, + * XXX query_flags currently ignored. + */ + +-#if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR)) ++#ifdef HAVE_GENERIC_FILLATTR_IDMAP_REQMASK ++ error = -zfs_getattr_fast(user_ns, request_mask, ip, stat); ++#elif (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR)) + error = -zfs_getattr_fast(user_ns, ip, stat); + #else + error = -zfs_getattr_fast(kcred->user_ns, ip, stat); + +From e4391234dccd189fd01665ad035b8f522edf4ce9 Mon Sep 17 00:00:00 2001 +From: Coleman Kane +Date: Fri, 15 Sep 2023 01:07:03 -0400 +Subject: [PATCH 3/3] linux-6.6: fsync_bdev() has been removed in favor of + sync_blockdev() + +In Linux commit 560e20e4bf6484a0c12f9f3c7a1aa55056948e1e, the +fsync_bdev() function was removed in favor of sync_blockdev() to do +(roughly) the same thing, given the same input. This change +conditionally attempts to call sync_blockdev() if fsync_bdev() isn't +discovered during configure. + +Signed-off-by: Coleman Kane +--- + config/kernel-fsync-bdev.m4 | 36 +++++++++++++++++++++++++++++++++++ + config/kernel.m4 | 2 ++ + module/os/linux/zfs/zvol_os.c | 6 ++++++ + 3 files changed, 44 insertions(+) + create mode 100644 config/kernel-fsync-bdev.m4 + +diff --git a/config/kernel-fsync-bdev.m4 b/config/kernel-fsync-bdev.m4 +new file mode 100644 +index 000000000000..c47e236f705f +--- /dev/null ++++ b/config/kernel-fsync-bdev.m4 +@@ -0,0 +1,36 @@ ++dnl # ++dnl # 6.6 API change, ++dnl # fsync_bdev was removed in favor of sync_blockdev ++dnl # ++AC_DEFUN([ZFS_AC_KERNEL_SRC_SYNC_BDEV], [ ++ ZFS_LINUX_TEST_SRC([fsync_bdev], [ ++ #include ++ ],[ ++ fsync_bdev(NULL); ++ ]) ++ ++ ZFS_LINUX_TEST_SRC([sync_blockdev], [ ++ #include ++ ],[ ++ sync_blockdev(NULL); ++ ]) ++]) ++ ++AC_DEFUN([ZFS_AC_KERNEL_SYNC_BDEV], [ ++ AC_MSG_CHECKING([whether fsync_bdev() exists]) ++ ZFS_LINUX_TEST_RESULT([fsync_bdev], [ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_FSYNC_BDEV, 1, ++ [fsync_bdev() is declared in include/blkdev.h]) ++ ],[ ++ AC_MSG_CHECKING([whether sync_blockdev() exists]) ++ ZFS_LINUX_TEST_RESULT([sync_blockdev], [ ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_SYNC_BLOCKDEV, 1, ++ [sync_blockdev() is declared in include/blkdev.h]) ++ ],[ ++ ZFS_LINUX_TEST_ERROR( ++ [neither fsync_bdev() nor sync_blockdev() exist]) ++ ]) ++ ]) ++]) +diff --git a/config/kernel.m4 b/config/kernel.m4 +index df194ec72207..056517a841f2 100644 +--- a/config/kernel.m4 ++++ b/config/kernel.m4 +@@ -162,6 +162,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ + ZFS_AC_KERNEL_SRC_RECLAIMED + ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE + ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ ++ ZFS_AC_KERNEL_SRC_SYNC_BDEV + case "$host_cpu" in + powerpc*) + ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE +@@ -303,6 +304,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ + ZFS_AC_KERNEL_RECLAIMED + ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE + ZFS_AC_KERNEL_COPY_SPLICE_READ ++ ZFS_AC_KERNEL_SYNC_BDEV + case "$host_cpu" in + powerpc*) + ZFS_AC_KERNEL_CPU_HAS_FEATURE +diff --git a/module/os/linux/zfs/zvol_os.c b/module/os/linux/zfs/zvol_os.c +index 7a95b54bdf0d..f94ce69fb9e2 100644 +--- a/module/os/linux/zfs/zvol_os.c ++++ b/module/os/linux/zfs/zvol_os.c +@@ -873,7 +873,13 @@ zvol_ioctl(struct block_device *bdev, fmode_t mode, + + switch (cmd) { + case BLKFLSBUF: ++#ifdef HAVE_FSYNC_BDEV + fsync_bdev(bdev); ++#elif defined(HAVE_SYNC_BLOCKDEV) ++ sync_blockdev(bdev); ++#else ++#error "Neither fsync_bdev() nor sync_blockdev() found" ++#endif + invalidate_bdev(bdev); + rw_enter(&zv->zv_suspend_lock, RW_READER); +