linux 6.7 compat: use inode atime/mtime accessors

6.6 made i_ctime inaccessible; 6.7 has done the same for i_atime and
i_mtime. This extends the method used for ctime in b37f29341 to atime
and mtime as well.

Signed-off-by: Rob Norris <robn@despairlabs.com>
Sponsored-by: https://github.com/sponsors/robn
(cherry picked from commit 3c13601a12)
This commit is contained in:
Rob Norris 2023-12-16 22:31:32 +11:00 committed by Tony Hutter
parent da1cbd869b
commit e5f191d760
6 changed files with 148 additions and 35 deletions

View File

@ -52,6 +52,48 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_TIMES], [
memset(&ip, 0, sizeof(ip)); memset(&ip, 0, sizeof(ip));
inode_set_ctime_to_ts(&ip, ts); inode_set_ctime_to_ts(&ip, ts);
]) ])
dnl #
dnl # 6.7 API change
dnl # i_atime/i_mtime no longer directly accessible, must use
dnl # inode_get_mtime(ip), inode_set_mtime*(ip) to
dnl # read/write.
dnl #
ZFS_LINUX_TEST_SRC([inode_get_atime], [
#include <linux/fs.h>
],[
struct inode ip;
memset(&ip, 0, sizeof(ip));
inode_get_atime(&ip);
])
ZFS_LINUX_TEST_SRC([inode_get_mtime], [
#include <linux/fs.h>
],[
struct inode ip;
memset(&ip, 0, sizeof(ip));
inode_get_mtime(&ip);
])
ZFS_LINUX_TEST_SRC([inode_set_atime_to_ts], [
#include <linux/fs.h>
],[
struct inode ip;
struct timespec64 ts = {0};
memset(&ip, 0, sizeof(ip));
inode_set_atime_to_ts(&ip, ts);
])
ZFS_LINUX_TEST_SRC([inode_set_mtime_to_ts], [
#include <linux/fs.h>
],[
struct inode ip;
struct timespec64 ts = {0};
memset(&ip, 0, sizeof(ip));
inode_set_mtime_to_ts(&ip, ts);
])
]) ])
AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [ AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
@ -90,4 +132,40 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
],[ ],[
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
]) ])
AC_MSG_CHECKING([whether inode_get_atime() exists])
ZFS_LINUX_TEST_RESULT([inode_get_atime], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_INODE_GET_ATIME, 1,
[inode_get_atime() exists in linux/fs.h])
],[
AC_MSG_RESULT(no)
])
AC_MSG_CHECKING([whether inode_set_atime_to_ts() exists])
ZFS_LINUX_TEST_RESULT([inode_set_atime_to_ts], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_INODE_SET_ATIME_TO_TS, 1,
[inode_set_atime_to_ts() exists in linux/fs.h])
],[
AC_MSG_RESULT(no)
])
AC_MSG_CHECKING([whether inode_get_mtime() exists])
ZFS_LINUX_TEST_RESULT([inode_get_mtime], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_INODE_GET_MTIME, 1,
[inode_get_mtime() exists in linux/fs.h])
],[
AC_MSG_RESULT(no)
])
AC_MSG_CHECKING([whether inode_set_mtime_to_ts() exists])
ZFS_LINUX_TEST_RESULT([inode_set_mtime_to_ts], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_INODE_SET_MTIME_TO_TS, 1,
[inode_set_mtime_to_ts() exists in linux/fs.h])
],[
AC_MSG_RESULT(no)
])
]) ])

View File

@ -217,5 +217,25 @@ zpl_dir_emit_dots(struct file *file, zpl_dir_context_t *ctx)
#else #else
#define zpl_inode_set_ctime_to_ts(ip, ts) (ip->i_ctime = ts) #define zpl_inode_set_ctime_to_ts(ip, ts) (ip->i_ctime = ts)
#endif #endif
#ifdef HAVE_INODE_GET_ATIME
#define zpl_inode_get_atime(ip) inode_get_atime(ip)
#else
#define zpl_inode_get_atime(ip) (ip->i_atime)
#endif
#ifdef HAVE_INODE_SET_ATIME_TO_TS
#define zpl_inode_set_atime_to_ts(ip, ts) inode_set_atime_to_ts(ip, ts)
#else
#define zpl_inode_set_atime_to_ts(ip, ts) (ip->i_atime = ts)
#endif
#ifdef HAVE_INODE_GET_MTIME
#define zpl_inode_get_mtime(ip) inode_get_mtime(ip)
#else
#define zpl_inode_get_mtime(ip) (ip->i_mtime)
#endif
#ifdef HAVE_INODE_SET_MTIME_TO_TS
#define zpl_inode_set_mtime_to_ts(ip, ts) inode_set_mtime_to_ts(ip, ts)
#else
#define zpl_inode_set_mtime_to_ts(ip, ts) (ip->i_mtime = ts)
#endif
#endif /* _SYS_ZPL_H */ #endif /* _SYS_ZPL_H */

View File

