diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4 index fa7294597..1ebe1f0d9 100644 --- a/config/kernel-xattr-handler.m4 +++ b/config/kernel-xattr-handler.m4 @@ -30,3 +30,52 @@ AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER], AC_MSG_RESULT([no]) ]) ]) + +dnl # +dnl # 2.6.33 API change, +dnl # The xattr_hander->get() callback was changed to take a dentry +dnl # instead of an inode, and a handler_flags argument was added. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [ + AC_MSG_CHECKING([whether xattr_handler->get() wants dentry]) + ZFS_LINUX_TRY_COMPILE([ + #include + ],[ + int (*get)(struct dentry *dentry, const char *name, + void *buffer, size_t size, int handler_flags) = NULL; + struct xattr_handler xops; + + xops.get = get; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_DENTRY_XATTR_GET, 1, + [xattr_handler->get() wants dentry]) + ],[ + AC_MSG_RESULT(no) + ]) +]) + +dnl # +dnl # 2.6.33 API change, +dnl # The xattr_hander->set() callback was changed to take a dentry +dnl # instead of an inode, and a handler_flags argument was added. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [ + AC_MSG_CHECKING([whether xattr_handler->set() wants dentry]) + ZFS_LINUX_TRY_COMPILE([ + #include + ],[ + int (*set)(struct dentry *dentry, const char *name, + const void *buffer, size_t size, int flags, + int handler_flags) = NULL; + struct xattr_handler xops; + + xops.set = set; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_DENTRY_XATTR_SET, 1, + [xattr_handler->set() wants dentry]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index c411c8f49..1f271d178 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -29,6 +29,8 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL_RQ_IS_SYNC ZFS_AC_KERNEL_RQ_FOR_EACH_SEGMENT ZFS_AC_KERNEL_CONST_XATTR_HANDLER + ZFS_AC_KERNEL_XATTR_HANDLER_GET + ZFS_AC_KERNEL_XATTR_HANDLER_SET ZFS_AC_KERNEL_FSYNC_2ARGS if test "$LINUX_OBJ" != "$LINUX"; then diff --git a/configure b/configure index fa721d43f..55cf1576f 100755 --- a/configure +++ b/configure @@ -13900,6 +13900,145 @@ fi + { $as_echo "$as_me:$LINENO: checking whether xattr_handler->get() wants dentry" >&5 +$as_echo_n "checking whether xattr_handler->get() wants dentry... " >&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) +{ + + int (*get)(struct dentry *dentry, const char *name, + void *buffer, size_t size, int handler_flags) = NULL; + struct xattr_handler xops; + + xops.get = get; + + ; + 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_DENTRY_XATTR_GET 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 xattr_handler->set() wants dentry" >&5 +$as_echo_n "checking whether xattr_handler->set() wants dentry... " >&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) +{ + + int (*set)(struct dentry *dentry, const char *name, + const void *buffer, size_t size, int flags, + int handler_flags) = NULL; + struct xattr_handler xops; + + xops.set = set; + + ; + 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_DENTRY_XATTR_SET 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 fops->fsync() wants 2 args" >&5 $as_echo_n "checking whether fops->fsync() wants 2 args... " >&6; } @@ -17572,6 +17711,145 @@ fi + { $as_echo "$as_me:$LINENO: checking whether xattr_handler->get() wants dentry" >&5 +$as_echo_n "checking whether xattr_handler->get() wants dentry... " >&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) +{ + + int (*get)(struct dentry *dentry, const char *name, + void *buffer, size_t size, int handler_flags) = NULL; + struct xattr_handler xops; + + xops.get = get; + + ; + 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_DENTRY_XATTR_GET 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 xattr_handler->set() wants dentry" >&5 +$as_echo_n "checking whether xattr_handler->set() wants dentry... " >&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) +{ + + int (*set)(struct dentry *dentry, const char *name, + const void *buffer, size_t size, int flags, + int handler_flags) = NULL; + struct xattr_handler xops; + + xops.set = set; + + ; + 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_DENTRY_XATTR_SET 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 fops->fsync() wants 2 args" >&5 $as_echo_n "checking whether fops->fsync() wants 2 args... " >&6; } diff --git a/include/linux/xattr_compat.h b/include/linux/xattr_compat.h index dfa92acab..9878aab72 100644 --- a/include/linux/xattr_compat.h +++ b/include/linux/xattr_compat.h @@ -39,4 +39,49 @@ typedef const struct xattr_handler xattr_handler_t; typedef struct xattr_handler xattr_handler_t; #endif +/* + * 2.6.33 API change, + * The xattr_hander->get() callback was changed to take a dentry + * instead of an inode, and a handler_flags argument was added. + */ +#ifdef HAVE_DENTRY_XATTR_GET +#define ZPL_XATTR_GET_WRAPPER(fn) \ +static int \ +fn(struct dentry *dentry, const char *name, void *buffer, size_t size, \ + int unused_handler_flags) \ +{ \ + return __ ## fn(dentry->d_inode, name, buffer, size); \ +} +#else +#define ZPL_XATTR_GET_WRAPPER(fn) \ +static int \ +fn(struct inode *ip, const char *name, void *buffer, size_t size) \ +{ \ + return __ ## fn(ip, name, buffer, size); \ +} +#endif /* HAVE_DENTRY_XATTR_GET */ + +/* + * 2.6.33 API change, + * The xattr_hander->set() callback was changed to take a dentry + * instead of an inode, and a handler_flags argument was added. + */ +#ifdef HAVE_DENTRY_XATTR_SET +#define ZPL_XATTR_SET_WRAPPER(fn) \ +static int \ +fn(struct dentry *dentry, const char *name, const void *buffer, \ + size_t size, int flags, int unused_handler_flags) \ +{ \ + return __ ## fn(dentry->d_inode, name, buffer, size, flags); \ +} +#else +#define ZPL_XATTR_SET_WRAPPER(fn) \ +static int \ +fn(struct inode *ip, const char *name, const void *buffer, \ + size_t size, int flags) \ +{ \ + return __ ## fn(ip, name, buffer, size, flags); \ +} +#endif /* HAVE_DENTRY_XATTR_SET */ + #endif /* _ZFS_XATTR_H */ diff --git a/module/zfs/zpl_xattr.c b/module/zfs/zpl_xattr.c index 86e52f791..7a1ecec8f 100644 --- a/module/zfs/zpl_xattr.c +++ b/module/zfs/zpl_xattr.c @@ -266,7 +266,7 @@ out: } static int -zpl_xattr_user_get(struct inode *ip, const char *name, +__zpl_xattr_user_get(struct inode *ip, const char *name, void *buffer, size_t size) { char *xattr_name; @@ -284,9 +284,10 @@ zpl_xattr_user_get(struct inode *ip, const char *name, return (error); } +ZPL_XATTR_GET_WRAPPER(zpl_xattr_user_get); static int -zpl_xattr_user_set(struct inode *ip, const char *name, +__zpl_xattr_user_set(struct inode *ip, const char *name, const void *value, size_t size, int flags) { char *xattr_name; @@ -304,6 +305,7 @@ zpl_xattr_user_set(struct inode *ip, const char *name, return (error); } +ZPL_XATTR_SET_WRAPPER(zpl_xattr_user_set); xattr_handler_t zpl_xattr_user_handler = { .prefix = XATTR_USER_PREFIX, @@ -312,7 +314,7 @@ xattr_handler_t zpl_xattr_user_handler = { }; static int -zpl_xattr_trusted_get(struct inode *ip, const char *name, +__zpl_xattr_trusted_get(struct inode *ip, const char *name, void *buffer, size_t size) { char *xattr_name; @@ -330,9 +332,10 @@ zpl_xattr_trusted_get(struct inode *ip, const char *name, return (error); } +ZPL_XATTR_GET_WRAPPER(zpl_xattr_trusted_get); static int -zpl_xattr_trusted_set(struct inode *ip, const char *name, +__zpl_xattr_trusted_set(struct inode *ip, const char *name, const void *value, size_t size, int flags) { char *xattr_name; @@ -350,6 +353,7 @@ zpl_xattr_trusted_set(struct inode *ip, const char *name, return (error); } +ZPL_XATTR_SET_WRAPPER(zpl_xattr_trusted_set); xattr_handler_t zpl_xattr_trusted_handler = { .prefix = XATTR_TRUSTED_PREFIX, @@ -358,7 +362,7 @@ xattr_handler_t zpl_xattr_trusted_handler = { }; static int -zpl_xattr_security_get(struct inode *ip, const char *name, +__zpl_xattr_security_get(struct inode *ip, const char *name, void *buffer, size_t size) { char *xattr_name; @@ -373,9 +377,10 @@ zpl_xattr_security_get(struct inode *ip, const char *name, return (error); } +ZPL_XATTR_GET_WRAPPER(zpl_xattr_security_get); static int -zpl_xattr_security_set(struct inode *ip, const char *name, +__zpl_xattr_security_set(struct inode *ip, const char *name, const void *value, size_t size, int flags) { char *xattr_name; @@ -390,6 +395,7 @@ zpl_xattr_security_set(struct inode *ip, const char *name, return (error); } +ZPL_XATTR_SET_WRAPPER(zpl_xattr_security_set); int zpl_xattr_security_init(struct inode *ip, struct inode *dip) @@ -407,7 +413,7 @@ zpl_xattr_security_init(struct inode *ip, struct inode *dip) return (error); } - error = zpl_xattr_security_set(ip, name, value, len, 0); + error = __zpl_xattr_security_set(ip, name, value, len, 0); kfree(name); kfree(value); diff --git a/zfs_config.h.in b/zfs_config.h.in index fd7bd668c..d6999bbda 100644 --- a/zfs_config.h.in +++ b/zfs_config.h.in @@ -60,6 +60,12 @@ /* super_block uses const struct xattr_hander */ #undef HAVE_CONST_XATTR_HANDLER +/* xattr_handler->get() wants dentry */ +#undef HAVE_DENTRY_XATTR_GET + +/* xattr_handler->set() wants dentry */ +#undef HAVE_DENTRY_XATTR_SET + /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H