SPL_AC_KERNEL_2ARGS_INVALIDATE_INODES
SPL_AC_SHRINK_DCACHE_MEMORY
SPL_AC_SHRINK_ICACHE_MEMORY
- SPL_AC_KERN_PATH_PARENT
+ SPL_AC_KERN_PATH_PARENT_HEADER
+ SPL_AC_KERN_PATH_PARENT_SYMBOL
SPL_AC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE
SPL_AC_SHRINK_CONTROL_STRUCT
])
fi
])
+dnl #
+dnl # SPL_CHECK_SYMBOL_HEADER
+dnl # check if a symbol prototype is defined in listed headers.
+dnl #
+AC_DEFUN([SPL_CHECK_SYMBOL_HEADER], [
+ AC_MSG_CHECKING([whether symbol $1 exists in header])
+ header=0
+ for file in $3; do
+ grep -q "$2" "$LINUX/$file" 2>/dev/null
+ rc=$?
+ if test $rc -eq 0; then
+ header=1
+ break;
+ fi
+ done
+ if test $header -eq 0; then
+ AC_MSG_RESULT([no])
+ $5
+ else
+ AC_MSG_RESULT([yes])
+ $4
+ fi
+])
+
dnl #
dnl # SPL_CHECK_HEADER
dnl # check whether header exists and define HAVE_$2_HEADER
dnl # offered is that of LOOKUP_PARENT. The spl already always passed
dnl # this flag so dropping the flag does not impact us.
dnl #
-AC_DEFUN([SPL_AC_KERN_PATH_PARENT], [
+AC_DEFUN([SPL_AC_KERN_PATH_PARENT_HEADER], [
+ SPL_CHECK_SYMBOL_HEADER(
+ [kern_path_parent],
+ [int kern_path_parent(const char \*, struct nameidata \*)],
+ [include/linux/namei.h],
+ [AC_DEFINE(HAVE_KERN_PATH_PARENT_HEADER, 1,
+ [kern_path_parent() is available])],
+ [])
+])
+
+dnl #
+dnl # 3.1 API compat,
+dnl # The kern_path_parent() symbol is no longer exported by the kernel.
+dnl # However, it remains the prefered interface and since we still have
+dnl # access to the prototype we dynamically lookup the required address.
+dnl #
+AC_DEFUN([SPL_AC_KERN_PATH_PARENT_SYMBOL], [
SPL_CHECK_SYMBOL_EXPORT(
[kern_path_parent],
[fs/namei.c],
- [AC_DEFINE(HAVE_KERN_PATH_PARENT, 1,
+ [AC_DEFINE(HAVE_KERN_PATH_PARENT_SYMBOL, 1,
[kern_path_parent() is available])],
[])
])
+
+ { $as_echo "$as_me:$LINENO: checking whether symbol kern_path_parent exists in header" >&5
+$as_echo_n "checking whether symbol kern_path_parent exists in header... " >&6; }
+ header=0
+ for file in include/linux/namei.h; do
+ grep -q "int kern_path_parent(const char \*, struct nameidata \*)" "$LINUX/$file" 2>/dev/null
+ rc=$?
+ if test $rc -eq 0; then
+ header=1
+ break;
+ fi
+ done
+ if test $header -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_KERN_PATH_PARENT_HEADER 1
+_ACEOF
+
+ fi
+
+
+
{ $as_echo "$as_me:$LINENO: checking whether symbol kern_path_parent is exported" >&5
$as_echo_n "checking whether symbol kern_path_parent is exported... " >&6; }
grep -q -E '[[:space:]]kern_path_parent[[:space:]]' \
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
-#define HAVE_KERN_PATH_PARENT 1
+#define HAVE_KERN_PATH_PARENT_SYMBOL 1
_ACEOF
fi
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
-#define HAVE_KERN_PATH_PARENT 1
+#define HAVE_KERN_PATH_PARENT_SYMBOL 1
_ACEOF
fi
+
+ { $as_echo "$as_me:$LINENO: checking whether symbol kern_path_parent exists in header" >&5
+$as_echo_n "checking whether symbol kern_path_parent exists in header... " >&6; }
+ header=0
+ for file in include/linux/namei.h; do
+ grep -q "int kern_path_parent(const char \*, struct nameidata \*)" "$LINUX/$file" 2>/dev/null
+ rc=$?
+ if test $rc -eq 0; then
+ header=1
+ break;
+ fi
+ done
+ if test $header -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_KERN_PATH_PARENT_HEADER 1
+_ACEOF
+
+ fi
+
+
+
{ $as_echo "$as_me:$LINENO: checking whether symbol kern_path_parent is exported" >&5
$as_echo_n "checking whether symbol kern_path_parent is exported... " >&6; }
grep -q -E '[[:space:]]kern_path_parent[[:space:]]' \
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
-#define HAVE_KERN_PATH_PARENT 1
+#define HAVE_KERN_PATH_PARENT_SYMBOL 1
_ACEOF
fi
$as_echo "yes" >&6; }
cat >>confdefs.h <<\_ACEOF
-#define HAVE_KERN_PATH_PARENT 1
+#define HAVE_KERN_PATH_PARENT_SYMBOL 1
_ACEOF
fi
#define spl_inode_unlock(ip) (up(&(ip)->i_sem))
#endif /* HAVE_INODE_I_MUTEX */
-#ifdef HAVE_KERN_PATH_PARENT
-#define spl_kern_path_parent(path, nd) kern_path_parent(path, nd)
+#ifdef HAVE_KERN_PATH_PARENT_HEADER
+# ifndef HAVE_KERN_PATH_PARENT_SYMBOL
+typedef int (*kern_path_parent_t)(const char *, struct nameidata *);
+extern kern_path_parent_t kern_path_parent_fn;
+# define spl_kern_path_parent(path, nd) kern_path_parent_fn(path, nd)
+# else
+# define spl_kern_path_parent(path, nd) kern_path_parent(path, nd)
+# endif /* HAVE_KERN_PATH_PARENT_SYMBOL */
#else
-#define spl_kern_path_parent(path, nd) path_lookup(path, LOOKUP_PARENT, nd)
-#endif /* HAVE_KERN_PATH_PARENT */
+# define spl_kern_path_parent(path, nd) path_lookup(path, LOOKUP_PARENT, nd)
+#endif /* HAVE_KERN_PATH_PARENT_HEADER */
#endif /* SPL_FILE_COMPAT_H */
extern void vn_releasef(int fd);
extern int vn_set_pwd(const char *filename);
-int vn_init(void);
-void vn_fini(void);
+int spl_vn_init_kallsyms_lookup(void);
+int spl_vn_init(void);
+void spl_vn_fini(void);
#define VOP_CLOSE vn_close
#define VOP_SEEK vn_seek
if ((rc = spl_taskq_init()))
SGOTO(out4, rc);
- if ((rc = vn_init()))
+ if ((rc = spl_vn_init()))
SGOTO(out5, rc);
if ((rc = proc_init()))
if ((rc = spl_kmem_init_kallsyms_lookup()))
SGOTO(out10, rc);
+ if ((rc = spl_vn_init_kallsyms_lookup()))
+ SGOTO(out10, rc);
+
printk(KERN_NOTICE "SPL: Loaded module v%s%s, using hostid 0x%08x\n",
SPL_META_VERSION, SPL_DEBUG_STR, (unsigned int) spl_hostid);
SRETURN(rc);
out7:
proc_fini();
out6:
- vn_fini();
+ spl_vn_fini();
out5:
spl_taskq_fini();
out4:
tsd_fini();
kstat_fini();
proc_fini();
- vn_fini();
+ spl_vn_fini();
spl_taskq_fini();
spl_rw_fini();
spl_mutex_fini();
static DEFINE_SPINLOCK(vn_file_lock);
static LIST_HEAD(vn_file_list);
+#ifdef HAVE_KERN_PATH_PARENT_HEADER
+#ifndef HAVE_KERN_PATH_PARENT_SYMBOL
+kern_path_parent_t kern_path_parent_fn = SYMBOL_POISON;
+EXPORT_SYMBOL(kern_path_parent_fn);
+#endif /* HAVE_KERN_PATH_PARENT_SYMBOL */
+#endif /* HAVE_KERN_PATH_PARENT_HEADER */
+
vtype_t
vn_mode_to_vtype(mode_t mode)
{
mutex_destroy(&fp->f_lock);
} /* vn_file_cache_destructor() */
+int spl_vn_init_kallsyms_lookup(void)
+{
+#ifdef HAVE_KERN_PATH_PARENT_HEADER
+#ifndef HAVE_KERN_PATH_PARENT_SYMBOL
+ kern_path_parent_fn = (kern_path_parent_t)
+ spl_kallsyms_lookup_name("kern_path_parent");
+ if (!kern_path_parent_fn) {
+ printk(KERN_ERR "Error: Unknown symbol kern_path_parent\n");
+ return -EFAULT;
+ }
+#endif /* HAVE_KERN_PATH_PARENT_SYMBOL */
+#endif /* HAVE_KERN_PATH_PARENT_HEADER */
+
+ return (0);
+}
+
int
-vn_init(void)
+spl_vn_init(void)
{
SENTRY;
vn_cache = kmem_cache_create("spl_vn_cache",
} /* vn_init() */
void
-vn_fini(void)
+spl_vn_fini(void)
{
file_t *fp, *next_fp;
int leaked = 0;
#undef HAVE_KALLSYMS_LOOKUP_NAME
/* kern_path_parent() is available */
-#undef HAVE_KERN_PATH_PARENT
+#undef HAVE_KERN_PATH_PARENT_HEADER
+
+/* kern_path_parent() is available */
+#undef HAVE_KERN_PATH_PARENT_SYMBOL
/* kmalloc_node() is available */
#undef HAVE_KMALLOC_NODE