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. Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <robn@despairlabs.com> Sponsored-by: https://github.com/sponsors/robn Closes #15681
This commit is contained in:
parent
db4fc559cc
commit
1d324aceef
|
@ -19,14 +19,46 @@ 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])
|
||||
],[
|
||||
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()])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 3.12 API change
|
||||
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue