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
(cherry picked from commit 18a9185165
)
This commit is contained in:
parent
e5f191d760
commit
72bf91dfdb
|
@ -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_DEFUN([ZFS_AC_KERNEL_SUPER_BLOCK_S_SHRINK], [
|
||||||
AC_MSG_CHECKING([whether super_block has s_shrink])
|
AC_MSG_CHECKING([whether super_block has s_shrink])
|
||||||
ZFS_LINUX_TEST_RESULT([super_block_s_shrink], [
|
ZFS_LINUX_TEST_RESULT([super_block_s_shrink], [
|
||||||
AC_MSG_RESULT(yes)
|
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], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_SHRINKER], [
|
||||||
ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_SHRINK
|
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_SHRINK_CONTROL_HAS_NID
|
||||||
ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK
|
ZFS_AC_KERNEL_SRC_SHRINKER_CALLBACK
|
||||||
ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT
|
ZFS_AC_KERNEL_SRC_SHRINK_CONTROL_STRUCT
|
||||||
|
|
|
@ -1238,12 +1238,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
|
* 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.
|
* 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
|
int
|
||||||
zfs_prune(struct super_block *sb, unsigned long nr_to_scan, int *objects)
|
zfs_prune(struct super_block *sb, unsigned long nr_to_scan, int *objects)
|
||||||
{
|
{
|
||||||
zfsvfs_t *zfsvfs = sb->s_fs_info;
|
zfsvfs_t *zfsvfs = sb->s_fs_info;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
struct shrinker *shrinker = &sb->s_shrink;
|
struct shrinker *shrinker = S_SHRINK(sb);
|
||||||
struct shrink_control sc = {
|
struct shrink_control sc = {
|
||||||
.nr_to_scan = nr_to_scan,
|
.nr_to_scan = nr_to_scan,
|
||||||
.gfp_mask = GFP_KERNEL,
|
.gfp_mask = GFP_KERNEL,
|
||||||
|
@ -1254,7 +1260,7 @@ zfs_prune(struct super_block *sb, unsigned long nr_to_scan, int *objects)
|
||||||
#if defined(HAVE_SPLIT_SHRINKER_CALLBACK) && \
|
#if defined(HAVE_SPLIT_SHRINKER_CALLBACK) && \
|
||||||
defined(SHRINK_CONTROL_HAS_NID) && \
|
defined(SHRINK_CONTROL_HAS_NID) && \
|
||||||
defined(SHRINKER_NUMA_AWARE)
|
defined(SHRINKER_NUMA_AWARE)
|
||||||
if (sb->s_shrink.flags & SHRINKER_NUMA_AWARE) {
|
if (shrinker->flags & SHRINKER_NUMA_AWARE) {
|
||||||
*objects = 0;
|
*objects = 0;
|
||||||
for_each_online_node(sc.nid) {
|
for_each_online_node(sc.nid) {
|
||||||
*objects += (*shrinker->scan_objects)(shrinker, &sc);
|
*objects += (*shrinker->scan_objects)(shrinker, &sc);
|
||||||
|
|
Loading…
Reference in New Issue