Skip to content

Commit b37f293

Browse files
ckanebehlendorf
authored andcommitted
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. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Coleman Kane <[email protected]> Closes openzfs#15263 Closes openzfs#15257
1 parent 2dc89b9 commit b37f293

File tree

7 files changed

+80
-15
lines changed

7 files changed

+80
-15
lines changed

config/kernel-inode-times.m4

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,31 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_TIMES], [
2727
memset(&ip, 0, sizeof(ip));
2828
ts = ip.i_mtime;
2929
])
30+
31+
dnl #
32+
dnl # 6.6 API change
33+
dnl # i_ctime no longer directly accessible, must use
34+
dnl # inode_get_ctime(ip), inode_set_ctime*(ip) to
35+
dnl # read/write.
36+
dnl #
37+
ZFS_LINUX_TEST_SRC([inode_get_ctime], [
38+
#include <linux/fs.h>
39+
],[
40+
struct inode ip;
41+
42+
memset(&ip, 0, sizeof(ip));
43+
inode_get_ctime(&ip);
44+
])
45+
46+
ZFS_LINUX_TEST_SRC([inode_set_ctime_to_ts], [
47+
#include <linux/fs.h>
48+
],[
49+
struct inode ip;
50+
struct timespec64 ts;
51+
52+
memset(&ip, 0, sizeof(ip));
53+
inode_set_ctime_to_ts(&ip, ts);
54+
])
3055
])
3156

3257
AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
@@ -47,4 +72,22 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
4772
AC_DEFINE(HAVE_INODE_TIMESPEC64_TIMES, 1,
4873
[inode->i_*time's are timespec64])
4974
])
75+
76+
AC_MSG_CHECKING([whether inode_get_ctime() exists])
77+
ZFS_LINUX_TEST_RESULT([inode_get_ctime], [
78+
AC_MSG_RESULT(yes)
79+
AC_DEFINE(HAVE_INODE_GET_CTIME, 1,
80+
[inode_get_ctime() exists in linux/fs.h])
81+
],[
82+
AC_MSG_RESULT(no)
83+
])
84+
85+
AC_MSG_CHECKING([whether inode_set_ctime_to_ts() exists])
86+
ZFS_LINUX_TEST_RESULT([inode_set_ctime_to_ts], [
87+
AC_MSG_RESULT(yes)
88+
AC_DEFINE(HAVE_INODE_SET_CTIME_TO_TS, 1,
89+
[inode_set_ctime_to_ts() exists in linux/fs.h])
90+
],[
91+
AC_MSG_RESULT(no)
92+
])
5093
])

include/os/linux/zfs/sys/zpl.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,4 +263,15 @@ extern long zpl_ioctl_fideduperange(struct file *filp, void *arg);
263263
#define zpl_setattr_prepare(ns, dentry, ia) setattr_prepare(dentry, ia)
264264
#endif
265265

266+
#ifdef HAVE_INODE_GET_CTIME
267+
#define zpl_inode_get_ctime(ip) inode_get_ctime(ip)
268+
#else
269+
#define zpl_inode_get_ctime(ip) (ip->i_ctime)
270+
#endif
271+
#ifdef HAVE_INODE_SET_CTIME_TO_TS
272+
#define zpl_inode_set_ctime_to_ts(ip, ts) inode_set_ctime_to_ts(ip, ts)
273+
#else
274+
#define zpl_inode_set_ctime_to_ts(ip, ts) (ip->i_ctime = ts)
275+
#endif
276+
266277
#endif /* _SYS_ZPL_H */

module/os/linux/zfs/zfs_ctldir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ zfsctl_inode_alloc(zfsvfs_t *zfsvfs, uint64_t id,
522522
ip->i_blkbits = SPA_MINBLOCKSHIFT;
523523
ip->i_atime = now;
524524
ip->i_mtime = now;
525-
ip->i_ctime = now;
525+
zpl_inode_set_ctime_to_ts(ip, now);
526526
ip->i_fop = fops;
527527
ip->i_op = ops;
528528
#if defined(IOP_XATTR)

module/os/linux/zfs/zfs_vnops_os.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2439,8 +2439,8 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr, zidmap_t *mnt_ns)
24392439