@ -518,8 +518,8 @@ zfsctl_inode_alloc(zfsvfs_t *zfsvfs, uint64_t id,
ip->i_uid = SUID_TO_KUID(0); ip->i_uid = SUID_TO_KUID(0);
ip->i_gid = SGID_TO_KGID(0); ip->i_gid = SGID_TO_KGID(0);
ip->i_blkbits = SPA_MINBLOCKSHIFT; ip->i_blkbits = SPA_MINBLOCKSHIFT;
ip->i_atime = now; zpl_inode_set_atime_to_ts(ip, now);
ip->i_mtime = now; zpl_inode_set_mtime_to_ts(ip, now);
zpl_inode_set_ctime_to_ts(ip, 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;

View File

@ -2450,15 +2450,17 @@ top:
if ((mask & ATTR_ATIME) || zp->z_atime_dirty) { if ((mask & ATTR_ATIME) || zp->z_atime_dirty) {
zp->z_atime_dirty = B_FALSE; zp->z_atime_dirty = B_FALSE;
ZFS_TIME_ENCODE(&ip->i_atime, atime); inode_timespec_t tmp_atime;
ZFS_TIME_ENCODE(&tmp_atime, atime);
zpl_inode_set_atime_to_ts(ZTOI(zp), tmp_atime);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL,
&atime, sizeof (atime)); &atime, sizeof (atime));
} }
if (mask & (ATTR_MTIME | ATTR_SIZE)) { if (mask & (ATTR_MTIME | ATTR_SIZE)) {
ZFS_TIME_ENCODE(&vap->va_mtime, mtime); ZFS_TIME_ENCODE(&vap->va_mtime, mtime);
ZTOI(zp)->i_mtime = zpl_inode_timestamp_truncate( zpl_inode_set_mtime_to_ts(ZTOI(zp),
vap->va_mtime, ZTOI(zp)); zpl_inode_timestamp_truncate(vap->va_mtime, ZTOI(zp)));
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL,
mtime, sizeof (mtime)); mtime, sizeof (mtime));
@ -3503,7 +3505,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; inode_timespec_t tmp_ts;
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;
@ -3667,9 +3669,10 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
&zp->z_pflags, 8); &zp->z_pflags, 8);
/* 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); tmp_ts = zpl_inode_get_mtime(ip);
tmp_ctime = zpl_inode_get_ctime(ip); ZFS_TIME_ENCODE(&tmp_ts, mtime);
ZFS_TIME_ENCODE(&tmp_ctime, ctime); tmp_ts = zpl_inode_get_ctime(ip);
ZFS_TIME_ENCODE(&tmp_ts, ctime);
zp->z_atime_dirty = B_FALSE; zp->z_atime_dirty = B_FALSE;
zp->z_seq++; zp->z_seq++;
@ -3719,7 +3722,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; inode_timespec_t tmp_ts;
sa_bulk_attr_t bulk[4]; sa_bulk_attr_t bulk[4];
int error = 0; int error = 0;
int cnt = 0; int cnt = 0;
@ -3764,10 +3767,12 @@ zfs_dirty_inode(struct inode *ip, int flags)
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16); SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16);
/* 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); tmp_ts = zpl_inode_get_atime(ip);
ZFS_TIME_ENCODE(&ip->i_mtime, mtime); ZFS_TIME_ENCODE(&tmp_ts, atime);
tmp_ctime = zpl_inode_get_ctime(ip); tmp_ts = zpl_inode_get_mtime(ip);
ZFS_TIME_ENCODE(&tmp_ctime, ctime); ZFS_TIME_ENCODE(&tmp_ts, mtime);
tmp_ts = zpl_inode_get_ctime(ip);
ZFS_TIME_ENCODE(&tmp_ts, ctime);
mode = ip->i_mode; mode = ip->i_mode;
zp->z_mode = mode; zp->z_mode = mode;
@ -3811,7 +3816,9 @@ zfs_inactive(struct inode *ip)
if (error) { if (error) {
dmu_tx_abort(tx); dmu_tx_abort(tx);
} else { } else {
ZFS_TIME_ENCODE(&ip->i_atime, atime); inode_timespec_t tmp_atime;
tmp_atime = zpl_inode_get_atime(ip);
ZFS_TIME_ENCODE(&tmp_atime, atime);
mutex_enter(&zp->z_lock); mutex_enter(&zp->z_lock);
(void) sa_update(zp->z_sa_hdl, SA_ZPL_ATIME(zfsvfs), (void) sa_update(zp->z_sa_hdl, SA_ZPL_ATIME(zfsvfs),
(void *)&atime, sizeof (atime), tx); (void *)&atime, sizeof (atime), tx);

View File

@ -530,7 +530,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; inode_timespec_t tmp_ts;
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;
@ -602,10 +602,12 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
if (zp->z_pflags & ZFS_XATTR) if (zp->z_pflags & ZFS_XATTR)
zp->z_xattr_parent = parent; zp->z_xattr_parent = parent;
ZFS_TIME_DECODE(&ip->i_atime, atime); ZFS_TIME_DECODE(&tmp_ts, atime);
ZFS_TIME_DECODE(&ip->i_mtime, mtime); zpl_inode_set_atime_to_ts(ip, tmp_ts);
ZFS_TIME_DECODE(&tmp_ctime, ctime); ZFS_TIME_DECODE(&tmp_ts, mtime);
zpl_inode_set_ctime_to_ts(ip, tmp_ctime); zpl_inode_set_mtime_to_ts(ip, tmp_ts);
ZFS_TIME_DECODE(&tmp_ts, ctime);
zpl_inode_set_ctime_to_ts(ip, tmp_ts);
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;
@ -1186,7 +1188,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; inode_timespec_t tmp_ts;
uint64_t projid = ZFS_DEFAULT_PROJID; uint64_t projid = ZFS_DEFAULT_PROJID;
znode_hold_t *zh; znode_hold_t *zh;
@ -1279,10 +1281,12 @@ zfs_rezget(znode_t *zp)
zfs_uid_write(ZTOI(zp), z_uid); zfs_uid_write(ZTOI(zp), z_uid);
zfs_gid_write(ZTOI(zp), z_gid); zfs_gid_write(ZTOI(zp), z_gid);
ZFS_TIME_DECODE(&ZTOI(zp)->i_atime, atime); ZFS_TIME_DECODE(&tmp_ts, atime);
ZFS_TIME_DECODE(&ZTOI(zp)->i_mtime, mtime); zpl_inode_set_atime_to_ts(ZTOI(zp), tmp_ts);
ZFS_TIME_DECODE(&tmp_ctime, ctime); ZFS_TIME_DECODE(&tmp_ts, mtime);
zpl_inode_set_ctime_to_ts(ZTOI(zp), tmp_ctime); zpl_inode_set_mtime_to_ts(ZTOI(zp), tmp_ts);
ZFS_TIME_DECODE(&tmp_ts, ctime);
zpl_inode_set_ctime_to_ts(ZTOI(zp), tmp_ts);
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) {
@ -1390,22 +1394,24 @@ 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, tmp_ctime; inode_timespec_t now, tmp_atime, tmp_ts;
gethrestime(&now); gethrestime(&now);
tmp_atime = zpl_inode_get_atime(ip);
/* /*
* In relatime mode, only update the atime if the previous atime * In relatime mode, only update the atime if the previous atime
* is earlier than either the ctime or mtime or if at least a day * is earlier than either the ctime or mtime or if at least a day
* has passed since the last update of atime. * has passed since the last update of atime.
*/ */
if (zfs_compare_timespec(&ip->i_mtime, &ip->i_atime) >= 0) tmp_ts = zpl_inode_get_mtime(ip);
if (zfs_compare_timespec(&tmp_ts, &tmp_atime) >= 0)
return (B_TRUE); return (B_TRUE);
tmp_ctime = zpl_inode_get_ctime(ip); tmp_ts = zpl_inode_get_ctime(ip);
if (zfs_compare_timespec(&tmp_ctime, &ip->i_atime) >= 0) if (zfs_compare_timespec(&tmp_ts, &tmp_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)tmp_atime.tv_sec >= 24*60*60)
return (B_TRUE); return (B_TRUE);
return (B_FALSE); return (B_FALSE);
@ -1428,7 +1434,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, tmp_ctime; inode_timespec_t now, tmp_ts;
gethrestime(&now); gethrestime(&now);
@ -1436,7 +1442,8 @@ zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2],
if (flag & ATTR_MTIME) { if (flag & ATTR_MTIME) {
ZFS_TIME_ENCODE(&now, mtime); ZFS_TIME_ENCODE(&now, mtime);
ZFS_TIME_DECODE(&(ZTOI(zp)->i_mtime), mtime); ZFS_TIME_DECODE(&tmp_ts, mtime);
zpl_inode_set_mtime_to_ts(ZTOI(zp), tmp_ts);
if (ZTOZSB(zp)->z_use_fuids) { if (ZTOZSB(zp)->z_use_fuids) {
zp->z_pflags |= (ZFS_ARCHIVE | zp->z_pflags |= (ZFS_ARCHIVE |
ZFS_AV_MODIFIED); ZFS_AV_MODIFIED);
@ -1445,8 +1452,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(&tmp_ctime, ctime); ZFS_TIME_DECODE(&tmp_ts, ctime);
zpl_inode_set_ctime_to_ts(ZTOI(zp), tmp_ctime); zpl_inode_set_ctime_to_ts(ZTOI(zp), tmp_ts);
if (ZTOZSB(zp)->z_use_fuids) if (ZTOZSB(zp)->z_use_fuids)
zp->z_pflags |= ZFS_ARCHIVE; zp->z_pflags |= ZFS_ARCHIVE;
} }

View File

@ -497,7 +497,8 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
vap->va_ctime = ia->ia_ctime; vap->va_ctime = ia->ia_ctime;
if (vap->va_mask & ATTR_ATIME) if (vap->va_mask & ATTR_ATIME)
ip->i_atime = zpl_inode_timestamp_truncate(ia->ia_atime, ip); zpl_inode_set_atime_to_ts(ip,
zpl_inode_timestamp_truncate(ia->ia_atime, ip));
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_setattr(ITOZ(ip), vap, 0, cr); error = -zfs_setattr(ITOZ(ip), vap, 0, cr);