diff --git a/Makefile.in b/Makefile.in index 332efc173292..37c813cd3dbf 100644 --- a/Makefile.in +++ b/Makefile.in @@ -92,6 +92,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/cmd/Makefile.in b/cmd/Makefile.in index ee3f4bef26d8..eb86e279604a 100644 --- a/cmd/Makefile.in +++ b/cmd/Makefile.in @@ -69,6 +69,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/cmd/mount_zfs/Makefile.in b/cmd/mount_zfs/Makefile.in index 73660d21badb..44d07667e00a 100644 --- a/cmd/mount_zfs/Makefile.in +++ b/cmd/mount_zfs/Makefile.in @@ -72,6 +72,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/cmd/sas_switch_id/Makefile.in b/cmd/sas_switch_id/Makefile.in index fb6ea65ec0bb..889da17859c3 100644 --- a/cmd/sas_switch_id/Makefile.in +++ b/cmd/sas_switch_id/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/cmd/zdb/Makefile.in b/cmd/zdb/Makefile.in index da3119592f06..4fd55e5fa904 100644 --- a/cmd/zdb/Makefile.in +++ b/cmd/zdb/Makefile.in @@ -72,6 +72,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/cmd/zfs/Makefile.in b/cmd/zfs/Makefile.in index 55ca80892fcd..0b9b4dcc6808 100644 --- a/cmd/zfs/Makefile.in +++ b/cmd/zfs/Makefile.in @@ -72,6 +72,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/cmd/zinject/Makefile.in b/cmd/zinject/Makefile.in index 5e6f90ecbcc4..8adfaab39086 100644 --- a/cmd/zinject/Makefile.in +++ b/cmd/zinject/Makefile.in @@ -72,6 +72,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/cmd/zpios/Makefile.in b/cmd/zpios/Makefile.in index cf672f1e12d7..c0a84df6bdaa 100644 --- a/cmd/zpios/Makefile.in +++ b/cmd/zpios/Makefile.in @@ -72,6 +72,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/cmd/zpool/Makefile.in b/cmd/zpool/Makefile.in index b915006f4114..127b93690cee 100644 --- a/cmd/zpool/Makefile.in +++ b/cmd/zpool/Makefile.in @@ -72,6 +72,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/cmd/zpool_id/Makefile.in b/cmd/zpool_id/Makefile.in index aadd124133c6..29f83a3ffaa5 100644 --- a/cmd/zpool_id/Makefile.in +++ b/cmd/zpool_id/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/cmd/zpool_layout/Makefile.in b/cmd/zpool_layout/Makefile.in index e1b16431313e..514e88f5ffd2 100644 --- a/cmd/zpool_layout/Makefile.in +++ b/cmd/zpool_layout/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/cmd/ztest/Makefile.in b/cmd/ztest/Makefile.in index e99cc9e85271..dc6549b6c9c7 100644 --- a/cmd/ztest/Makefile.in +++ b/cmd/ztest/Makefile.in @@ -72,6 +72,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/cmd/zvol_id/Makefile.in b/cmd/zvol_id/Makefile.in index d6719fdb6a31..d657c8007472 100644 --- a/cmd/zvol_id/Makefile.in +++ b/cmd/zvol_id/Makefile.in @@ -72,6 +72,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/config/kernel-shrink.m4 b/config/kernel-shrink.m4 new file mode 100644 index 000000000000..ea748c9747e5 --- /dev/null +++ b/config/kernel-shrink.m4 @@ -0,0 +1,64 @@ +dnl # +dnl # 3.1 API change +dnl # The super_block structure now stores a per-filesystem shrinker. +dnl # This interface is preferable because it can be used to specifically +dnl # target only the zfs filesystem for pruning. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SHRINK], [ + AC_MSG_CHECKING([whether super_block has s_shrink]) + ZFS_LINUX_TRY_COMPILE([ + #include + ],[ + int (*shrink)(struct shrinker *, struct shrink_control *sc) + __attribute__ ((unused)) = NULL; + struct super_block sb __attribute__ ((unused)) = { + .s_shrink.shrink = shrink, + .s_shrink.seeks = DEFAULT_SEEKS, + .s_shrink.batch = 0, + }; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SHRINK, 1, [struct super_block has s_shrink]) + + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_NR_CACHED_OBJECTS], [ + AC_MSG_CHECKING([whether sops->nr_cached_objects() exists]) + ZFS_LINUX_TRY_COMPILE([ + #include + ],[ + int (*nr_cached_objects)(struct super_block *) + __attribute__ ((unused)) = NULL; + struct super_operations sops __attribute__ ((unused)) = { + .nr_cached_objects = nr_cached_objects, + }; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NR_CACHED_OBJECTS, 1, + [sops->nr_cached_objects() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_FREE_CACHED_OBJECTS], [ + AC_MSG_CHECKING([whether sops->free_cached_objects() exists]) + ZFS_LINUX_TRY_COMPILE([ + #include + ],[ + void (*free_cached_objects)(struct super_block *, int) + __attribute__ ((unused)) = NULL; + struct super_operations sops __attribute__ ((unused)) = { + .free_cached_objects = free_cached_objects, + }; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_FREE_CACHED_OBJECTS, 1, + [sops->free_cached_objects() exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index 63a3237ec8b7..2afe77e63b45 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -34,12 +34,15 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL_XATTR_HANDLER_SET ZFS_AC_KERNEL_FSYNC ZFS_AC_KERNEL_EVICT_INODE + ZFS_AC_KERNEL_NR_CACHED_OBJECTS + ZFS_AC_KERNEL_FREE_CACHED_OBJECTS ZFS_AC_KERNEL_INSERT_INODE_LOCKED ZFS_AC_KERNEL_D_OBTAIN_ALIAS ZFS_AC_KERNEL_CHECK_DISK_SIZE_CHANGE ZFS_AC_KERNEL_TRUNCATE_SETSIZE ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY ZFS_AC_KERNEL_MOUNT_NODEV + ZFS_AC_KERNEL_SHRINK ZFS_AC_KERNEL_BDI ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER ZFS_AC_KERNEL_SET_NLINK diff --git a/configure b/configure index d6f405bbbd09..f30b1ffcbbf7 100755 --- a/configure +++ b/configure @@ -14774,6 +14774,144 @@ fi + { $as_echo "$as_me:$LINENO: checking whether sops->nr_cached_objects() exists" >&5 +$as_echo_n "checking whether sops->nr_cached_objects() exists... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + int (*nr_cached_objects)(struct super_block *) + __attribute__ ((unused)) = NULL; + struct super_operations sops __attribute__ ((unused)) = { + .nr_cached_objects = nr_cached_objects, + }; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_NR_CACHED_OBJECTS 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + + { $as_echo "$as_me:$LINENO: checking whether sops->free_cached_objects() exists" >&5 +$as_echo_n "checking whether sops->free_cached_objects() exists... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + void (*free_cached_objects)(struct super_block *, int) + __attribute__ ((unused)) = NULL; + struct super_operations sops __attribute__ ((unused)) = { + .free_cached_objects = free_cached_objects, + }; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_FREE_CACHED_OBJECTS 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + { $as_echo "$as_me:$LINENO: checking whether symbol insert_inode_locked is exported" >&5 $as_echo_n "checking whether symbol insert_inode_locked is exported... " >&6; } grep -q -E '[[:space:]]insert_inode_locked[[:space:]]' \ @@ -15107,6 +15245,78 @@ fi + { $as_echo "$as_me:$LINENO: checking whether super_block has s_shrink" >&5 +$as_echo_n "checking whether super_block has s_shrink... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + int (*shrink)(struct shrinker *, struct shrink_control *sc) + __attribute__ ((unused)) = NULL; + struct super_block sb __attribute__ ((unused)) = { + .s_shrink.shrink = shrink, + .s_shrink.seeks = DEFAULT_SEEKS, + .s_shrink.batch = 0, + }; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SHRINK 1 +_ACEOF + + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + { $as_echo "$as_me:$LINENO: checking whether super_block has s_bdi" >&5 $as_echo_n "checking whether super_block has s_bdi... " >&6; } @@ -19611,6 +19821,144 @@ fi + { $as_echo "$as_me:$LINENO: checking whether sops->nr_cached_objects() exists" >&5 +$as_echo_n "checking whether sops->nr_cached_objects() exists... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + int (*nr_cached_objects)(struct super_block *) + __attribute__ ((unused)) = NULL; + struct super_operations sops __attribute__ ((unused)) = { + .nr_cached_objects = nr_cached_objects, + }; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_NR_CACHED_OBJECTS 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + + { $as_echo "$as_me:$LINENO: checking whether sops->free_cached_objects() exists" >&5 +$as_echo_n "checking whether sops->free_cached_objects() exists... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + void (*free_cached_objects)(struct super_block *, int) + __attribute__ ((unused)) = NULL; + struct super_operations sops __attribute__ ((unused)) = { + .free_cached_objects = free_cached_objects, + }; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_FREE_CACHED_OBJECTS 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + { $as_echo "$as_me:$LINENO: checking whether symbol insert_inode_locked is exported" >&5 $as_echo_n "checking whether symbol insert_inode_locked is exported... " >&6; } grep -q -E '[[:space:]]insert_inode_locked[[:space:]]' \ @@ -19944,6 +20292,78 @@ fi + { $as_echo "$as_me:$LINENO: checking whether super_block has s_shrink" >&5 +$as_echo_n "checking whether super_block has s_shrink... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + int (*shrink)(struct shrinker *, struct shrink_control *sc) + __attribute__ ((unused)) = NULL; + struct super_block sb __attribute__ ((unused)) = { + .s_shrink.shrink = shrink, + .s_shrink.seeks = DEFAULT_SEEKS, + .s_shrink.batch = 0, + }; + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SHRINK 1 +_ACEOF + + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + { $as_echo "$as_me:$LINENO: checking whether super_block has s_bdi" >&5 $as_echo_n "checking whether super_block has s_bdi... " >&6; } diff --git a/dracut/90zfs/Makefile.in b/dracut/90zfs/Makefile.in index cc79618127ca..ca1d86063154 100644 --- a/dracut/90zfs/Makefile.in +++ b/dracut/90zfs/Makefile.in @@ -70,6 +70,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/dracut/Makefile.in b/dracut/Makefile.in index 1c6b3e609ef9..f385985d227f 100644 --- a/dracut/Makefile.in +++ b/dracut/Makefile.in @@ -69,6 +69,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/etc/Makefile.in b/etc/Makefile.in index a2e398604dc6..481d0cdd6d8e 100644 --- a/etc/Makefile.in +++ b/etc/Makefile.in @@ -69,6 +69,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/etc/init.d/Makefile.in b/etc/init.d/Makefile.in index 9eb8ae7b4be2..f4d0854850f2 100644 --- a/etc/init.d/Makefile.in +++ b/etc/init.d/Makefile.in @@ -70,6 +70,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/etc/zfs/Makefile.in b/etc/zfs/Makefile.in index 6c81f5d8c96c..b421d59bc925 100644 --- a/etc/zfs/Makefile.in +++ b/etc/zfs/Makefile.in @@ -70,6 +70,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/include/Makefile.in b/include/Makefile.in index f82fdb267b26..18e235722d46 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/include/linux/Makefile.in b/include/linux/Makefile.in index e50b89b9b847..030437b442bc 100644 --- a/include/linux/Makefile.in +++ b/include/linux/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/include/sys/Makefile.in b/include/sys/Makefile.in index b17649b028ca..012ffe9f7ecd 100644 --- a/include/sys/Makefile.in +++ b/include/sys/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/include/sys/arc.h b/include/sys/arc.h index 8f189c62d31d..dd9b128bc1ea 100644 --- a/include/sys/arc.h +++ b/include/sys/arc.h @@ -34,16 +34,27 @@ extern "C" { #include #include #include +#include typedef struct arc_buf_hdr arc_buf_hdr_t; typedef struct arc_buf arc_buf_t; +typedef struct arc_prune arc_prune_t; typedef void arc_done_func_t(zio_t *zio, arc_buf_t *buf, void *private); +typedef void arc_prune_func_t(int64_t bytes, void *private); typedef int arc_evict_func_t(void *private); /* generic arc_done_func_t's which you can use */ arc_done_func_t arc_bcopy_func; arc_done_func_t arc_getbuf_func; +/* generic arc_prune_func_t wrapper for callbacks */ +struct arc_prune { + arc_prune_func_t *p_pfunc; + void *p_private; + list_node_t p_node; + refcount_t p_refcnt; +}; + struct arc_buf { arc_buf_hdr_t *b_hdr; arc_buf_t *b_next; @@ -113,9 +124,13 @@ zio_t *arc_write(zio_t *pio, spa_t *spa, uint64_t txg, arc_done_func_t *ready, arc_done_func_t *done, void *private, int priority, int zio_flags, const zbookmark_t *zb); +arc_prune_t *arc_add_prune_callback(arc_prune_func_t *func, void *private); +void arc_remove_prune_callback(arc_prune_t *p); + void arc_set_callback(arc_buf_t *buf, arc_evict_func_t *func, void *private); int arc_buf_evict(arc_buf_t *buf); +void arc_adjust_meta(int64_t adjustment, boolean_t may_prune); void arc_flush(spa_t *spa); void arc_tempreserve_clear(uint64_t reserve); int arc_tempreserve_space(uint64_t reserve, uint64_t txg); diff --git a/include/sys/fm/Makefile.in b/include/sys/fm/Makefile.in index e3fd84cfdda7..932e5e7329f6 100644 --- a/include/sys/fm/Makefile.in +++ b/include/sys/fm/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/include/sys/fm/fs/Makefile.in b/include/sys/fm/fs/Makefile.in index 40952616b81d..bbcb1c258e50 100644 --- a/include/sys/fm/fs/Makefile.in +++ b/include/sys/fm/fs/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/include/sys/fs/Makefile.in b/include/sys/fs/Makefile.in index db73ab8622cf..da86a6fbc281 100644 --- a/include/sys/fs/Makefile.in +++ b/include/sys/fs/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/include/sys/zfs_vfsops.h b/include/sys/zfs_vfsops.h index 6d4d713cebb0..b7badeed8e58 100644 --- a/include/sys/zfs_vfsops.h +++ b/include/sys/zfs_vfsops.h @@ -67,7 +67,8 @@ typedef struct zfs_sb { boolean_t z_unmounted; /* unmounted */ rrwlock_t z_teardown_lock; krwlock_t z_teardown_inactive_lock; - list_t z_all_znodes; /* all vnodes in the fs */ + list_t z_all_znodes; /* all znodes in the fs */ + uint64_t z_nr_znodes; /* number of znodes in the fs */ kmutex_t z_znodes_lock; /* lock for z_all_znodes */ struct inode *z_ctldir; /* .zfs directory inode */ boolean_t z_show_ctldir; /* expose .zfs in the root dir */ @@ -185,6 +186,8 @@ extern int zfs_get_zplprop(objset_t *os, zfs_prop_t prop, extern int zfs_sb_create(const char *name, zfs_sb_t **zsbp); extern int zfs_sb_setup(zfs_sb_t *zsb, boolean_t mounting); extern void zfs_sb_free(zfs_sb_t *zsb); +extern int zfs_sb_prune(struct super_block *sb, unsigned long nr_to_scan, + int *objects); extern int zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting); extern int zfs_check_global_label(const char *dsname, const char *hexsl); extern boolean_t zfs_is_readonly(zfs_sb_t *zsb); diff --git a/include/sys/zpl.h b/include/sys/zpl.h index 0aacce8bdf43..2195ec9a3d98 100644 --- a/include/sys/zpl.h +++ b/include/sys/zpl.h @@ -48,6 +48,8 @@ extern const struct file_operations zpl_file_operations; extern const struct file_operations zpl_dir_file_operations; /* zpl_super.c */ +extern void zpl_prune_sbs(int64_t bytes_to_scan, void *private); + typedef struct zpl_mount_data { const char *z_osname; /* Dataset name */ void *z_data; /* Mount options string */ diff --git a/lib/Makefile.in b/lib/Makefile.in index 17f84a5482dd..5929cc468246 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -69,6 +69,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libavl/Makefile.in b/lib/libavl/Makefile.in index 55bb04d9f5b7..9a6ea3a7537a 100644 --- a/lib/libavl/Makefile.in +++ b/lib/libavl/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libefi/Makefile.in b/lib/libefi/Makefile.in index 6e4a83b3c09f..7abee8cab28f 100644 --- a/lib/libefi/Makefile.in +++ b/lib/libefi/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libnvpair/Makefile.in b/lib/libnvpair/Makefile.in index 60439aece27e..33d3f3b1d9fc 100644 --- a/lib/libnvpair/Makefile.in +++ b/lib/libnvpair/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libshare/Makefile.in b/lib/libshare/Makefile.in index 94ea82e90ac1..67d23d27967d 100644 --- a/lib/libshare/Makefile.in +++ b/lib/libshare/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libspl/Makefile.in b/lib/libspl/Makefile.in index 194679a93839..db3499a6d1bb 100644 --- a/lib/libspl/Makefile.in +++ b/lib/libspl/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libspl/asm-generic/Makefile.in b/lib/libspl/asm-generic/Makefile.in index a9ffb578c8e5..cae5d5678da8 100644 --- a/lib/libspl/asm-generic/Makefile.in +++ b/lib/libspl/asm-generic/Makefile.in @@ -70,6 +70,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libspl/asm-i386/Makefile.in b/lib/libspl/asm-i386/Makefile.in index ca6573040465..652782e66764 100644 --- a/lib/libspl/asm-i386/Makefile.in +++ b/lib/libspl/asm-i386/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libspl/asm-x86_64/Makefile.in b/lib/libspl/asm-x86_64/Makefile.in index 2db49b35a68e..ad6c870dc06d 100644 --- a/lib/libspl/asm-x86_64/Makefile.in +++ b/lib/libspl/asm-x86_64/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libspl/include/Makefile.in b/lib/libspl/include/Makefile.in index d7a8f52fcefe..419041afa43d 100644 --- a/lib/libspl/include/Makefile.in +++ b/lib/libspl/include/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libspl/include/ia32/Makefile.in b/lib/libspl/include/ia32/Makefile.in index b60892865a9e..c0418ee60ded 100644 --- a/lib/libspl/include/ia32/Makefile.in +++ b/lib/libspl/include/ia32/Makefile.in @@ -69,6 +69,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libspl/include/ia32/sys/Makefile.in b/lib/libspl/include/ia32/sys/Makefile.in index 36629967ef24..86b08fd796c7 100644 --- a/lib/libspl/include/ia32/sys/Makefile.in +++ b/lib/libspl/include/ia32/sys/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libspl/include/rpc/Makefile.in b/lib/libspl/include/rpc/Makefile.in index 68e3c2f12948..92529aecf774 100644 --- a/lib/libspl/include/rpc/Makefile.in +++ b/lib/libspl/include/rpc/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libspl/include/sys/Makefile.in b/lib/libspl/include/sys/Makefile.in index 6851505dd96b..09e1ec95797c 100644 --- a/lib/libspl/include/sys/Makefile.in +++ b/lib/libspl/include/sys/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libspl/include/sys/dktp/Makefile.in b/lib/libspl/include/sys/dktp/Makefile.in index 89c3285e1d48..84961afae1a7 100644 --- a/lib/libspl/include/sys/dktp/Makefile.in +++ b/lib/libspl/include/sys/dktp/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libspl/include/sys/sysevent/Makefile.in b/lib/libspl/include/sys/sysevent/Makefile.in index de9db421b254..5d6a93dbe5cf 100644 --- a/lib/libspl/include/sys/sysevent/Makefile.in +++ b/lib/libspl/include/sys/sysevent/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libspl/include/util/Makefile.in b/lib/libspl/include/util/Makefile.in index d7cd17c15086..068a2f560037 100644 --- a/lib/libspl/include/util/Makefile.in +++ b/lib/libspl/include/util/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libunicode/Makefile.in b/lib/libunicode/Makefile.in index f6c8690cdecc..fbcb32b9998d 100644 --- a/lib/libunicode/Makefile.in +++ b/lib/libunicode/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libuutil/Makefile.in b/lib/libuutil/Makefile.in index d44bba2d6581..6507a7eadb9a 100644 --- a/lib/libuutil/Makefile.in +++ b/lib/libuutil/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libzfs/Makefile.in b/lib/libzfs/Makefile.in index 29642b1ac189..a975a193f29a 100644 --- a/lib/libzfs/Makefile.in +++ b/lib/libzfs/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/lib/libzpool/Makefile.in b/lib/libzpool/Makefile.in index 0e46c1516d7f..5e1fded91ca9 100644 --- a/lib/libzpool/Makefile.in +++ b/lib/libzpool/Makefile.in @@ -71,6 +71,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/man/Makefile.in b/man/Makefile.in index 84c6c1706b69..1ad3c35fdd06 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -69,6 +69,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/man/man8/Makefile.in b/man/man8/Makefile.in index be187c9c03e2..86e691d2ef95 100644 --- a/man/man8/Makefile.in +++ b/man/man8/Makefile.in @@ -69,6 +69,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/module/zfs/arc.c b/module/zfs/arc.c index f71c24844e8b..95d14a9e7511 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -104,6 +104,14 @@ * protected from simultaneous callbacks from arc_buf_evict() * and arc_do_user_evicts(). * + * It as also possible to register a callback which is run when the + * arc_meta_limit is reached and no buffers can be safely evicted. In + * this case the arc user should drop a reference on some arc buffers so + * they can be reclaimed and the arc_meta_limit honored. For example, + * when using the ZPL each dentry holds a references on a znode. These + * dentries must be pruned before the arc buffer holding the znode can + * be safely evicted. + * * Note that the majority of the performance stats are manipulated * with atomic operations. * @@ -120,14 +128,13 @@ #include #include #include -#include #include #include #ifdef _KERNEL #include #include #include -#include +#include #endif #include #include @@ -141,8 +148,8 @@ extern int zfs_write_limit_shift; extern uint64_t zfs_write_limit_max; extern kmutex_t zfs_write_limit_lock; -#define ARC_REDUCE_DNLC_PERCENT 3 -uint_t arc_reduce_dnlc_percent = ARC_REDUCE_DNLC_PERCENT; +/* number of bytes to prune from caches when at arc_meta_limit is reached */ +uint_t arc_meta_prune = 1048576; typedef enum arc_reclaim_strategy { ARC_RECLAIM_AGGR, /* Aggressive reclaim strategy */ @@ -180,7 +187,7 @@ unsigned long zfs_arc_meta_limit = 0; int zfs_arc_grow_retry = 0; int zfs_arc_shrink_shift = 0; int zfs_arc_p_min_shift = 0; -int zfs_arc_reduce_dnlc_percent = 0; +int zfs_arc_meta_prune = 0; /* * Note that buffers can be in one of 6 states: @@ -288,6 +295,7 @@ typedef struct arc_stats { kstat_named_t arcstat_no_grow; kstat_named_t arcstat_tempreserve; kstat_named_t arcstat_loaned_bytes; + kstat_named_t arcstat_prune; kstat_named_t arcstat_meta_used; kstat_named_t arcstat_meta_limit; kstat_named_t arcstat_meta_max; @@ -352,6 +360,7 @@ static arc_stats_t arc_stats = { { "arc_no_grow", KSTAT_DATA_UINT64 }, { "arc_tempreserve", KSTAT_DATA_UINT64 }, { "arc_loaned_bytes", KSTAT_DATA_UINT64 }, + { "arc_prune", KSTAT_DATA_UINT64 }, { "arc_meta_used", KSTAT_DATA_UINT64 }, { "arc_meta_limit", KSTAT_DATA_UINT64 }, { "arc_meta_max", KSTAT_DATA_UINT64 }, @@ -481,6 +490,8 @@ struct arc_buf_hdr { list_node_t b_l2node; }; +static list_t arc_prune_list; +static kmutex_t arc_prune_mtx; static arc_buf_t *arc_eviction_list; static kmutex_t arc_eviction_mtx; static arc_buf_hdr_t arc_eviction_hdr; @@ -1925,6 +1936,48 @@ arc_adjust(void) } } +/* + * Request that arc user drop references so that N bytes can be released + * from the cache. This provides a mechanism to ensure the arc can honor + * the arc_meta_limit and reclaim buffers which are pinned in the cache + * by higher layers. (i.e. the zpl) + */ +static void +arc_do_user_prune(int64_t adjustment) +{ + arc_prune_func_t *func; + void *private; + arc_prune_t *cp, *np; + + mutex_enter(&arc_prune_mtx); + + cp = list_head(&arc_prune_list); + while (cp != NULL) { + func = cp->p_pfunc; + private = cp->p_private; + np = list_next(&arc_prune_list, cp); + refcount_add(&cp->p_refcnt, func); + mutex_exit(&arc_prune_mtx); + + if (func != NULL) + func(adjustment, private); + + mutex_enter(&arc_prune_mtx); + + /* User removed prune callback concurrently with execution */ + if (refcount_remove(&cp->p_refcnt, func) == 0) { + ASSERT(!list_link_active(&cp->p_node)); + refcount_destroy(&cp->p_refcnt); + kmem_free(cp, sizeof (*cp)); + } + + cp = np; + } + + ARCSTAT_BUMP(arcstat_prune); + mutex_exit(&arc_prune_mtx); +} + static void arc_do_user_evicts(void) { @@ -1948,6 +2001,32 @@ arc_do_user_evicts(void) mutex_exit(&arc_eviction_mtx); } +/* + * Evict only meta data objects from the cache leaving the data objects. + * This is only used to enforce the tunable arc_meta_limit, if we are + * unable to evict enough buffers notify the user via the prune callback. + */ +void +arc_adjust_meta(int64_t adjustment, boolean_t may_prune) +{ + int64_t delta; + + if (adjustment > 0 && arc_mru->arcs_lsize[ARC_BUFC_METADATA] > 0) { + delta = MIN(arc_mru->arcs_lsize[ARC_BUFC_METADATA], adjustment); + arc_evict(arc_mru, 0, delta, FALSE, ARC_BUFC_METADATA); + adjustment -= delta; + } + + if (adjustment > 0 && arc_mfu->arcs_lsize[ARC_BUFC_METADATA] > 0) { + delta = MIN(arc_mfu->arcs_lsize[ARC_BUFC_METADATA], adjustment); + arc_evict(arc_mfu, 0, delta, FALSE, ARC_BUFC_METADATA); + adjustment -= delta; + } + + if (may_prune && (adjustment > 0) && (arc_meta_used > arc_meta_limit)) + arc_do_user_prune(arc_meta_prune); +} + /* * Flush all *evictable* data from the cache for the given spa. * NOTE: this will not touch "active" (i.e. referenced) data. @@ -2085,24 +2164,6 @@ arc_kmem_reap_now(arc_reclaim_strategy_t strat) kmem_cache_t *prev_data_cache = NULL; extern kmem_cache_t *zio_buf_cache[]; extern kmem_cache_t *zio_data_buf_cache[]; -#ifdef _KERNEL - int retry = 0; - - while ((arc_meta_used >= arc_meta_limit) && (retry < 10)) { - /* - * We are exceeding our meta-data cache limit. - * Purge some DNLC entries to release holds on meta-data. - */ - dnlc_reduce_cache((void *)(uintptr_t)arc_reduce_dnlc_percent); - retry++; - } -#if defined(__i386) - /* - * Reclaim unused memory from all kmem caches. - */ - kmem_reap(); -#endif -#endif /* * An aggressive reclamation will shrink the cache size as well as @@ -2121,6 +2182,7 @@ arc_kmem_reap_now(arc_reclaim_strategy_t strat) kmem_cache_reap_now(zio_data_buf_cache[i]); } } + kmem_cache_reap_now(buf_cache); kmem_cache_reap_now(hdr_cache); } @@ -2131,6 +2193,7 @@ arc_reclaim_thread(void) clock_t growtime = 0; arc_reclaim_strategy_t last_reclaim = ARC_RECLAIM_CONS; callb_cpr_t cpr; + int64_t prune; CALLB_CPR_INIT(&cpr, &arc_reclaim_thr_lock, callb_generic_cpr, FTAG); @@ -2160,9 +2223,14 @@ arc_reclaim_thread(void) arc_no_grow = FALSE; } - /* Keep meta data usage within limits */ - if (arc_meta_used >= arc_meta_limit) - arc_kmem_reap_now(ARC_RECLAIM_CONS); + /* + * Keep meta data usage within limits, arc_shrink() is not + * used to avoid collapsing the arc_c value when only the + * arc_meta_limit is being exceeded. + */ + prune = (int64_t)arc_meta_used - (int64_t)arc_meta_limit; + if (prune > 0) + arc_adjust_meta(prune, B_TRUE); arc_adjust(); @@ -2399,16 +2467,27 @@ arc_get_data_buf(arc_buf_t *buf) state = (arc_mru->arcs_lsize[type] >= size && mfu_space > arc_mfu->arcs_size) ? arc_mru : arc_mfu; } + if ((buf->b_data = arc_evict(state, 0, size, TRUE, type)) == NULL) { if (type == ARC_BUFC_METADATA) { buf->b_data = zio_buf_alloc(size); arc_space_consume(size, ARC_SPACE_DATA); + + /* + * If we are unable to recycle an existing meta buffer + * signal the reclaim thread. It will notify users + * via the prune callback to drop references. The + * prune callback in run in the context of the reclaim + * thread to avoid deadlocking on the hash_lock. + */ + cv_signal(&arc_reclaim_thr_cv); } else { ASSERT(type == ARC_BUFC_DATA); buf->b_data = zio_data_buf_alloc(size); ARCSTAT_INCR(arcstat_data_size, size); atomic_add_64(&arc_size, size); } + ARCSTAT_BUMP(arcstat_recycle_miss); } ASSERT(buf->b_data != NULL); @@ -3021,6 +3100,37 @@ arc_read_nolock(zio_t *pio, spa_t *spa, const blkptr_t *bp, return (0); } +arc_prune_t * +arc_add_prune_callback(arc_prune_func_t *func, void *private) +{ + arc_prune_t *p; + + p = kmem_alloc(sizeof(*p), KM_SLEEP); + p->p_pfunc = func; + p->p_private = private; + list_link_init(&p->p_node); + refcount_create(&p->p_refcnt); + + mutex_enter(&arc_prune_mtx); + refcount_add(&p->p_refcnt, &arc_prune_list); + list_insert_head(&arc_prune_list, p); + mutex_exit(&arc_prune_mtx); + + return (p); +} + +void +arc_remove_prune_callback(arc_prune_t *p) +{ + mutex_enter(&arc_prune_mtx); + list_remove(&arc_prune_list, p); + if (refcount_remove(&p->p_refcnt, &arc_prune_list) == 0) { + refcount_destroy(&p->p_refcnt); + kmem_free(p, sizeof (*p)); + } + mutex_exit(&arc_prune_mtx); +} + void arc_set_callback(arc_buf_t *buf, arc_evict_func_t *func, void *private) { @@ -3598,8 +3708,8 @@ arc_init(void) if (zfs_arc_p_min_shift > 0) arc_p_min_shift = zfs_arc_p_min_shift; - if (zfs_arc_reduce_dnlc_percent > 0) - arc_reduce_dnlc_percent = zfs_arc_reduce_dnlc_percent; + if (zfs_arc_meta_prune > 0) + arc_meta_prune = zfs_arc_meta_prune; /* if kmem_flags are set, lets try to use less memory */ if (kmem_debugging()) @@ -3646,7 +3756,10 @@ arc_init(void) buf_init(); arc_thread_exit = 0; + list_create(&arc_prune_list, sizeof (arc_prune_t), + offsetof(arc_prune_t, p_node)); arc_eviction_list = NULL; + mutex_init(&arc_prune_mtx, NULL, MUTEX_DEFAULT, NULL); mutex_init(&arc_eviction_mtx, NULL, MUTEX_DEFAULT, NULL); bzero(&arc_eviction_hdr, sizeof (arc_buf_hdr_t)); @@ -3674,6 +3787,8 @@ arc_init(void) void arc_fini(void) { + arc_prune_t *p; + mutex_enter(&arc_reclaim_thr_lock); #ifdef _KERNEL spl_unregister_shrinker(&arc_shrinker); @@ -3693,6 +3808,17 @@ arc_fini(void) arc_ksp = NULL; } + mutex_enter(&arc_prune_mtx); + while ((p = list_head(&arc_prune_list)) != NULL) { + list_remove(&arc_prune_list, p); + refcount_remove(&p->p_refcnt, &arc_prune_list); + refcount_destroy(&p->p_refcnt); + kmem_free(p, sizeof (*p)); + } + mutex_exit(&arc_prune_mtx); + + list_destroy(&arc_prune_list); + mutex_destroy(&arc_prune_mtx); mutex_destroy(&arc_eviction_mtx); mutex_destroy(&arc_reclaim_thr_lock); cv_destroy(&arc_reclaim_thr_cv); @@ -4774,6 +4900,8 @@ l2arc_stop(void) EXPORT_SYMBOL(arc_read); EXPORT_SYMBOL(arc_buf_remove_ref); EXPORT_SYMBOL(arc_getbuf_func); +EXPORT_SYMBOL(arc_add_prune_callback); +EXPORT_SYMBOL(arc_remove_prune_callback); module_param(zfs_arc_min, ulong, 0444); MODULE_PARM_DESC(zfs_arc_min, "Min arc size"); @@ -4784,8 +4912,8 @@ MODULE_PARM_DESC(zfs_arc_max, "Max arc size"); module_param(zfs_arc_meta_limit, ulong, 0444); MODULE_PARM_DESC(zfs_arc_meta_limit, "Meta limit for arc size"); -module_param(zfs_arc_reduce_dnlc_percent, int, 0444); -MODULE_PARM_DESC(zfs_arc_reduce_dnlc_percent, "Meta reclaim percentage"); +module_param(zfs_arc_meta_prune, int, 0444); +MODULE_PARM_DESC(zfs_arc_meta_prune, "Bytes of meta data to prune"); module_param(zfs_arc_grow_retry, int, 0444); MODULE_PARM_DESC(zfs_arc_grow_retry, "Seconds before growing arc size"); diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index a0726e117eae..fb319a547a93 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -986,6 +986,26 @@ zfs_root(zfs_sb_t *zsb, struct inode **ipp) } EXPORT_SYMBOL(zfs_root); +#ifdef HAVE_SHRINK +int +zfs_sb_prune(struct super_block *sb, unsigned long nr_to_scan, int *objects) +{ + zfs_sb_t *zsb = sb->s_fs_info; + struct shrinker *shrinker = &sb->s_shrink; + struct shrink_control sc = { + .nr_to_scan = nr_to_scan, + .gfp_mask = GFP_KERNEL, + }; + + ZFS_ENTER(zsb); + *objects = (*shrinker->shrink)(shrinker, &sc); + ZFS_EXIT(zsb); + + return (0); +} +EXPORT_SYMBOL(zfs_sb_prune); +#endif /* HAVE_SHRINK */ + /* * Teardown the zfs_sb_t::z_os. * @@ -1533,6 +1553,7 @@ zfs_init(void) zfs_znode_init(); dmu_objset_register_type(DMU_OST_ZFS, zfs_space_delta_cb); register_filesystem(&zpl_fs_type); + (void) arc_add_prune_callback(zpl_prune_sbs, NULL); } void diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index a35e3b5f2c78..709ae74f8f5c 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -269,6 +269,7 @@ zfs_inode_destroy(struct inode *ip) mutex_enter(&zsb->z_znodes_lock); list_remove(&zsb->z_all_znodes, zp); + zsb->z_nr_znodes--; mutex_exit(&zsb->z_znodes_lock); if (zp->z_acl_cached) { @@ -401,6 +402,7 @@ zfs_znode_alloc(zfs_sb_t *zsb, dmu_buf_t *db, int blksz, mutex_enter(&zsb->z_znodes_lock); list_insert_tail(&zsb->z_all_znodes, zp); + zsb->z_nr_znodes++; membar_producer(); mutex_exit(&zsb->z_znodes_lock); diff --git a/module/zfs/zpl_super.c b/module/zfs/zpl_super.c index 650e9c0d3791..3abb26a9e418 100644 --- a/module/zfs/zpl_super.c +++ b/module/zfs/zpl_super.c @@ -199,34 +199,120 @@ zpl_kill_sb(struct super_block *sb) kill_anon_super(sb); } +#ifdef HAVE_SHRINK +/* + * Linux 3.1 - 3.x API + * + * The Linux 3.1 API introduced per-sb cache shrinkers to replace the + * global ones. This allows us a mechanism to cleanly target a specific + * zfs file system when the dnode and inode caches grow too large. + * + * In addition, the 3.0 kernel added the iterate_supers_type() helper + * function which is used to safely walk all of the zfs file systems. + */ +static void +zpl_prune_sb(struct super_block *sb, void *arg) +{ + int objects = 0; + int error; + + error = -zfs_sb_prune(sb, *(unsigned long *)arg, &objects); + ASSERT3S(error, <=, 0); + + return; +} + +void +zpl_prune_sbs(int64_t bytes_to_scan, void *private) +{ + unsigned long nr_to_scan = (bytes_to_scan / sizeof(znode_t)); + + iterate_supers_type(&zpl_fs_type, zpl_prune_sb, &nr_to_scan); + kmem_reap(); +} +#else +/* + * Linux 2.6.x - 3.0 API + * + * These are best effort interfaces are provided by the SPL to induce + * the Linux VM subsystem to reclaim a fraction of the both dnode and + * inode caches. Ideally, we want to just target the zfs file systems + * however our only option is to reclaim from them all. + */ +void +zpl_prune_sbs(int64_t bytes_to_scan, void *private) +{ + unsigned long nr_to_scan = (bytes_to_scan / sizeof(znode_t)); + + shrink_dcache_memory(nr_to_scan, GFP_KERNEL); + shrink_icache_memory(nr_to_scan, GFP_KERNEL); + kmem_reap(); +} +#endif /* HAVE_SHRINK */ + +#ifdef HAVE_NR_CACHED_OBJECTS +static int +zpl_nr_cached_objects(struct super_block *sb) +{ + zfs_sb_t *zsb = sb->s_fs_info; + int nr; + + mutex_enter(&zsb->z_znodes_lock); + nr = zsb->z_nr_znodes; + mutex_exit(&zsb->z_znodes_lock); + + return (nr); +} +#endif /* HAVE_NR_CACHED_OBJECTS */ + +#ifdef HAVE_FREE_CACHED_OBJECTS +/* + * Attempt to evict some meta data from the cache. The ARC operates in + * terms of bytes while the Linux VFS uses objects. Now because this is + * just a best effort eviction and the exact values aren't critical so we + * extrapolate from an object count to a byte size using the znode_t size. + */ +static void +zpl_free_cached_objects(struct super_block *sb, int nr_to_scan) +{ + arc_adjust_meta(nr_to_scan * sizeof(znode_t), B_FALSE); +} +#endif /* HAVE_FREE_CACHED_OBJECTS */ + const struct super_operations zpl_super_operations = { - .alloc_inode = zpl_inode_alloc, - .destroy_inode = zpl_inode_destroy, - .dirty_inode = NULL, - .write_inode = NULL, - .drop_inode = NULL, + .alloc_inode = zpl_inode_alloc, + .destroy_inode = zpl_inode_destroy, + .dirty_inode = NULL, + .write_inode = NULL, + .drop_inode = NULL, #ifdef HAVE_EVICT_INODE - .evict_inode = zpl_evict_inode, + .evict_inode = zpl_evict_inode, #else - .clear_inode = zpl_clear_inode, - .delete_inode = zpl_inode_delete, + .clear_inode = zpl_clear_inode, + .delete_inode = zpl_inode_delete, #endif /* HAVE_EVICT_INODE */ - .put_super = zpl_put_super, - .write_super = NULL, - .sync_fs = zpl_sync_fs, - .statfs = zpl_statfs, - .remount_fs = zpl_remount_fs, - .show_options = zpl_show_options, - .show_stats = NULL, + .put_super = zpl_put_super, + .write_super = NULL, + .sync_fs = zpl_sync_fs, + .statfs = zpl_statfs, + .remount_fs = zpl_remount_fs, + .show_options = zpl_show_options, + .show_stats = NULL, +#ifdef HAVE_NR_CACHED_OBJECTS + .nr_cached_objects = zpl_nr_cached_objects, +#endif /* HAVE_NR_CACHED_OBJECTS */ +#ifdef HAVE_FREE_CACHED_OBJECTS + .free_cached_objects = zpl_free_cached_objects, +#endif /* HAVE_FREE_CACHED_OBJECTS */ }; struct file_system_type zpl_fs_type = { - .owner = THIS_MODULE, - .name = ZFS_DRIVER, + .owner = THIS_MODULE, + .name = ZFS_DRIVER, #ifdef HAVE_MOUNT_NODEV - .mount = zpl_mount, + .mount = zpl_mount, #else - .get_sb = zpl_get_sb, + .get_sb = zpl_get_sb, #endif /* HAVE_MOUNT_NODEV */ - .kill_sb = zpl_kill_sb, + .kill_sb = zpl_kill_sb, }; diff --git a/scripts/Makefile.in b/scripts/Makefile.in index 5115a9e0b344..4fdc85b676a9 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -70,6 +70,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/scripts/zpios-profile/Makefile.in b/scripts/zpios-profile/Makefile.in index 1c59d7475d7e..339062111577 100644 --- a/scripts/zpios-profile/Makefile.in +++ b/scripts/zpios-profile/Makefile.in @@ -70,6 +70,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/scripts/zpios-test/Makefile.in b/scripts/zpios-test/Makefile.in index fb1114530a79..1adbef8cf89f 100644 --- a/scripts/zpios-test/Makefile.in +++ b/scripts/zpios-test/Makefile.in @@ -70,6 +70,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/scripts/zpool-config/Makefile.in b/scripts/zpool-config/Makefile.in index 2c4fcb976855..c78e79667b4f 100644 --- a/scripts/zpool-config/Makefile.in +++ b/scripts/zpool-config/Makefile.in @@ -70,6 +70,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/scripts/zpool-layout/Makefile.in b/scripts/zpool-layout/Makefile.in index bebd47b8feae..59034e069af9 100644 --- a/scripts/zpool-layout/Makefile.in +++ b/scripts/zpool-layout/Makefile.in @@ -70,6 +70,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/udev/Makefile.in b/udev/Makefile.in index 856d11aaf4f1..6232f65dbbd0 100644 --- a/udev/Makefile.in +++ b/udev/Makefile.in @@ -69,6 +69,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/udev/rules.d/Makefile.in b/udev/rules.d/Makefile.in index 37eb4c732eac..f9a72cfb63cb 100644 --- a/udev/rules.d/Makefile.in +++ b/udev/rules.d/Makefile.in @@ -70,6 +70,7 @@ am__aclocal_m4_deps = \ $(top_srcdir)/config/kernel-rq-is_sync.m4 \ $(top_srcdir)/config/kernel-security-inode-init.m4 \ $(top_srcdir)/config/kernel-set-nlink.m4 \ + $(top_srcdir)/config/kernel-shrink.m4 \ $(top_srcdir)/config/kernel-truncate-setsize.m4 \ $(top_srcdir)/config/kernel-xattr-handler.m4 \ $(top_srcdir)/config/kernel.m4 \ diff --git a/zfs_config.h.in b/zfs_config.h.in index e0f746704b99..b53ca52d75a6 100644 --- a/zfs_config.h.in +++ b/zfs_config.h.in @@ -90,6 +90,9 @@ /* kernel defines fmode_t */ #undef HAVE_FMODE_T +/* sops->free_cached_objects() exists */ +#undef HAVE_FREE_CACHED_OBJECTS + /* fops->fsync() with range */ #undef HAVE_FSYNC_RANGE @@ -141,6 +144,9 @@ /* mount_nodev() is available */ #undef HAVE_MOUNT_NODEV +/* sops->nr_cached_objects() exists */ +#undef HAVE_NR_CACHED_OBJECTS + /* open_bdev_exclusive() is available */ #undef HAVE_OPEN_BDEV_EXCLUSIVE @@ -156,6 +162,9 @@ /* set_nlink() is available */ #undef HAVE_SET_NLINK +/* struct super_block has s_shrink */ +#undef HAVE_SHRINK + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H