]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Linux 6.6 compat: use inode_get/set_ctime*(...)
authorColeman Kane <ckane@colemankane.org>
Tue, 12 Sep 2023 03:21:29 +0000 (23:21 -0400)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 22 Sep 2023 01:38:31 +0000 (18:38 -0700)
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.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Coleman Kane <ckane@colemankane.org>
Closes #15263
Closes #15257

config/kernel-inode-times.m4
include/os/linux/zfs/sys/zpl.h
module/os/linux/zfs/zfs_ctldir.c
module/os/linux/zfs/zfs_vnops_os.c
module/os/linux/zfs/zfs_znode.c
module/os/linux/zfs/zpl_inode.c
module/os/linux/zfs/zpl_xattr.c

index 9c016c790081567c1895e8ce93930ea8076c9688..412e13b47df588e79f9f0afcd7d3d57fe4ce1c08 100644 (file)
@@ -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 <linux/fs.h>
+       ],[
+               struct inode ip;
+
+               memset(&ip, 0, sizeof(ip));
+               inode_get_ctime(&ip);
+       ])
+
+       ZFS_LINUX_TEST_SRC([inode_set_ctime_to_ts], [
+               #include <linux/fs.h>
+       ],[
+               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)
+       ])
 ])
index 0bd20f64897da90889b3a1b2620b3b67418a5536..f4f1dcf95d4ce3a6b22d39b8bf7ab49f8b17a37a 100644 (file)
@@ -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 */
index 02cb379ea8400190e812dc64424243d6a73ecaf0..94e25fa0ae8fd435b3004dc0caf38e74972cce90 100644 (file)
@@ -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)
index b7d44f344daf3ad1417d5a3b26394da6391aa6df..e2c23a81fd6ceeb7445447ecb86fcd4c6c61d2f2 100644 (file)
@@ -2439,8 +2439,8 @@ top:
 
        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;
index 52c8e51df659083ff75f8f9cf3177957fb7177f9..f71026da83cbb5c07588961ea7892d855ada77f1 100644 (file)
@@ -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;
        }
index 5f5ad186a61c4154551c94bcdc3f5b25f70ada1c..ef50f86877799f82abc1103ea4dfea016f68f5f2 100644 (file)
@@ -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);
 
index 96d85991811e449d8c72d40905273d991602de44..4e4f5210f85d96de01de56f82756878e78b09cf6 100644 (file)
@@ -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);
                }