24402440
if (mask & (ATTR_CTIME | ATTR_SIZE)) {
24412441
ZFS_TIME_ENCODE(&vap->va_ctime, ctime);
2442-
ZTOI(zp)->i_ctime = zpl_inode_timestamp_truncate(vap->va_ctime,
2443-
ZTOI(zp));
2442+
zpl_inode_set_ctime_to_ts(ZTOI(zp),
2443+
zpl_inode_timestamp_truncate(vap->va_ctime, ZTOI(zp)));
24442444
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL,
24452445
ctime, sizeof (ctime));
24462446
}
@@ -3645,6 +3645,7 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
36453645
caddr_t va;
36463646
int err = 0;
36473647
uint64_t mtime[2], ctime[2];
3648+
inode_timespec_t tmp_ctime;
36483649
sa_bulk_attr_t bulk[3];
36493650
int cnt = 0;
36503651
struct address_space *mapping;
@@ -3809,7 +3810,8 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
38093810

38103811
/* Preserve the mtime and ctime provided by the inode */
38113812
ZFS_TIME_ENCODE(&ip->i_mtime, mtime);
3812-
ZFS_TIME_ENCODE(&ip->i_ctime, ctime);
3813+
tmp_ctime = zpl_inode_get_ctime(ip);
3814+
ZFS_TIME_ENCODE(&tmp_ctime, ctime);
38133815
zp->z_atime_dirty = B_FALSE;
38143816
zp->z_seq++;
38153817

@@ -3859,6 +3861,7 @@ zfs_dirty_inode(struct inode *ip, int flags)
38593861
zfsvfs_t *zfsvfs = ITOZSB(ip);
38603862
dmu_tx_t *tx;
38613863
uint64_t mode, atime[2], mtime[2], ctime[2];
3864+
inode_timespec_t tmp_ctime;
38623865
sa_bulk_attr_t bulk[4];
38633866
int error = 0;
38643867
int cnt = 0;
@@ -3905,7 +3908,8 @@ zfs_dirty_inode(struct inode *ip, int flags)
39053908
/* Preserve the mode, mtime and ctime provided by the inode */
39063909
ZFS_TIME_ENCODE(&ip->i_atime, atime);
39073910
ZFS_TIME_ENCODE(&ip->i_mtime, mtime);
3908-
ZFS_TIME_ENCODE(&ip->i_ctime, ctime);
3911+
tmp_ctime = zpl_inode_get_ctime(ip);
3912+
ZFS_TIME_ENCODE(&tmp_ctime, ctime);
39093913
mode = ip->i_mode;
39103914

39113915
zp->z_mode = mode;

module/os/linux/zfs/zfs_znode.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,7 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
542542
uint64_t links;
543543
uint64_t z_uid, z_gid;
544544
uint64_t atime[2], mtime[2], ctime[2], btime[2];
545+
inode_timespec_t tmp_ctime;
545546
uint64_t projid = ZFS_DEFAULT_PROJID;
546547
sa_bulk_attr_t bulk[12];
547548
int count = 0;
@@ -615,7 +616,8 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
615616

616617
ZFS_TIME_DECODE(&ip->i_atime, atime);
617618
ZFS_TIME_DECODE(&ip->i_mtime, mtime);
618-
ZFS_TIME_DECODE(&ip->i_ctime, ctime);
619+
ZFS_TIME_DECODE(&tmp_ctime, ctime);
620+
zpl_inode_set_ctime_to_ts(ip, tmp_ctime);
619621
ZFS_TIME_DECODE(&zp->z_btime, btime);
620622

621623
ip->i_ino = zp->z_id;
@@ -1195,6 +1197,7 @@ zfs_rezget(znode_t *zp)
11951197
uint64_t gen;
11961198
uint64_t z_uid, z_gid;
11971199
uint64_t atime[2], mtime[2], ctime[2], btime[2];
1200+
inode_timespec_t tmp_ctime;
11981201
uint64_t projid = ZFS_DEFAULT_PROJID;
11991202
znode_hold_t *zh;
12001203

@@ -1289,7 +1292,8 @@ zfs_rezget(znode_t *zp)
12891292

