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 <behlendorf1@llnl.gov> Signed-off-by: Coleman Kane <ckane@colemankane.org> Closes #15263 Closes #15257
This commit is contained in:
parent
7aef672b77
commit
fe9d409e90
|
@ -27,6 +27,31 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_TIMES], [
|
||||||
memset(&ip, 0, sizeof(ip));
|
memset(&ip, 0, sizeof(ip));
|
||||||
ts = ip.i_mtime;
|
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], [
|
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,
|
AC_DEFINE(HAVE_INODE_TIMESPEC64_TIMES, 1,
|
||||||
[inode->i_*time's are timespec64])
|
[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)
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
|
@ -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)
|
#define zpl_setattr_prepare(ns, dentry, ia) setattr_prepare(dentry, ia)
|
||||||
#endif
|
#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 */
|
#endif /* _SYS_ZPL_H */
|
||||||
|
|
|
@ -522,7 +522,7 @@ zfsctl_inode_alloc(zfsvfs_t *zfsvfs, uint64_t id,
|
||||||
ip->i_blkbits = SPA_MINBLOCKSHIFT;
|
ip->i_blkbits = SPA_MINBLOCKSHIFT;
|
||||||
ip->i_atime = now;
|
ip->i_atime = now;
|
||||||
ip->i_mtime = now;
|
ip->i_mtime = now;
|
||||||
ip->i_ctime = now;
|
zpl_inode_set_ctime_to_ts(ip, now);
|
||||||
ip->i_fop = fops;
|
ip->i_fop = fops;
|
||||||
ip->i_op = ops;
|
ip->i_op = ops;
|
||||||
#if defined(IOP_XATTR)
|
#if defined(IOP_XATTR)
|
||||||
|
|
|
@ -2442,8 +2442,8 @@ top:
|
||||||
|
|
||||||
if (mask & (ATTR_CTIME | ATTR_SIZE)) {
|
if (mask & (ATTR_CTIME | ATTR_SIZE)) {
|
||||||
ZFS_TIME_ENCODE(&vap->va_ctime, ctime);
|
ZFS_TIME_ENCODE(&vap->va_ctime, ctime);
|
||||||
ZTOI(zp)->i_ctime = zpl_inode_timestamp_truncate(vap->va_ctime,
|
zpl_inode_set_ctime_to_ts(ZTOI(zp),
|
||||||
ZTOI(zp));
|
zpl_inode_timestamp_truncate(vap->va_ctime, ZTOI(zp)));
|
||||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL,
|
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL,
|
||||||
ctime, sizeof (ctime));
|
ctime, sizeof (ctime));
|
||||||
}
|
}
|
||||||
|
@ -3648,6 +3648,7 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
|
||||||
caddr_t va;
|
caddr_t va;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
uint64_t mtime[2], ctime[2];
|
uint64_t mtime[2], ctime[2];
|
||||||
|
inode_timespec_t tmp_ctime;
|
||||||
sa_bulk_attr_t bulk[3];
|
sa_bulk_attr_t bulk[3];
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
struct address_space *mapping;
|
struct address_space *mapping;
|
||||||
|
@ -3812,7 +3813,8 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
|
||||||
|
|
||||||
/* Preserve the mtime and ctime provided by the inode */
|
/* Preserve the mtime and ctime provided by the inode */
|
||||||
ZFS_TIME_ENCODE(&ip->i_mtime, mtime);
|
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_atime_dirty = B_FALSE;
|
||||||
zp->z_seq++;
|
zp->z_seq++;
|
||||||
|
|
||||||
|
@ -3862,6 +3864,7 @@ zfs_dirty_inode(struct inode *ip, int flags)
|
||||||
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
||||||
dmu_tx_t *tx;
|
dmu_tx_t *tx;
|
||||||
uint64_t mode, atime[2], mtime[2], ctime[2];
|
uint64_t mode, atime[2], mtime[2], ctime[2];
|
||||||
|
inode_timespec_t tmp_ctime;
|
||||||
sa_bulk_attr_t bulk[4];
|
sa_bulk_attr_t bulk[4];
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
@ -3908,7 +3911,8 @@ zfs_dirty_inode(struct inode *ip, int flags)
|
||||||
/* Preserve the mode, mtime and ctime provided by the inode */
|
/* Preserve the mode, mtime and ctime provided by the inode */
|
||||||
ZFS_TIME_ENCODE(&ip->i_atime, atime);
|
ZFS_TIME_ENCODE(&ip->i_atime, atime);
|
||||||
ZFS_TIME_ENCODE(&ip->i_mtime, mtime);
|
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;
|
mode = ip->i_mode;
|
||||||
|
|
||||||
zp->z_mode = mode;
|
zp->z_mode = mode;
|
||||||
|
|
|
@ -542,6 +542,7 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
|
||||||
uint64_t links;
|
uint64_t links;
|
||||||
uint64_t z_uid, z_gid;
|
uint64_t z_uid, z_gid;
|
||||||
uint64_t atime[2], mtime[2], ctime[2], btime[2];
|
uint64_t atime[2], mtime[2], ctime[2], btime[2];
|
||||||
|
inode_timespec_t tmp_ctime;
|
||||||
uint64_t projid = ZFS_DEFAULT_PROJID;
|
uint64_t projid = ZFS_DEFAULT_PROJID;
|
||||||
sa_bulk_attr_t bulk[12];
|
sa_bulk_attr_t bulk[12];
|
||||||
int count = 0;
|
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_atime, atime);
|
||||||
ZFS_TIME_DECODE(&ip->i_mtime, mtime);
|
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);
|
ZFS_TIME_DECODE(&zp->z_btime, btime);
|
||||||
|
|
||||||
ip->i_ino = zp->z_id;
|
ip->i_ino = zp->z_id;
|
||||||
|
@ -1195,6 +1197,7 @@ zfs_rezget(znode_t *zp)
|
||||||
uint64_t gen;
|
uint64_t gen;
|
||||||
uint64_t z_uid, z_gid;
|
uint64_t z_uid, z_gid;
|
||||||
uint64_t atime[2], mtime[2], ctime[2], btime[2];
|
uint64_t atime[2], mtime[2], ctime[2], btime[2];
|
||||||
|
inode_timespec_t tmp_ctime;
|
||||||
uint64_t projid = ZFS_DEFAULT_PROJID;
|
uint64_t projid = ZFS_DEFAULT_PROJID;
|
||||||
znode_hold_t *zh;
|
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_atime, atime);
|
||||||
ZFS_TIME_DECODE(&ZTOI(zp)->i_mtime, mtime);
|
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);
|
ZFS_TIME_DECODE(&zp->z_btime, btime);
|
||||||
|
|
||||||
if ((uint32_t)gen != ZTOI(zp)->i_generation) {
|
if ((uint32_t)gen != ZTOI(zp)->i_generation) {
|
||||||
|
@ -1397,7 +1401,7 @@ zfs_zinactive(znode_t *zp)
|
||||||
boolean_t
|
boolean_t
|
||||||
zfs_relatime_need_update(const struct inode *ip)
|
zfs_relatime_need_update(const struct inode *ip)
|
||||||
{
|
{
|
||||||
inode_timespec_t now;
|
inode_timespec_t now, tmp_ctime;
|
||||||
|
|
||||||
gethrestime(&now);
|
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)
|
if (zfs_compare_timespec(&ip->i_mtime, &ip->i_atime) >= 0)
|
||||||
return (B_TRUE);
|
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);
|
return (B_TRUE);
|
||||||
|
|
||||||
if ((hrtime_t)now.tv_sec - (hrtime_t)ip->i_atime.tv_sec >= 24*60*60)
|
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],
|
zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2],
|
||||||
uint64_t ctime[2])
|
uint64_t ctime[2])
|
||||||
{
|
{
|
||||||
inode_timespec_t now;
|
inode_timespec_t now, tmp_ctime;
|
||||||
|
|
||||||
gethrestime(&now);
|
gethrestime(&now);
|
||||||
|
|
||||||
|
@ -1451,7 +1456,8 @@ zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2],
|
||||||
|
|
||||||
if (flag & ATTR_CTIME) {
|
if (flag & ATTR_CTIME) {
|
||||||
ZFS_TIME_ENCODE(&now, 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)
|
if (ZTOZSB(zp)->z_use_fuids)
|
||||||
zp->z_pflags |= ZFS_ARCHIVE;
|
zp->z_pflags |= ZFS_ARCHIVE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -774,7 +774,7 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
|
||||||
return (-EMLINK);
|
return (-EMLINK);
|
||||||
|
|
||||||
crhold(cr);
|
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 */
|
/* Must have an existing ref, so igrab() cannot return NULL */
|
||||||
VERIFY3P(igrab(ip), !=, NULL);
|
VERIFY3P(igrab(ip), !=, NULL);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
error = -zfs_write_simple(xzp, value, size, pos, NULL);
|
||||||
out:
|
out:
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
ip->i_ctime = current_time(ip);
|
zpl_inode_set_ctime_to_ts(ip, current_time(ip));
|
||||||
zfs_mark_inode_dirty(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) {
|
if (ip->i_mode != mode) {
|
||||||
ip->i_mode = ITOZ(ip)->z_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);
|
zfs_mark_inode_dirty(ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1170,7 +1171,7 @@ zpl_init_acl(struct inode *ip, struct inode *dir)
|
||||||
return (PTR_ERR(acl));
|
return (PTR_ERR(acl));
|
||||||
if (!acl) {
|
if (!acl) {
|
||||||
ITOZ(ip)->z_mode = (ip->i_mode &= ~current_umask());
|
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);
|
zfs_mark_inode_dirty(ip);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue