summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/kernel-xattr-handler.m449
-rw-r--r--config/kernel.m42
-rwxr-xr-xconfigure278
-rw-r--r--include/linux/xattr_compat.h45
-rw-r--r--module/zfs/zpl_xattr.c20
-rw-r--r--zfs_config.h.in6
6 files changed, 393 insertions, 7 deletions
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 <linux/xattr.h>
+ ],[
+ 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 <linux/xattr.h>
+ ],[
+ 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 <linux/xattr.h>
+
+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 <linux/xattr.h>
+
+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 <linux/xattr.h>
+
+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 <linux/xattr.h>
+
+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 <dlfcn.h> header file. */
#undef HAVE_DLFCN_H