Linux 3.1 compat, kern_path_parent()
Prior to Linux 3.1 the kern_path_parent symbol was exported for use by kernel modules. As of Linux 3.1 it is now longer easily available. To handle this case the spl will now dynamically look up address of the missing symbol at module load time. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Issue #52
This commit is contained in:
parent
b8b6e4c453
commit
12ff95ff57
@ -80,7 +80,8 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
|
||||
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
|
||||
])
|
||||
@ -587,6 +588,30 @@ AC_DEFUN([SPL_CHECK_SYMBOL_EXPORT],
|
||||
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
|
||||
@ -1809,11 +1834,27 @@ dnl # and the flags argument has been removed. The only behavior now
|
||||
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])],
|
||||
[])
|
||||
])
|
||||
|
64
configure
vendored
64
configure
vendored
@ -15684,6 +15684,34 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
|
||||
{ $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:]]' \
|
||||
@ -15709,7 +15737,7 @@ $as_echo "no" >&6; }
|
||||
$as_echo "yes" >&6; }
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_KERN_PATH_PARENT 1
|
||||
#define HAVE_KERN_PATH_PARENT_SYMBOL 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
@ -15718,7 +15746,7 @@ _ACEOF
|
||||
$as_echo "yes" >&6; }
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_KERN_PATH_PARENT 1
|
||||
#define HAVE_KERN_PATH_PARENT_SYMBOL 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
@ -19885,6 +19913,34 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
|
||||
{ $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:]]' \
|
||||
@ -19910,7 +19966,7 @@ $as_echo "no" >&6; }
|
||||
$as_echo "yes" >&6; }
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_KERN_PATH_PARENT 1
|
||||
#define HAVE_KERN_PATH_PARENT_SYMBOL 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
@ -19919,7 +19975,7 @@ _ACEOF
|
||||
$as_echo "yes" >&6; }
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_KERN_PATH_PARENT 1
|
||||
#define HAVE_KERN_PATH_PARENT_SYMBOL 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
@ -67,11 +67,17 @@ spl_filp_open(const char *name, int flags, int mode, int *err)
|
||||
#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 */
|
||||
|
||||
|
@ -189,8 +189,9 @@ extern file_t *vn_getf(int fd);
|
||||
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
|
||||
|
@ -561,7 +561,7 @@ __init spl_init(void)
|
||||
if ((rc = spl_taskq_init()))
|
||||
SGOTO(out4, rc);
|
||||
|
||||
if ((rc = vn_init()))
|
||||
if ((rc = spl_vn_init()))
|
||||
SGOTO(out5, rc);
|
||||
|
||||
if ((rc = proc_init()))
|
||||
@ -594,6 +594,9 @@ __init spl_init(void)
|
||||
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);
|
||||
@ -606,7 +609,7 @@ __init spl_init(void)
|
||||
out7:
|
||||
proc_fini();
|
||||
out6:
|
||||
vn_fini();
|
||||
spl_vn_fini();
|
||||
out5:
|
||||
spl_taskq_fini();
|
||||
out4:
|
||||
@ -634,7 +637,7 @@ spl_fini(void)
|
||||
tsd_fini();
|
||||
kstat_fini();
|
||||
proc_fini();
|
||||
vn_fini();
|
||||
spl_vn_fini();
|
||||
spl_taskq_fini();
|
||||
spl_rw_fini();
|
||||
spl_mutex_fini();
|
||||
|
@ -42,6 +42,13 @@ static spl_kmem_cache_t *vn_file_cache;
|
||||
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)
|
||||
{
|
||||
@ -789,8 +796,24 @@ vn_file_cache_destructor(void *buf, void *cdrarg)
|
||||
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",
|
||||
@ -808,7 +831,7 @@ vn_init(void)
|
||||
} /* vn_init() */
|
||||
|
||||
void
|
||||
vn_fini(void)
|
||||
spl_vn_fini(void)
|
||||
{
|
||||
file_t *fp, *next_fp;
|
||||
int leaked = 0;
|
||||
|
@ -115,7 +115,10 @@
|
||||
#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
|
||||
|
Loading…
Reference in New Issue
Block a user