diff options
-rw-r--r-- | config/spl-build.m4 | 47 | ||||
-rwxr-xr-x | configure | 64 | ||||
-rw-r--r-- | include/linux/file_compat.h | 14 | ||||
-rw-r--r-- | include/sys/vnode.h | 5 | ||||
-rw-r--r-- | module/spl/spl-generic.c | 9 | ||||
-rw-r--r-- | module/spl/spl-vnode.c | 27 | ||||
-rw-r--r-- | spl_config.h.in | 5 |
7 files changed, 152 insertions, 19 deletions
diff --git a/config/spl-build.m4 b/config/spl-build.m4 index c046db830..f5696b943 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -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 ]) @@ -588,6 +589,30 @@ AC_DEFUN([SPL_CHECK_SYMBOL_EXPORT], ]) 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 # @@ -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])], []) ]) @@ -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 diff --git a/include/linux/file_compat.h b/include/linux/file_compat.h index 97bd76396..d5fb2bc60 100644 --- a/include/linux/file_compat.h +++ b/include/linux/file_compat.h @@ -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 */ diff --git a/include/sys/vnode.h b/include/sys/vnode.h index 36605ca4a..03462bd70 100644 --- a/include/sys/vnode.h +++ b/include/sys/vnode.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 diff --git a/module/spl/spl-generic.c b/module/spl/spl-generic.c index 1dedf76cf..3f042cc0d 100644 --- a/module/spl/spl-generic.c +++ b/module/spl/spl-generic.c @@ -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 @@ out8: 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(); diff --git a/module/spl/spl-vnode.c b/module/spl/spl-vnode.c index 354e8798b..cd0fa2cd1 100644 --- a/module/spl/spl-vnode.c +++ b/module/spl/spl-vnode.c @@ -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; diff --git a/spl_config.h.in b/spl_config.h.in index 97f0e06f3..612205969 100644 --- a/spl_config.h.in +++ b/spl_config.h.in @@ -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 |