Linux compat 2.6.37, invalidate_inodes()

In the 2.6.37 kernel the function invalidate_inodes() is no longer
exported for use by modules.  This memory management functionality
is needed to invalidate the inodes attached to a super block without
unmounting the filesystem.

Because this function still exists in the kernel and the prototype
is available is a common header all we strictly need is the symbol
address.  The address is obtained using spl_kallsyms_lookup_name()
and assigned to the variable invalidate_inodes_fn.  Then a #define
is used to replace all instances of invalidate_inodes() with a
call to the acquired address.  All the complexity is hidden behind
HAVE_INVALIDATE_INODES and invalidate_inodes() can be used as usual.

Long term we should try to get this, or another, interface made
available to modules again.
This commit is contained in:
Brian Behlendorf 2011-02-23 12:25:45 -08:00
parent bf665d4075
commit 914b063133
5 changed files with 128 additions and 0 deletions

View File

@ -74,6 +74,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
SPL_AC_KVASPRINTF SPL_AC_KVASPRINTF
SPL_AC_3ARGS_FILE_FSYNC SPL_AC_3ARGS_FILE_FSYNC
SPL_AC_EXPORTED_RWSEM_IS_LOCKED SPL_AC_EXPORTED_RWSEM_IS_LOCKED
SPL_AC_KERNEL_INVALIDATE_INODES
]) ])
AC_DEFUN([SPL_AC_MODULE_SYMVERS], [ AC_DEFUN([SPL_AC_MODULE_SYMVERS], [
@ -1685,3 +1686,18 @@ AC_DEFUN([SPL_AC_EXPORTED_RWSEM_IS_LOCKED], [
[rwsem_is_locked() acquires sem->wait_lock])], [rwsem_is_locked() acquires sem->wait_lock])],
[]) [])
]) ])
dnl #
dnl # 2.6.37 API compat,
dnl # The function invalidate_inodes() is no longer exported by the kernel.
dnl # The prototype however is still available which means it is safe
dnl # to acquire the symbol's address using spl_kallsyms_lookup_name().
dnl #
AC_DEFUN([SPL_AC_KERNEL_INVALIDATE_INODES], [
SPL_CHECK_SYMBOL_EXPORT(
[invalidate_inodes],
[],
[AC_DEFINE(HAVE_INVALIDATE_INODES, 1,
[invalidate_inodes() is available])],
[])
])

82
configure vendored
View File

@ -15334,6 +15334,47 @@ _ACEOF
fi fi
{ $as_echo "$as_me:$LINENO: checking whether symbol invalidate_inodes is exported" >&5
$as_echo_n "checking whether symbol invalidate_inodes is exported... " >&6; }
grep -q -E '[[:space:]]invalidate_inodes[[:space:]]' \
$LINUX_OBJ/Module*.symvers 2>/dev/null
rc=$?
if test $rc -ne 0; then
export=0
for file in ; do
grep -q -E "EXPORT_SYMBOL.*(invalidate_inodes)" \
"$LINUX_OBJ/$file" 2>/dev/null
rc=$?
if test $rc -eq 0; then
export=1
break;
fi
done
if test $export -eq 0; then
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
else
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define HAVE_INVALIDATE_INODES 1
_ACEOF
fi
else
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define HAVE_INVALIDATE_INODES 1
_ACEOF
fi
;; ;;
user) user)
@ -19029,6 +19070,47 @@ _ACEOF
{ $as_echo "$as_me:$LINENO: checking whether symbol invalidate_inodes is exported" >&5
$as_echo_n "checking whether symbol invalidate_inodes is exported... " >&6; }
grep -q -E '[[:space:]]invalidate_inodes[[:space:]]' \
$LINUX_OBJ/Module*.symvers 2>/dev/null
rc=$?
if test $rc -ne 0; then
export=0
for file in ; do
grep -q -E "EXPORT_SYMBOL.*(invalidate_inodes)" \
"$LINUX_OBJ/$file" 2>/dev/null
rc=$?
if test $rc -eq 0; then
export=1
break;
fi
done
if test $export -eq 0; then
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
else
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define HAVE_INVALIDATE_INODES 1
_ACEOF
fi
else
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define HAVE_INVALIDATE_INODES 1
_ACEOF
fi
if test "x$AWK" != xgawk; then if test "x$AWK" != xgawk; then

View File

@ -26,6 +26,7 @@
#define _SPL_MM_COMPAT_H #define _SPL_MM_COMPAT_H
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/fs.h>
/* /*
* Linux 2.6.31 API Change. * Linux 2.6.31 API Change.
@ -43,4 +44,16 @@
#define high_wmark_pages(z) (z->pages_high) #define high_wmark_pages(z) (z->pages_high)
#endif #endif
/*
* 2.6.37 API compat,
* The function invalidate_inodes() is no longer exported by the kernel.
* The prototype however is still available which means it is safe
* to acquire the symbol's address using spl_kallsyms_lookup_name().
*/
#ifndef HAVE_INVALIDATE_INODES
typedef int (*invalidate_inodes_t)(struct super_block *sb);
extern invalidate_inodes_t invalidate_inodes_fn;
#define invalidate_inodes(sb) invalidate_inodes_fn(sb)
#endif /* HAVE_INVALIDATE_INODES */
#endif /* SPL_MM_COMPAT_H */ #endif /* SPL_MM_COMPAT_H */

View File

@ -180,6 +180,11 @@ spl_global_page_state(spl_zone_stat_item_t item)
#endif /* NEED_GET_ZONE_COUNTS */ #endif /* NEED_GET_ZONE_COUNTS */
EXPORT_SYMBOL(spl_global_page_state); EXPORT_SYMBOL(spl_global_page_state);
#ifndef HAVE_INVALIDATE_INODES
invalidate_inodes_t invalidate_inodes_fn = SYMBOL_POISON;
EXPORT_SYMBOL(invalidate_inodes_fn);
#endif /* HAVE_INVALIDATE_INODES */
pgcnt_t pgcnt_t
spl_kmem_availrmem(void) spl_kmem_availrmem(void)
{ {
@ -2089,6 +2094,15 @@ spl_kmem_init_kallsyms_lookup(void)
*/ */
spl_kmem_init_globals(); spl_kmem_init_globals();
#ifndef HAVE_INVALIDATE_INODES
invalidate_inodes_fn = (invalidate_inodes_t)
spl_kallsyms_lookup_name("invalidate_inodes");
if (!invalidate_inodes_fn) {
printk(KERN_ERR "Error: Unknown symbol invalidate_inodes\n");
return -EFAULT;
}
#endif /* HAVE_INVALIDATE_INODES */
return 0; return 0;
} }

View File

@ -102,6 +102,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */ /* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H #undef HAVE_INTTYPES_H
/* invalidate_inodes() is available */
#undef HAVE_INVALIDATE_INODES
/* kallsyms_lookup_name() is available */ /* kallsyms_lookup_name() is available */
#undef HAVE_KALLSYMS_LOOKUP_NAME #undef HAVE_KALLSYMS_LOOKUP_NAME