From e0093fea58f2ce2764b0b43337c960ed4a5d1b73 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Wed, 6 Jun 2012 16:51:53 +0000 Subject: [PATCH] Linux 3.4 compat, __clear_close_on_exec replaces FD_CLR torvalds/linux@1dce27c5aa6770e9d195f2bb7db1db3d4dde5591 introduced __clear_close_on_exec() as a replacement for FD_CLR. Further commits appear to have removed FD_CLR from the Linux source tree. This causes the following failure: error: implicit declaration of function '__FD_CLR' [-Werror=implicit-function-declaration] To correct this we update the code to use the current __clear_close_on_exec() interface for readability. Then we introduce an autotools check to determine if __clear_close_on_exec() is available. If it isn't then we define some compatibility logic which used the older FD_CLR() interface. Signed-off-by: Richard Yao Signed-off-by: Brian Behlendorf Closes #124 --- config/spl-build.m4 | 23 ++++++ configure | 136 ++++++++++++++++++++++++++++++++++++ include/linux/file_compat.h | 4 ++ module/splat/splat-vnode.c | 2 +- spl_config.h.in | 3 + 5 files changed, 167 insertions(+), 1 deletion(-) diff --git a/config/spl-build.m4 b/config/spl-build.m4 index 6605b82..4d02a72 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -44,6 +44,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ SPL_AC_INIT_UTSNAME SPL_AC_FDTABLE_HEADER SPL_AC_FILES_FDTABLE + SPL_AC_CLEAR_CLOSE_ON_EXEC SPL_AC_UACCESS_HEADER SPL_AC_KMALLOC_NODE SPL_AC_MONOTONIC_CLOCK @@ -1176,6 +1177,28 @@ AC_DEFUN([SPL_AC_FILES_FDTABLE], [ ]) ]) +dnl # +dnl # 3.4.0 API change, +dnl # check whether '__clear_close_on_exec()' exists +dnl # +AC_DEFUN([SPL_AC_CLEAR_CLOSE_ON_EXEC], [ + AC_MSG_CHECKING([whether __clear_close_on_exec() is available]) + SPL_LINUX_TRY_COMPILE([ + #include + ],[ + struct fdtable *fdt = NULL; + int fd = 0; + + __clear_close_on_exec(fd, fdt); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_CLEAR_CLOSE_ON_EXEC, 1, + [__clear_close_on_exec() is available]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + dnl # dnl # 2.6.18 API change, dnl # added linux/uaccess.h diff --git a/configure b/configure index f4a9f13..761fdc1 100755 --- a/configure +++ b/configure @@ -13506,6 +13506,74 @@ fi + { $as_echo "$as_me:$LINENO: checking whether __clear_close_on_exec() is available" >&5 +$as_echo_n "checking whether __clear_close_on_exec() is available... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + struct fdtable *fdt = NULL; + int fd = 0; + + __clear_close_on_exec(fd, fdt); + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CLEAR_CLOSE_ON_EXEC 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + { $as_echo "$as_me:$LINENO: checking whether header linux/uaccess.h exists" >&5 $as_echo_n "checking whether header linux/uaccess.h exists... " >&6; } @@ -17936,6 +18004,74 @@ fi + { $as_echo "$as_me:$LINENO: checking whether __clear_close_on_exec() is available" >&5 +$as_echo_n "checking whether __clear_close_on_exec() is available... " >&6; } + + +cat confdefs.h - <<_ACEOF >conftest.c +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + + #include + +int +main (void) +{ + + struct fdtable *fdt = NULL; + int fd = 0; + + __clear_close_on_exec(fd, fdt); + + ; + return 0; +} + +_ACEOF + + + rm -Rf build && mkdir -p build + echo "obj-m := conftest.o" >build/Makefile + if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CLEAR_CLOSE_ON_EXEC 1 +_ACEOF + + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + + + +fi + + rm -Rf build + + + + { $as_echo "$as_me:$LINENO: checking whether header linux/uaccess.h exists" >&5 $as_echo_n "checking whether header linux/uaccess.h exists... " >&6; } diff --git a/include/linux/file_compat.h b/include/linux/file_compat.h index 5c7833d..2b5b7d2 100644 --- a/include/linux/file_compat.h +++ b/include/linux/file_compat.h @@ -83,5 +83,9 @@ extern kern_path_parent_t kern_path_parent_fn; # define spl_kern_path_parent(path, nd) path_lookup(path, LOOKUP_PARENT, nd) #endif /* HAVE_KERN_PATH_PARENT_HEADER */ +#ifndef HAVE_CLEAR_CLOSE_ON_EXEC +#define __clear_close_on_exec(fd, fdt) FD_CLR(fd, fdt->close_on_exec) +#endif + #endif /* SPL_FILE_COMPAT_H */ diff --git a/module/splat/splat-vnode.c b/module/splat/splat-vnode.c index 0cd28a6..f5f010c 100644 --- a/module/splat/splat-vnode.c +++ b/module/splat/splat-vnode.c @@ -414,7 +414,7 @@ fd_uninstall(int fd) goto out_unlock; rcu_assign_pointer(fdt->fd[fd], NULL); - FD_CLR(fd, fdt->close_on_exec); + __clear_close_on_exec(fd, fdt); #else spin_lock(&files->file_lock); if (fd >= files->max_fds) diff --git a/spl_config.h.in b/spl_config.h.in index 05dcdc5..92c11df 100644 --- a/spl_config.h.in +++ b/spl_config.h.in @@ -60,6 +60,9 @@ /* class_device_create() is available */ #undef HAVE_CLASS_DEVICE_CREATE +/* __clear_close_on_exec() is available */ +#undef HAVE_CLEAR_CLOSE_ON_EXEC + /* struct cred exists */ #undef HAVE_CRED_STRUCT -- 2.40.0