]> granicus.if.org Git - spl/commitdiff
Linux compat 2.6.37, invalidate_inodes()
authorBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 23 Feb 2011 20:25:45 +0000 (12:25 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 23 Feb 2011 20:44:32 +0000 (12:44 -0800)
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.

config/spl-build.m4
configure
include/linux/mm_compat.h
module/spl/spl-kmem.c
spl_config.h.in

index d8eadb7e98c20c50d5d528ca8686a5083ba68e12..2356f209f2b296b59297136a564aaa7fc3db528b 100644 (file)
@@ -74,6 +74,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
        SPL_AC_KVASPRINTF
        SPL_AC_3ARGS_FILE_FSYNC
        SPL_AC_EXPORTED_RWSEM_IS_LOCKED
+       SPL_AC_KERNEL_INVALIDATE_INODES
 ])
 
 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])],
                [])
 ])
+
+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])],
+               [])
+])
index c3b08440efee4ae89087945736256b68ebe5f672..535ca2e7d364174dd80d8fddb62ade59df2b2452 100755 (executable)
--- a/configure
+++ b/configure
@@ -15334,6 +15334,47 @@ _ACEOF
        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)
 
@@ -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
index 57f83dcc9f5d8ba90c161e8244f3ea5cdddb0201..5c5198b90fdea03a2405f3abc12c4b8c8b375168 100644 (file)
@@ -26,6 +26,7 @@
 #define _SPL_MM_COMPAT_H
 
 #include <linux/mm.h>
+#include <linux/fs.h>
 
 /*
  * Linux 2.6.31 API Change.
 #define high_wmark_pages(z)    (z->pages_high)
 #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 */
index 1a9c1fe96f720014eb516f450337d6abc93bf84b..100d674e57abfd8d36c252ad4f1b0602b528fc00 100644 (file)
@@ -180,6 +180,11 @@ spl_global_page_state(spl_zone_stat_item_t item)
 #endif /* NEED_GET_ZONE_COUNTS */
 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
 spl_kmem_availrmem(void)
 {
@@ -2089,6 +2094,15 @@ spl_kmem_init_kallsyms_lookup(void)
         */
        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;
 }
 
index 7863f7b3c51e176ae15ffd244c3e6fc70e72d2e2..a587841191f8e7feca79519ede9fcc7ccb750a0b 100644 (file)
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
+/* invalidate_inodes() is available */
+#undef HAVE_INVALIDATE_INODES
+
 /* kallsyms_lookup_name() is available */
 #undef HAVE_KALLSYMS_LOOKUP_NAME