mirror of https://github.com/archzfs/zfs-dkms
parent
146d8d0930
commit
6f086f72f6
@ -1,966 +0,0 @@ |
|||||||
From 35d4d9df7041b25b966f660de7b5f92b57cc64b7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Norris <robn@despairlabs.com>
|
|
||||||
Date: Sat, 16 Dec 2023 18:01:45 +1100
|
|
||||||
Subject: [PATCH 1/4] linux 6.7 compat: simplify current_time() check
|
|
||||||
|
|
||||||
6.7 changed the names of the time members in struct inode, so we can't
|
|
||||||
assign back to it because we don't know its name. In practice this
|
|
||||||
doesn't matter though - if we're missing current_time(), then we must be
|
|
||||||
on <4.9, and we know our fallback will need to return timespec.
|
|
||||||
|
|
||||||
Signed-off-by: Rob Norris <robn@despairlabs.com>
|
|
||||||
Sponsored-by: https://github.com/sponsors/robn
|
|
||||||
---
|
|
||||||
config/kernel-current-time.m4 | 5 ++++-
|
|
||||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/config/kernel-current-time.m4 b/config/kernel-current-time.m4
|
|
||||||
index 3ceb5f63efa9..ab7d9c5cedba 100644
|
|
||||||
--- a/config/kernel-current-time.m4
|
|
||||||
+++ b/config/kernel-current-time.m4
|
|
||||||
@@ -2,12 +2,15 @@ dnl #
|
|
||||||
dnl # 4.9, current_time() added
|
|
||||||
dnl # 4.18, return type changed from timespec to timespec64
|
|
||||||
dnl #
|
|
||||||
+dnl # Note that we don't care about the return type in this check. If we have
|
|
||||||
+dnl # to implement a fallback, we'll know we're <4.9, which was timespec.
|
|
||||||
+dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_CURRENT_TIME], [
|
|
||||||
ZFS_LINUX_TEST_SRC([current_time], [
|
|
||||||
#include <linux/fs.h>
|
|
||||||
], [
|
|
||||||
struct inode ip __attribute__ ((unused));
|
|
||||||
- ip.i_atime = current_time(&ip);
|
|
||||||
+ (void) current_time(&ip);
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
From 82d0e42313aedc17447e4481822c38824a9e0d6c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Norris <robn@despairlabs.com>
|
|
||||||
Date: Sat, 16 Dec 2023 22:31:32 +1100
|
|
||||||
Subject: [PATCH 2/4] 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
|
|
||||||
---
|
|
||||||
config/kernel-inode-times.m4 | 78 ++++++++++++++++++++++++++++++
|
|
||||||
include/os/linux/zfs/sys/zpl.h | 20 ++++++++
|
|
||||||
module/os/linux/zfs/zfs_ctldir.c | 4 +-
|
|
||||||
module/os/linux/zfs/zfs_vnops_os.c | 33 ++++++++-----
|
|
||||||
module/os/linux/zfs/zfs_znode.c | 45 +++++++++--------
|
|
||||||
module/os/linux/zfs/zpl_inode.c | 3 +-
|
|
||||||
6 files changed, 148 insertions(+), 35 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/config/kernel-inode-times.m4 b/config/kernel-inode-times.m4
|
|
||||||
index aae95abf1720..4d861596ed0b 100644
|
|
||||||
--- a/config/kernel-inode-times.m4
|
|
||||||
+++ b/config/kernel-inode-times.m4
|
|
||||||
@@ -52,6 +52,48 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_TIMES], [
|
|
||||||
memset(&ip, 0, sizeof(ip));
|
|
||||||
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], [
|
|
||||||
@@ -90,4 +132,40 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
|
|
||||||
],[
|
|
||||||
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)
|
|
||||||
+ ])
|
|
||||||
])
|
|
||||||
diff --git a/include/os/linux/zfs/sys/zpl.h b/include/os/linux/zfs/sys/zpl.h
|
|
||||||
index 9b729be6d74d..91a4751fffb0 100644
|
|
||||||
--- a/include/os/linux/zfs/sys/zpl.h
|
|
||||||
+++ b/include/os/linux/zfs/sys/zpl.h
|
|
||||||
@@ -273,5 +273,25 @@ extern long zpl_ioctl_fideduperange(struct file *filp, void *arg);
|
|
||||||
#else
|
|
||||||
#define zpl_inode_set_ctime_to_ts(ip, ts) (ip->i_ctime = ts)
|
|
||||||
#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 */
|
|
||||||
diff --git a/module/os/linux/zfs/zfs_ctldir.c b/module/os/linux/zfs/zfs_ctldir.c
|
|
||||||
index 94e25fa0ae8f..54ed70d0394f 100644
|
|
||||||
--- a/module/os/linux/zfs/zfs_ctldir.c
|
|
||||||
+++ b/module/os/linux/zfs/zfs_ctldir.c
|
|
||||||
@@ -520,8 +520,8 @@ zfsctl_inode_alloc(zfsvfs_t *zfsvfs, uint64_t id,
|
|
||||||
ip->i_uid = SUID_TO_KUID(0);
|
|
||||||
ip->i_gid = SGID_TO_KGID(0);
|
|
||||||
ip->i_blkbits = SPA_MINBLOCKSHIFT;
|
|
||||||
- ip->i_atime = now;
|
|
||||||
- ip->i_mtime = now;
|
|
||||||
+ zpl_inode_set_atime_to_ts(ip, now);
|
|
||||||
+ zpl_inode_set_mtime_to_ts(ip, now);
|
|
||||||
zpl_inode_set_ctime_to_ts(ip, now);
|
|
||||||
ip->i_fop = fops;
|
|
||||||
ip->i_op = ops;
|
|
||||||
diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c
|
|
||||||
index e990f7055f8a..10162f62cda2 100644
|
|
||||||
--- a/module/os/linux/zfs/zfs_vnops_os.c
|
|
||||||
+++ b/module/os/linux/zfs/zfs_vnops_os.c
|
|
||||||
@@ -2438,15 +2438,17 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr, zidmap_t *mnt_ns)
|
|
||||||
|
|
||||||
if ((mask & ATTR_ATIME) || zp->z_atime_dirty) {
|
|
||||||
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,
|
|
||||||
&atime, sizeof (atime));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask & (ATTR_MTIME | ATTR_SIZE)) {
|
|
||||||
ZFS_TIME_ENCODE(&vap->va_mtime, mtime);
|
|
||||||
- ZTOI(zp)->i_mtime = zpl_inode_timestamp_truncate(
|
|
||||||
- vap->va_mtime, ZTOI(zp));
|
|
||||||
+ zpl_inode_set_mtime_to_ts(ZTOI(zp),
|
|
||||||
+ zpl_inode_timestamp_truncate(vap->va_mtime, ZTOI(zp)));
|
|
||||||
|
|
||||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL,
|
|
||||||
mtime, sizeof (mtime));
|
|
||||||
@@ -3660,7 +3662,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;
|
|
||||||
+ inode_timespec_t tmp_ts;
|
|
||||||
sa_bulk_attr_t bulk[3];
|
|
||||||
int cnt = 0;
|
|
||||||
struct address_space *mapping;
|
|
||||||
@@ -3824,9 +3826,10 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
|
|
||||||
&zp->z_pflags, 8);
|
|
||||||
|
|
||||||
/* Preserve the mtime and ctime provided by the inode */
|
|
||||||
- ZFS_TIME_ENCODE(&ip->i_mtime, mtime);
|
|
||||||
- tmp_ctime = zpl_inode_get_ctime(ip);
|
|
||||||
- ZFS_TIME_ENCODE(&tmp_ctime, ctime);
|
|
||||||
+ tmp_ts = zpl_inode_get_mtime(ip);
|
|
||||||
+ ZFS_TIME_ENCODE(&tmp_ts, mtime);
|
|
||||||
+ tmp_ts = zpl_inode_get_ctime(ip);
|
|
||||||
+ ZFS_TIME_ENCODE(&tmp_ts, ctime);
|
|
||||||
zp->z_atime_dirty = B_FALSE;
|
|
||||||
zp->z_seq++;
|
|
||||||
|
|
||||||
@@ -3880,7 +3883,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;
|
|
||||||
+ inode_timespec_t tmp_ts;
|
|
||||||
sa_bulk_attr_t bulk[4];
|
|
||||||
int error = 0;
|
|
||||||
int cnt = 0;
|
|
||||||
@@ -3925,10 +3928,12 @@ zfs_dirty_inode(struct inode *ip, int flags)
|
|
||||||
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16);
|
|
||||||
|
|
||||||
/* Preserve the mode, mtime and ctime provided by the inode */
|
|
||||||
- ZFS_TIME_ENCODE(&ip->i_atime, atime);
|
|
||||||
- ZFS_TIME_ENCODE(&ip->i_mtime, mtime);
|
|
||||||
- tmp_ctime = zpl_inode_get_ctime(ip);
|
|
||||||
- ZFS_TIME_ENCODE(&tmp_ctime, ctime);
|
|
||||||
+ tmp_ts = zpl_inode_get_atime(ip);
|
|
||||||
+ ZFS_TIME_ENCODE(&tmp_ts, atime);
|
|
||||||
+ tmp_ts = zpl_inode_get_mtime(ip);
|
|
||||||
+ ZFS_TIME_ENCODE(&tmp_ts, mtime);
|
|
||||||
+ tmp_ts = zpl_inode_get_ctime(ip);
|
|
||||||
+ ZFS_TIME_ENCODE(&tmp_ts, ctime);
|
|
||||||
mode = ip->i_mode;
|
|
||||||
|
|
||||||
zp->z_mode = mode;
|
|
||||||
@@ -3971,7 +3976,9 @@ zfs_inactive(struct inode *ip)
|
|
||||||
if (error) {
|
|
||||||
dmu_tx_abort(tx);
|
|
||||||
} 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);
|
|
||||||
(void) sa_update(zp->z_sa_hdl, SA_ZPL_ATIME(zfsvfs),
|
|
||||||
(void *)&atime, sizeof (atime), tx);
|
|
||||||
diff --git a/module/os/linux/zfs/zfs_znode.c b/module/os/linux/zfs/zfs_znode.c
|
|
||||||
index f71026da83cb..b99df188c64b 100644
|
|
||||||
--- a/module/os/linux/zfs/zfs_znode.c
|
|
||||||
+++ b/module/os/linux/zfs/zfs_znode.c
|
|
||||||
@@ -542,7 +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;
|
|
||||||
+ inode_timespec_t tmp_ts;
|
|
||||||
uint64_t projid = ZFS_DEFAULT_PROJID;
|
|
||||||
sa_bulk_attr_t bulk[12];
|
|
||||||
int count = 0;
|
|
||||||
@@ -614,10 +614,12 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
|
|
||||||
if (zp->z_pflags & ZFS_XATTR)
|
|
||||||
zp->z_xattr_parent = parent;
|
|
||||||
|
|
||||||
- ZFS_TIME_DECODE(&ip->i_atime, atime);
|
|
||||||
- ZFS_TIME_DECODE(&ip->i_mtime, mtime);
|
|
||||||
- ZFS_TIME_DECODE(&tmp_ctime, ctime);
|
|
||||||
- zpl_inode_set_ctime_to_ts(ip, tmp_ctime);
|
|
||||||
+ ZFS_TIME_DECODE(&tmp_ts, atime);
|
|
||||||
+ zpl_inode_set_atime_to_ts(ip, tmp_ts);
|
|
||||||
+ ZFS_TIME_DECODE(&tmp_ts, mtime);
|
|
||||||
+ 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);
|
|
||||||
|
|
||||||
ip->i_ino = zp->z_id;
|
|
||||||
@@ -1197,7 +1199,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;
|
|
||||||
+ inode_timespec_t tmp_ts;
|
|
||||||
uint64_t projid = ZFS_DEFAULT_PROJID;
|
|
||||||
znode_hold_t *zh;
|
|
||||||
|
|
||||||
@@ -1290,10 +1292,12 @@ zfs_rezget(znode_t *zp)
|
|
||||||
zfs_uid_write(ZTOI(zp), z_uid);
|
|
||||||
zfs_gid_write(ZTOI(zp), z_gid);
|
|
||||||
|
|
||||||
- ZFS_TIME_DECODE(&ZTOI(zp)->i_atime, atime);
|
|
||||||
- ZFS_TIME_DECODE(&ZTOI(zp)->i_mtime, mtime);
|
|
||||||
- ZFS_TIME_DECODE(&tmp_ctime, ctime);
|
|
||||||
- zpl_inode_set_ctime_to_ts(ZTOI(zp), tmp_ctime);
|
|
||||||
+ ZFS_TIME_DECODE(&tmp_ts, atime);
|
|
||||||
+ zpl_inode_set_atime_to_ts(ZTOI(zp), tmp_ts);
|
|
||||||
+ ZFS_TIME_DECODE(&tmp_ts, mtime);
|
|
||||||
+ 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);
|
|
||||||
|
|
||||||
if ((uint32_t)gen != ZTOI(zp)->i_generation) {
|
|
||||||
@@ -1401,22 +1405,24 @@ zfs_zinactive(znode_t *zp)
|
|
||||||
boolean_t
|
|
||||||
zfs_relatime_need_update(const struct inode *ip)
|
|
||||||
{
|
|
||||||
- inode_timespec_t now, tmp_ctime;
|
|
||||||
+ inode_timespec_t now, tmp_atime, tmp_ts;
|
|
||||||
|
|
||||||
gethrestime(&now);
|
|
||||||
+ tmp_atime = zpl_inode_get_atime(ip);
|
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
- tmp_ctime = zpl_inode_get_ctime(ip);
|
|
||||||
- if (zfs_compare_timespec(&tmp_ctime, &ip->i_atime) >= 0)
|
|
||||||
+ tmp_ts = zpl_inode_get_ctime(ip);
|
|
||||||
+ if (zfs_compare_timespec(&tmp_ts, &tmp_atime) >= 0)
|
|
||||||
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_FALSE);
|
|
||||||
@@ -1439,7 +1445,7 @@ void
|
|
||||||
zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2],
|
|
||||||
uint64_t ctime[2])
|
|
||||||
{
|
|
||||||
- inode_timespec_t now, tmp_ctime;
|
|
||||||
+ inode_timespec_t now, tmp_ts;
|
|
||||||
|
|
||||||
gethrestime(&now);
|
|
||||||
|
|
||||||
@@ -1447,7 +1453,8 @@ zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2],
|
|
||||||
|
|
||||||
if (flag & ATTR_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) {
|
|
||||||
zp->z_pflags |= (ZFS_ARCHIVE |
|
|
||||||
ZFS_AV_MODIFIED);
|
|
||||||
@@ -1456,8 +1463,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(&tmp_ctime, ctime);
|
|
||||||
- zpl_inode_set_ctime_to_ts(ZTOI(zp), tmp_ctime);
|
|
||||||
+ ZFS_TIME_DECODE(&tmp_ts, ctime);
|
|
||||||
+ zpl_inode_set_ctime_to_ts(ZTOI(zp), tmp_ts);
|
|
||||||
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 96f65b9e94e2..ad1753f7a071 100644
|
|
||||||
--- a/module/os/linux/zfs/zpl_inode.c
|
|
||||||
+++ b/module/os/linux/zfs/zpl_inode.c
|
|
||||||
@@ -526,7 +526,8 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
|
|
||||||
vap->va_ctime = ia->ia_ctime;
|
|
||||||
|
|
||||||
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();
|
|
||||||
#ifdef HAVE_USERNS_IOPS_SETATTR
|
|
||||||
|
|
||||||
From d7ebc6a92c45f5a62510f25b5544ad2ef7333c2c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Norris <robn@despairlabs.com>
|
|
||||||
Date: Sat, 16 Dec 2023 17:39:07 +1100
|
|
||||||
Subject: [PATCH 3/4] linux 6.7 compat: handle superblock shrinker member
|
|
||||||
change
|
|
||||||
|
|
||||||
In 6.7 the superblock shrinker member s_shrink has changed from being an
|
|
||||||
embedded struct to a pointer. Detect this, and don't take a reference if
|
|
||||||
it already is one.
|
|
||||||
|
|
||||||
Signed-off-by: Rob Norris <robn@despairlabs.com>
|
|
||||||
Sponsored-by: https://github.com/sponsors/robn
|
|
||||||
---
|
|
||||||
config/kernel-shrink.m4 | 35 +++++++++++++++++++++++++++++++-
|
|
||||||
module/os/linux/zfs/zfs_vfsops.c | 10 +++++++--
|
|
||||||
2 files changed, 42 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/config/kernel-shrink.m4 b/config/kernel-shrink.m4
|
|
||||||
index 0c702153e8c4..1c5f753d411c 100644
|
|
||||||
--- a/config/kernel-shrink.m4
|
|
||||||
+++ b/config/kernel-shrink.m4
|
|
||||||
@@ -19,12 +19,44 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK], [
|
|
||||||
],[])
|
|
||||||
])
|
|
||||||
|
|
||||||
+dnl #
|
|
||||||
+dnl # 6.7 API change
|
|
||||||
+dnl # s_shrink is now a pointer.
|
|
||||||
+dnl #
|
|
||||||
+AC_DEFUN([ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK_PTR], [
|
|
||||||
+ ZFS_LINUX_TEST_SRC([super_block_s_shrink_ptr], [
|
|
||||||
+ #include <linux/fs.h>
|
|
||||||
+ unsigned long shrinker_cb(struct shrinker *shrink,
|
|
||||||
+ struct shrink_control *sc) { return 0; }
|
|
||||||
+ static struct shrinker shrinker = {
|
|
||||||
+ .count_objects = shrinker_cb,
|
|
||||||
+ .scan_objects = shrinker_cb,
|
|
||||||
+ .seeks = DEFAULT_SEEKS,
|
|
||||||
+ };
|
|
||||||
+ static const struct super_block
|
|
||||||
+ sb __attribute__ ((unused)) = {
|
|
||||||
+ .s_shrink = &shrinker,
|
|
||||||
+ };
|
|
||||||
+ ],[])
|
|
||||||
+])
|
|
||||||
+
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SUPER_BLOCK_S_SHRINK], [
|
|
||||||
AC_MSG_CHECKING([whether super_block has s_shrink])
|
|
||||||
ZFS_LINUX_TEST_RESULT([super_block_s_shrink], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
+ AC_DEFINE(HAVE_SUPER_BLOCK_S_SHRINK, 1,
|
|
||||||
+ [have super_block s_shrink])
|
|
||||||
],[
|
|
||||||
- ZFS_LINUX_TEST_ERROR([sb->s_shrink()])
|
|
||||||
+ AC_MSG_RESULT(no)
|
|
||||||
+ AC_MSG_CHECKING([whether super_block has s_shrink pointer])
|
|
||||||
+ ZFS_LINUX_TEST_RESULT([super_block_s_shrink_ptr], [
|
|
||||||
+ AC_MSG_RESULT(yes)
|
|
||||||
+ AC_DEFINE(HAVE_SUPER_BLOCK_S_SHRINK_PTR, 1,
|
|
||||||
+ [have super_block s_shrink pointer])
|
|
||||||
+ ],[
|
|
||||||
+ AC_MSG_RESULT(no)
|
|
||||||
+ ZFS_LINUX_TEST_ERROR([sb->s_shrink()])
|
|
||||||
+ ])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
@@ -174,6 +206,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINK_CONTROL_STRUCT], [
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER], [
|
|
||||||
ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK
|
|
||||||
+ ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK_PTR
|
|
||||||
ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_HAS_NID
|
|
||||||
ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK
|
|
||||||
ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT
|
|
||||||
diff --git a/module/os/linux/zfs/zfs_vfsops.c b/module/os/linux/zfs/zfs_vfsops.c
|
|
||||||
index 2792bc027213..2015c20d7340 100644
|
|
||||||
--- a/module/os/linux/zfs/zfs_vfsops.c
|
|
||||||
+++ b/module/os/linux/zfs/zfs_vfsops.c
|
|
||||||
@@ -1240,12 +1240,18 @@ zfs_prune_aliases(zfsvfs_t *zfsvfs, unsigned long nr_to_scan)
|
|
||||||
* and inode caches. This can occur when the ARC needs to free meta data
|
|
||||||
* blocks but can't because they are all pinned by entries in these caches.
|
|
||||||
*/
|
|
||||||
+#if defined(HAVE_SUPER_BLOCK_S_SHRINK)
|
|
||||||
+#define S_SHRINK(sb) (&(sb)->s_shrink)
|
|
||||||
+#elif defined(HAVE_SUPER_BLOCK_S_SHRINK_PTR)
|
|
||||||
+#define S_SHRINK(sb) ((sb)->s_shrink)
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
int
|
|
||||||
zfs_prune(struct super_block *sb, unsigned long nr_to_scan, int *objects)
|
|
||||||
{
|
|
||||||
zfsvfs_t *zfsvfs = sb->s_fs_info;
|
|
||||||
int error = 0;
|
|
||||||
- struct shrinker *shrinker = &sb->s_shrink;
|
|
||||||
+ struct shrinker *shrinker = S_SHRINK(sb);
|
|
||||||
struct shrink_control sc = {
|
|
||||||
.nr_to_scan = nr_to_scan,
|
|
||||||
.gfp_mask = GFP_KERNEL,
|
|
||||||
@@ -1257,7 +1263,7 @@ zfs_prune(struct super_block *sb, unsigned long nr_to_scan, int *objects)
|
|
||||||
#if defined(HAVE_SPLIT_SHRINKER_CALLBACK) && \
|
|
||||||
defined(SHRINK_CONTROL_HAS_NID) && \
|
|
||||||
defined(SHRINKER_NUMA_AWARE)
|
|
||||||
- if (sb->s_shrink.flags & SHRINKER_NUMA_AWARE) {
|
|
||||||
+ if (shrinker->flags & SHRINKER_NUMA_AWARE) {
|
|
||||||
*objects = 0;
|
|
||||||
for_each_online_node(sc.nid) {
|
|
||||||
*objects += (*shrinker->scan_objects)(shrinker, &sc);
|
|
||||||
|
|
||||||
From e0cc696208e903cb00fe23bf7f5dc235c6995122 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Norris <robn@despairlabs.com>
|
|
||||||
Date: Sun, 17 Dec 2023 00:36:21 +1100
|
|
||||||
Subject: [PATCH 4/4] linux 6.7 compat: rework shrinker setup for heap
|
|
||||||
allocations
|
|
||||||
|
|
||||||
6.7 changes the shrinker API such that shrinkers must be allocated
|
|
||||||
dynamically by the kernel. To accomodate this, this commit reworks
|
|
||||||
spl_register_shrinker() to do something similar against earlier kernels.
|
|
||||||
|
|
||||||
Signed-off-by: Rob Norris <robn@despairlabs.com>
|
|
||||||
Sponsored-by: https://github.com/sponsors/robn
|
|
||||||
---
|
|
||||||
config/kernel-shrink.m4 | 52 +++++++++++--
|
|
||||||
include/os/linux/spl/sys/shrinker.h | 66 +++++-----------
|
|
||||||
module/Kbuild.in | 1 +
|
|
||||||
module/os/linux/spl/spl-shrinker.c | 115 ++++++++++++++++++++++++++++
|
|
||||||
module/os/linux/zfs/arc_os.c | 11 ++-
|
|
||||||
5 files changed, 189 insertions(+), 56 deletions(-)
|
|
||||||
create mode 100644 module/os/linux/spl/spl-shrinker.c
|
|
||||||
|
|
||||||
diff --git a/config/kernel-shrink.m4 b/config/kernel-shrink.m4
|
|
||||||
index 1c5f753d411c..4a529c43b5b0 100644
|
|
||||||
--- a/config/kernel-shrink.m4
|
|
||||||
+++ b/config/kernel-shrink.m4
|
|
||||||
@@ -128,6 +128,25 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK], [
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
+dnl #
|
|
||||||
+dnl # 6.7 API change
|
|
||||||
+dnl # register_shrinker has been replaced by shrinker_register.
|
|
||||||
+dnl #
|
|
||||||
+AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER_REGISTER], [
|
|
||||||
+ ZFS_LINUX_TEST_SRC([shrinker_register], [
|
|
||||||
+ #include <linux/shrinker.h>
|
|
||||||
+ unsigned long shrinker_cb(struct shrinker *shrink,
|
|
||||||
+ struct shrink_control *sc) { return 0; }
|
|
||||||
+ ],[
|
|
||||||
+ struct shrinker cache_shrinker = {
|
|
||||||
+ .count_objects = shrinker_cb,
|
|
||||||
+ .scan_objects = shrinker_cb,
|
|
||||||
+ .seeks = DEFAULT_SEEKS,
|
|
||||||
+ };
|
|
||||||
+ shrinker_register(&cache_shrinker);
|
|
||||||
+ ])
|
|
||||||
+])
|
|
||||||
+
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
|
|
||||||
dnl #
|
|
||||||
dnl # 6.0 API change
|
|
||||||
@@ -165,14 +184,36 @@ AC_DEFUN([ZFS_AC_KERNEL_SHRINKER_CALLBACK],[
|
|
||||||
dnl # cs->shrink() is logically split in to
|
|
||||||
dnl # cs->count_objects() and cs->scan_objects()
|
|
||||||
dnl #
|
|
||||||
- AC_MSG_CHECKING([if cs->count_objects callback exists])
|
|
||||||
+ AC_MSG_CHECKING(
|
|
||||||
+ [whether cs->count_objects callback exists])
|
|
||||||
ZFS_LINUX_TEST_RESULT(
|
|
||||||
- [shrinker_cb_shrink_control_split],[
|
|
||||||
- AC_MSG_RESULT(yes)
|
|
||||||
- AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK, 1,
|
|
||||||
- [cs->count_objects exists])
|
|
||||||
+ [shrinker_cb_shrink_control_split],[
|
|
||||||
+ AC_MSG_RESULT(yes)
|
|
||||||
+ AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK, 1,
|
|
||||||
+ [cs->count_objects exists])
|
|
||||||
],[
|
|
||||||
+ AC_MSG_RESULT(no)
|
|
||||||
+
|
|
||||||
+ AC_MSG_CHECKING(
|
|
||||||
+ [whether shrinker_register exists])
|
|
||||||
+ ZFS_LINUX_TEST_RESULT([shrinker_register], [
|
|
||||||
+ AC_MSG_RESULT(yes)
|
|
||||||
+ AC_DEFINE(HAVE_SHRINKER_REGISTER, 1,
|
|
||||||
+ [shrinker_register exists])
|
|
||||||
+
|
|
||||||
+ dnl # We assume that the split shrinker
|
|
||||||
+ dnl # callback exists if
|
|
||||||
+ dnl # shrinker_register() exists,
|
|
||||||
+ dnl # because the latter is a much more
|
|
||||||
+ dnl # recent addition, and the macro
|
|
||||||
+ dnl # test for shrinker_register() only
|
|
||||||
+ dnl # works if the callback is split
|
|
||||||
+ AC_DEFINE(HAVE_SPLIT_SHRINKER_CALLBACK,
|
|
||||||
+ 1, [cs->count_objects exists])
|
|
||||||
+ ],[
|
|
||||||
+ AC_MSG_RESULT(no)
|
|
||||||
ZFS_LINUX_TEST_ERROR([shrinker])
|
|
||||||
+ ])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
])
|
|
||||||
@@ -211,6 +252,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER], [
|
|
||||||
ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK
|
|
||||||
ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT
|
|
||||||
ZFS_AC_KERNEL_SRC_REGISTER_SHRINKER_VARARG
|
|
||||||
+ ZFS_AC_KERNEL_SRC_SHRINKER_REGISTER
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SHRINKER], [
|
|
||||||
diff --git a/include/os/linux/spl/sys/shrinker.h b/include/os/linux/spl/sys/shrinker.h
|
|
||||||
index d472754be4f4..bca4c850694a 100644
|
|
||||||
--- a/include/os/linux/spl/sys/shrinker.h
|
|
||||||
+++ b/include/os/linux/spl/sys/shrinker.h
|
|
||||||
@@ -29,12 +29,13 @@
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Due to frequent changes in the shrinker API the following
|
|
||||||
- * compatibility wrappers should be used. They are as follows:
|
|
||||||
+ * compatibility wrapper should be used.
|
|
||||||
*
|
|
||||||
- * SPL_SHRINKER_DECLARE(varname, countfunc, scanfunc, seek_cost);
|
|
||||||
+ * shrinker = spl_register_shrinker(name, countfunc, scanfunc, seek_cost);
|
|
||||||
+ * spl_unregister_shrinker(shrinker);
|
|
||||||
*
|
|
||||||
- * SPL_SHRINKER_DECLARE is used to declare a shrinker with the name varname,
|
|
||||||
- * which is passed to spl_register_shrinker()/spl_unregister_shrinker().
|
|
||||||
+ * spl_register_shrinker is used to create and register a shrinker with the
|
|
||||||
+ * given name.
|
|
||||||
* The countfunc returns the number of free-able objects.
|
|
||||||
* The scanfunc returns the number of objects that were freed.
|
|
||||||
* The callbacks can return SHRINK_STOP if further calls can't make any more
|
|
||||||
@@ -57,57 +58,28 @@
|
|
||||||
* ...scan objects in the cache and reclaim them...
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
- * SPL_SHRINKER_DECLARE(my_shrinker, my_count, my_scan, DEFAULT_SEEKS);
|
|
||||||
+ * static struct shrinker *my_shrinker;
|
|
||||||
*
|
|
||||||
* void my_init_func(void) {
|
|
||||||
- * spl_register_shrinker(&my_shrinker);
|
|
||||||
+ * my_shrinker = spl_register_shrinker("my-shrinker",
|
|
||||||
+ * my_count, my_scan, DEFAULT_SEEKS);
|
|
||||||
+ * }
|
|
||||||
+ *
|
|
||||||
+ * void my_fini_func(void) {
|
|
||||||
+ * spl_unregister_shrinker(my_shrinker);
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
|
|
||||||
-#ifdef HAVE_REGISTER_SHRINKER_VARARG
|
|
||||||
-#define spl_register_shrinker(x) register_shrinker(x, "zfs-arc-shrinker")
|
|
||||||
-#else
|
|
||||||
-#define spl_register_shrinker(x) register_shrinker(x)
|
|
||||||
-#endif
|
|
||||||
-#define spl_unregister_shrinker(x) unregister_shrinker(x)
|
|
||||||
+typedef unsigned long (*spl_shrinker_cb)
|
|
||||||
+ (struct shrinker *, struct shrink_control *);
|
|
||||||
|
|
||||||
-/*
|
|
||||||
- * Linux 3.0 to 3.11 Shrinker API Compatibility.
|
|
||||||
- */
|
|
||||||
-#if defined(HAVE_SINGLE_SHRINKER_CALLBACK)
|
|
||||||
-#define SPL_SHRINKER_DECLARE(varname, countfunc, scanfunc, seek_cost) \
|
|
||||||
-static int \
|
|
||||||
-__ ## varname ## _wrapper(struct shrinker *shrink, struct shrink_control *sc)\
|
|
||||||
-{ \
|
|
||||||
- if (sc->nr_to_scan != 0) { \
|
|
||||||
- (void) scanfunc(shrink, sc); \
|
|
||||||
- } \
|
|
||||||
- return (countfunc(shrink, sc)); \
|
|
||||||
-} \
|
|
||||||
- \
|
|
||||||
-static struct shrinker varname = { \
|
|
||||||
- .shrink = __ ## varname ## _wrapper, \
|
|
||||||
- .seeks = seek_cost, \
|
|
||||||
-}
|
|
||||||
+struct shrinker *spl_register_shrinker(const char *name,
|
|
||||||
+ spl_shrinker_cb countfunc, spl_shrinker_cb scanfunc, int seek_cost);
|
|
||||||
+void spl_unregister_shrinker(struct shrinker *);
|
|
||||||
|
|
||||||
+#ifndef SHRINK_STOP
|
|
||||||
+/* 3.0-3.11 compatibility */
|
|
||||||
#define SHRINK_STOP (-1)
|
|
||||||
-
|
|
||||||
-/*
|
|
||||||
- * Linux 3.12 and later Shrinker API Compatibility.
|
|
||||||
- */
|
|
||||||
-#elif defined(HAVE_SPLIT_SHRINKER_CALLBACK)
|
|
||||||
-#define SPL_SHRINKER_DECLARE(varname, countfunc, scanfunc, seek_cost) \
|
|
||||||
-static struct shrinker varname = { \
|
|
||||||
- .count_objects = countfunc, \
|
|
||||||
- .scan_objects = scanfunc, \
|
|
||||||
- .seeks = seek_cost, \
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-#else
|
|
||||||
-/*
|
|
||||||
- * Linux 2.x to 2.6.22, or a newer shrinker API has been introduced.
|
|
||||||
- */
|
|
||||||
-#error "Unknown shrinker callback"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* SPL_SHRINKER_H */
|
|
||||||
diff --git a/module/Kbuild.in b/module/Kbuild.in
|
|
||||||
index e34b9fab9efc..fb22bfe733c0 100644
|
|
||||||
--- a/module/Kbuild.in
|
|
||||||
+++ b/module/Kbuild.in
|
|
||||||
@@ -79,6 +79,7 @@ SPL_OBJS := \
|
|
||||||
spl-kstat.o \
|
|
||||||
spl-proc.o \
|
|
||||||
spl-procfs-list.o \
|
|
||||||
+ spl-shrinker.o \
|
|
||||||
spl-taskq.o \
|
|
||||||
spl-thread.o \
|
|
||||||
spl-trace.o \
|
|
||||||
diff --git a/module/os/linux/spl/spl-shrinker.c b/module/os/linux/spl/spl-shrinker.c
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000000..d5c8da471cbb
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/module/os/linux/spl/spl-shrinker.c
|
|
||||||
@@ -0,0 +1,115 @@
|
|
||||||
+/*
|
|
||||||
+ * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
|
|
||||||
+ * Copyright (C) 2007 The Regents of the University of California.
|
|
||||||
+ * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
|
|
||||||
+ * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
|
|
||||||
+ * UCRL-CODE-235197
|
|
||||||
+ *
|
|
||||||
+ * This file is part of the SPL, Solaris Porting Layer.
|
|
||||||
+ *
|
|
||||||
+ * The SPL is free software; you can redistribute it and/or modify it
|
|
||||||
+ * under the terms of the GNU General Public License as published by the
|
|
||||||
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
+ * option) any later version.
|
|
||||||
+ *
|
|
||||||
+ * The SPL is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
+ * for more details.
|
|
||||||
+ *
|
|
||||||
+ * You should have received a copy of the GNU General Public License along
|
|
||||||
+ * with the SPL. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
+ *
|
|
||||||
+ * Solaris Porting Layer (SPL) Shrinker Implementation.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#include <sys/kmem.h>
|
|
||||||
+#include <sys/shrinker.h>
|
|
||||||
+
|
|
||||||
+#ifdef HAVE_SINGLE_SHRINKER_CALLBACK
|
|
||||||
+/* 3.0-3.11: single shrink() callback, which we wrap to carry both functions */
|
|
||||||
+struct spl_shrinker_wrap {
|
|
||||||
+ struct shrinker shrinker;
|
|
||||||
+ spl_shrinker_cb countfunc;
|
|
||||||
+ spl_shrinker_cb scanfunc;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int
|
|
||||||
+spl_shrinker_single_cb(struct shrinker *shrinker, struct shrink_control *sc)
|
|
||||||
+{
|
|
||||||
+ struct spl_shrinker_wrap *sw = (struct spl_shrinker_wrap *)shrinker;
|
|
||||||
+
|
|
||||||
+ if (sc->nr_to_scan != 0)
|
|
||||||
+ (void) sw->scanfunc(&sw->shrinker, sc);
|
|
||||||
+ return (sw->countfunc(&sw->shrinker, sc));
|
|
||||||
+}
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+struct shrinker *
|
|
||||||
+spl_register_shrinker(const char *name, spl_shrinker_cb countfunc,
|
|
||||||
+ spl_shrinker_cb scanfunc, int seek_cost)
|
|
||||||
+{
|
|
||||||
+ struct shrinker *shrinker;
|
|
||||||
+
|
|
||||||
+ /* allocate shrinker */
|
|
||||||
+#if defined(HAVE_SHRINKER_REGISTER)
|
|
||||||
+ /* 6.7: kernel will allocate the shrinker for us */
|
|
||||||
+ shrinker = shrinker_alloc(0, name);
|
|
||||||
+#elif defined(HAVE_SPLIT_SHRINKER_CALLBACK)
|
|
||||||
+ /* 3.12-6.6: we allocate the shrinker */
|
|
||||||
+ shrinker = kmem_zalloc(sizeof (struct shrinker), KM_SLEEP);
|
|
||||||
+#elif defined(HAVE_SINGLE_SHRINKER_CALLBACK)
|
|
||||||
+ /* 3.0-3.11: allocate a wrapper */
|
|
||||||
+ struct spl_shrinker_wrap *sw =
|
|
||||||
+ kmem_zalloc(sizeof (struct spl_shrinker_wrap), KM_SLEEP);
|
|
||||||
+ shrinker = &sw->shrinker;
|
|
||||||
+#else
|
|
||||||
+ /* 2.x-2.6.22, or a newer shrinker API has been introduced. */
|
|
||||||
+#error "Unknown shrinker API"
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ if (shrinker == NULL)
|
|
||||||
+ return (NULL);
|
|
||||||
+
|
|
||||||
+ /* set callbacks */
|
|
||||||
+#ifdef HAVE_SINGLE_SHRINKER_CALLBACK
|
|
||||||
+ sw->countfunc = countfunc;
|
|
||||||
+ sw->scanfunc = scanfunc;
|
|
||||||
+ shrinker->shrink = spl_shrinker_single_cb;
|
|
||||||
+#else
|
|
||||||
+ shrinker->count_objects = countfunc;
|
|
||||||
+ shrinker->scan_objects = scanfunc;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ /* set params */
|
|
||||||
+ shrinker->seeks = seek_cost;
|
|
||||||
+
|
|
||||||
+ /* register with kernel */
|
|
||||||
+#if defined(HAVE_SHRINKER_REGISTER)
|
|
||||||
+ shrinker_register(shrinker);
|
|
||||||
+#elif defined(HAVE_REGISTER_SHRINKER_VARARG)
|
|
||||||
+ register_shrinker(shrinker, name);
|
|
||||||
+#else
|
|
||||||
+ register_shrinker(shrinker);
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ return (shrinker);
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL(spl_register_shrinker);
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+spl_unregister_shrinker(struct shrinker *shrinker)
|
|
||||||
+{
|
|
||||||
+#if defined(HAVE_SHRINKER_REGISTER)
|
|
||||||
+ shrinker_free(shrinker);
|
|
||||||
+#elif defined(HAVE_SPLIT_SHRINKER_CALLBACK)
|
|
||||||
+ unregister_shrinker(shrinker);
|
|
||||||
+ kmem_free(shrinker, sizeof (struct shrinker));
|
|
||||||
+#elif defined(HAVE_SINGLE_SHRINKER_CALLBACK)
|
|
||||||
+ unregister_shrinker(shrinker);
|
|
||||||
+ kmem_free(shrinker, sizeof (struct spl_shrinker_wrap));
|
|
||||||
+#else
|
|
||||||
+#error "Unknown shrinker API"
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL(spl_unregister_shrinker);
|
|
||||||
diff --git a/module/os/linux/zfs/arc_os.c b/module/os/linux/zfs/arc_os.c
|
|
||||||
index 55cdbba5b5eb..02dd80c06062 100644
|
|
||||||
--- a/module/os/linux/zfs/arc_os.c
|
|
||||||
+++ b/module/os/linux/zfs/arc_os.c
|
|
||||||
@@ -253,8 +253,7 @@ arc_shrinker_scan(struct shrinker *shrink, struct shrink_control *sc)
|
|
||||||
return (sc->nr_to_scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
-SPL_SHRINKER_DECLARE(arc_shrinker,
|
|
||||||
- arc_shrinker_count, arc_shrinker_scan, DEFAULT_SEEKS);
|
|
||||||
+static struct shrinker *arc_shrinker = NULL;
|
|
||||||
|
|
||||||
int
|
|
||||||
arc_memory_throttle(spa_t *spa, uint64_t reserve, uint64_t txg)
|
|
||||||
@@ -357,14 +356,18 @@ arc_lowmem_init(void)
|
|
||||||
* reclaim from the arc. This is done to prevent kswapd from
|
|
||||||
* swapping out pages when it is preferable to shrink the arc.
|
|
||||||
*/
|
|
||||||
- spl_register_shrinker(&arc_shrinker);
|
|
||||||
+ arc_shrinker = spl_register_shrinker("zfs-arc-shrinker",
|
|
||||||
+ arc_shrinker_count, arc_shrinker_scan, DEFAULT_SEEKS);
|
|
||||||
+ VERIFY(arc_shrinker);
|
|
||||||
+
|
|
||||||
arc_set_sys_free(allmem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
arc_lowmem_fini(void)
|
|
||||||
{
|
|
||||||
- spl_unregister_shrinker(&arc_shrinker);
|
|
||||||
+ spl_unregister_shrinker(arc_shrinker);
|
|
||||||
+ arc_shrinker = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
|
|
||||||
|
|
||||||
From 49b2dee41a483ebc187ab2b42a6250242298b71b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Norris <robn@despairlabs.com>
|
|
||||||
Date: Mon, 15 Jan 2024 09:01:39 +1100
|
|
||||||
Subject: [PATCH 1/2] tests/ctime: ensure times change by the right amount
|
|
||||||
|
|
||||||
Previously, we only checked if the times changed at all, which missed a
|
|
||||||
bug where the atime was being set to an undefined value.
|
|
||||||
|
|
||||||
Now ensure the times change by two seconds (or thereabouts), ensuring we
|
|
||||||
catch cases where we set the time to something bonkers
|
|
||||||
|
|
||||||
Signed-off-by: Rob Norris <robn@despairlabs.com>
|
|
||||||
Sponsored-by: https://despairlabs.com/sponsor/
|
|
||||||
---
|
|
||||||
tests/zfs-tests/cmd/ctime.c | 14 +++++++++++---
|
|
||||||
1 file changed, 11 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tests/zfs-tests/cmd/ctime.c b/tests/zfs-tests/cmd/ctime.c
|
|
||||||
index 0f5d81aea613..5ff1cea8a869 100644
|
|
||||||
--- a/tests/zfs-tests/cmd/ctime.c
|
|
||||||
+++ b/tests/zfs-tests/cmd/ctime.c
|
|
||||||
@@ -362,12 +362,20 @@ main(void)
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (t1 == t2) {
|
|
||||||
- (void) fprintf(stderr, "%s: t1(%ld) == t2(%ld)\n",
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Ideally, time change would be exactly two seconds, but allow
|
|
||||||
+ * a little slack in case of scheduling delays or similar.
|
|
||||||
+ */
|
|
||||||
+ long delta = (long)t2 - (long)t1;
|
|
||||||
+ if (delta < 2 || delta > 4) {
|
|
||||||
+ (void) fprintf(stderr,
|
|
||||||
+ "%s: BAD time change: t1(%ld), t2(%ld)\n",
|
|
||||||
timetest_table[i].name, (long)t1, (long)t2);
|
|
||||||
return (1);
|
|
||||||
} else {
|
|
||||||
- (void) fprintf(stderr, "%s: t1(%ld) != t2(%ld)\n",
|
|
||||||
+ (void) fprintf(stderr,
|
|
||||||
+ "%s: good time change: t1(%ld), t2(%ld)\n",
|
|
||||||
timetest_table[i].name, (long)t1, (long)t2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
From 34c12f76f46ba91ff2a7cd8d2855524844e0cadc Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rob Norris <robn@despairlabs.com>
|
|
||||||
Date: Sun, 14 Jan 2024 13:46:06 +1100
|
|
||||||
Subject: [PATCH 2/2] zfs_setattr: fix atime update
|
|
||||||
|
|
||||||
In db4fc559c I messed up and changed this bit of code to set the inode
|
|
||||||
atime to an uninitialised value, when actually it was just supposed to
|
|
||||||
loading the atime from the inode to be stored in the SA. This changes it
|
|
||||||
to what it should have been.
|
|
||||||
|
|
||||||
Signed-off-by: Rob Norris <robn@despairlabs.com>
|
|
||||||
Sponsored-by: https://despairlabs.com/sponsor/
|
|
||||||
Fixes: #15762
|
|
||||||
---
|
|
||||||
module/os/linux/zfs/zfs_vnops_os.c | 3 +--
|
|
||||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c
|
|
||||||
index 2a766a585b70..b7b89b8afc56 100644
|
|
||||||
--- a/module/os/linux/zfs/zfs_vnops_os.c
|
|
||||||
+++ b/module/os/linux/zfs/zfs_vnops_os.c
|
|
||||||
@@ -2439,9 +2439,8 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr, zidmap_t *mnt_ns)
|
|
||||||
|
|
||||||
if ((mask & ATTR_ATIME) || zp->z_atime_dirty) {
|
|
||||||
zp->z_atime_dirty = B_FALSE;
|
|
||||||
- inode_timespec_t tmp_atime;
|
|
||||||
+ inode_timespec_t tmp_atime = zpl_inode_get_atime(ip);
|
|
||||||
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,
|
|
||||||
&atime, sizeof (atime));
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in new issue