12901293
ZFS_TIME_DECODE(&ZTOI(zp)->i_atime, atime);
12911294
ZFS_TIME_DECODE(&ZTOI(zp)->i_mtime, mtime);
1292-
ZFS_TIME_DECODE(&ZTOI(zp)->i_ctime, ctime);
1295+
ZFS_TIME_DECODE(&tmp_ctime, ctime);
1296+
zpl_inode_set_ctime_to_ts(ZTOI(zp), tmp_ctime);
12931297
ZFS_TIME_DECODE(&zp->z_btime, btime);
12941298

12951299
if ((uint32_t)gen != ZTOI(zp)->i_generation) {
@@ -1397,7 +1401,7 @@ zfs_zinactive(znode_t *zp)
13971401
boolean_t
13981402
zfs_relatime_need_update(const struct inode *ip)
13991403
{
1400-
inode_timespec_t now;
1404+
inode_timespec_t now, tmp_ctime;
14011405

14021406
gethrestime(&now);
14031407
/*
@@ -1408,7 +1412,8 @@ zfs_relatime_need_update(const struct inode *ip)
14081412
if (zfs_compare_timespec(&ip->i_mtime, &ip->i_atime) >= 0)
14091413
return (B_TRUE);
14101414

1411-
if (zfs_compare_timespec(&ip->i_ctime, &ip->i_atime) >= 0)
1415+
tmp_ctime = zpl_inode_get_ctime(ip);
1416+
if (zfs_compare_timespec(&tmp_ctime, &ip->i_atime) >= 0)
14121417
return (B_TRUE);
14131418

14141419
if ((hrtime_t)now.tv_sec - (hrtime_t)ip->i_atime.tv_sec >= 24*60*60)
@@ -1434,7 +1439,7 @@ void
14341439
zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2],
14351440
uint64_t ctime[2])
14361441
{
1437-
inode_timespec_t now;
1442+
inode_timespec_t now, tmp_ctime;
14381443

14391444
gethrestime(&now);
14401445

@@ -1451,7 +1456,8 @@ zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2],
14511456

14521457
if (flag & ATTR_CTIME) {
14531458
ZFS_TIME_ENCODE(&now, ctime);
1454-
ZFS_TIME_DECODE(&(ZTOI(zp)->i_ctime), ctime);
1459+
ZFS_TIME_DECODE(&tmp_ctime, ctime);
1460+
zpl_inode_set_ctime_to_ts(ZTOI(zp), tmp_ctime);
14551461
if (ZTOZSB(zp)->z_use_fuids)
14561462
zp->z_pflags |= ZFS_ARCHIVE;
14571463
}

module/os/linux/zfs/zpl_inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,7 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
774774
return (-EMLINK);
775775

776776
crhold(cr);
777-
ip->i_ctime = current_time(ip);
777+
zpl_inode_set_ctime_to_ts(ip, current_time(ip));
778778
/* Must have an existing ref, so igrab() cannot return NULL */
779779
VERIFY3P(igrab(ip), !=, NULL);
780780

module/os/linux/zfs/zpl_xattr.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
513513
error = -zfs_write_simple(xzp, value, size, pos, NULL);
514514
out:
515515
if (error == 0) {
516-
ip->i_ctime = current_time(ip);
516+
zpl_inode_set_ctime_to_ts(ip, current_time(ip));
517517
zfs_mark_inode_dirty(ip);
518518
}
519519

@@ -1011,7 +1011,8 @@ zpl_set_acl_impl(struct inode *ip, struct posix_acl *acl, int type)
10111011
*/
10121012
if (ip->i_mode != mode) {
10131013
ip->i_mode = ITOZ(ip)->z_mode = mode;
1014-
ip->i_ctime = current_time(ip);
1014+
zpl_inode_set_ctime_to_ts(ip,
1015+
current_time(ip));
10151016
zfs_mark_inode_dirty(ip);
10161017
}
10171018

@@ -1170,7 +1171,7 @@ zpl_init_acl(struct inode *ip, struct inode *dir)
11701171
return (PTR_ERR(acl));
11711172
if (!acl) {
11721173
ITOZ(ip)->z_mode = (ip->i_mode &= ~current_umask());
1173-
ip->i_ctime = current_time(ip);
1174+
zpl_inode_set_ctime_to_ts(ip, current_time(ip));
11741175
zfs_mark_inode_dirty(ip);
11751176
return (0);
11761177
}

0 commit comments

Comments
 (0)