aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/kernel-xattr-handler.m469
-rw-r--r--include/linux/xattr_compat.h28
-rw-r--r--module/zfs/zpl_xattr.c69
3 files changed, 164 insertions, 2 deletions
diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
index 1374f7917..d79a6e47b 100644
--- a/config/kernel-xattr-handler.m4
+++ b/config/kernel-xattr-handler.m4
@@ -37,6 +37,11 @@ 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 #
+dnl # 4.4 API change,
+dnl # The xattr_hander->get() callback was changed to take a xattr_handler,
+dnl # and handler_flags argument was removed and should be accessed by
+dnl # handler->flags.
+dnl #
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
AC_MSG_CHECKING([whether xattr_handler->get() wants dentry])
ZFS_LINUX_TRY_COMPILE([
@@ -55,6 +60,24 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
[xattr_handler->get() wants dentry])
],[
AC_MSG_RESULT(no)
+ AC_MSG_CHECKING([whether xattr_handler->get() wants xattr_handler])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/xattr.h>
+
+ int get(const struct xattr_handler *handler, struct dentry *dentry,
+ const char *name, void *buffer, size_t size) { return 0; }
+ static const struct xattr_handler
+ xops __attribute__ ((unused)) = {
+ .get = get,
+ };
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_HANDLER_XATTR_GET, 1,
+ [xattr_handler->get() wants xattr_handler])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
])
])
@@ -63,6 +86,11 @@ 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 #
+dnl # 4.4 API change,
+dnl # The xattr_hander->set() callback was changed to take a xattr_handler,
+dnl # and handler_flags argument was removed and should be accessed by
+dnl # handler->flags.
+dnl #
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
AC_MSG_CHECKING([whether xattr_handler->set() wants dentry])
ZFS_LINUX_TRY_COMPILE([
@@ -82,6 +110,24 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
[xattr_handler->set() wants dentry])
],[
AC_MSG_RESULT(no)
+ AC_MSG_CHECKING([whether xattr_handler->set() wants xattr_handler])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/xattr.h>
+
+ int set(const struct xattr_handler *handler, struct dentry *dentry,
+ const char *name, const void *buffer, size_t size, int flags) { return 0; }
+ static const struct xattr_handler
+ xops __attribute__ ((unused)) = {
+ .set = set,
+ };
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_HANDLER_XATTR_SET, 1,
+ [xattr_handler->set() wants xattr_handler])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
])
])
@@ -90,6 +136,11 @@ dnl # 2.6.33 API change,
dnl # The xattr_hander->list() callback was changed to take a dentry
dnl # instead of an inode, and a handler_flags argument was added.
dnl #
+dnl # 4.4 API change,
+dnl # The xattr_hander->list() callback was changed to take a xattr_handler,
+dnl # and handler_flags argument was removed and should be accessed by
+dnl # handler->flags.
+dnl #
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
AC_MSG_CHECKING([whether xattr_handler->list() wants dentry])
ZFS_LINUX_TRY_COMPILE([
@@ -109,6 +160,24 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
[xattr_handler->list() wants dentry])
],[
AC_MSG_RESULT(no)
+ AC_MSG_CHECKING([whether xattr_handler->list() wants xattr_handler])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/xattr.h>
+
+ size_t list(const struct xattr_handler *handler, struct dentry *dentry,
+ char *list, size_t list_size, const char *name, size_t name_len) { return 0; }
+ static const struct xattr_handler
+ xops __attribute__ ((unused)) = {
+ .list = list,
+ };
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_HANDLER_XATTR_LIST, 1,
+ [xattr_handler->list() wants xattr_handler])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
])
])
diff --git a/include/linux/xattr_compat.h b/include/linux/xattr_compat.h
index a7371f946..28eff95fa 100644
--- a/include/linux/xattr_compat.h
+++ b/include/linux/xattr_compat.h
@@ -54,6 +54,20 @@ fn(struct dentry *dentry, const char *name, void *buffer, size_t size, \
{ \
return (__ ## fn(dentry->d_inode, name, buffer, size)); \
}
+/*
+ * 4.4 API change,
+ * The xattr_hander->get() callback was changed to take a xattr_handler,
+ * and handler_flags argument was removed and should be accessed by
+ * handler->flags.
+ */
+#elif defined(HAVE_HANDLER_XATTR_GET)
+#define ZPL_XATTR_GET_WRAPPER(fn) \
+static int \
+fn(const struct xattr_handler *handler, struct dentry *dentry, \
+ const char *name, void *buffer, size_t size) \
+{ \
+ return (__ ## fn(dentry->d_inode, name, buffer, size)); \
+}
#else
#define ZPL_XATTR_GET_WRAPPER(fn) \
static int \
@@ -76,6 +90,20 @@ fn(struct dentry *dentry, const char *name, const void *buffer, \
{ \
return (__ ## fn(dentry->d_inode, name, buffer, size, flags)); \
}
+/*
+ * 4.4 API change,
+ * The xattr_hander->set() callback was changed to take a xattr_handler,
+ * and handler_flags argument was removed and should be accessed by
+ * handler->flags.
+ */
+#elif defined(HAVE_HANDLER_XATTR_SET)
+#define ZPL_XATTR_SET_WRAPPER(fn) \
+static int \
+fn(const struct xattr_handler *handler, struct dentry *dentry, \
+ const char *name, const void *buffer, size_t size, int flags) \
+{ \
+ return (__ ## fn(dentry->d_inode, name, buffer, size, flags)); \
+}
#else
#define ZPL_XATTR_SET_WRAPPER(fn) \
static int \
diff --git a/module/zfs/zpl_xattr.c b/module/zfs/zpl_xattr.c
index 202199c6d..d224078ef 100644
--- a/module/zfs/zpl_xattr.c
+++ b/module/zfs/zpl_xattr.c
@@ -1022,6 +1022,29 @@ zpl_xattr_acl_list_default(struct dentry *dentry, char *list,
list, list_size, name, name_len, type);
}
+#elif defined(HAVE_HANDLER_XATTR_LIST)
+static size_t
+zpl_xattr_acl_list_access(const struct xattr_handler *handler,
+ struct dentry *dentry, char *list, size_t list_size, const char *name,
+ size_t name_len)
+{
+ int type = handler->flags;
+ ASSERT3S(type, ==, ACL_TYPE_ACCESS);
+ return zpl_xattr_acl_list(dentry->d_inode,
+ list, list_size, name, name_len, type);
+}
+
+static size_t
+zpl_xattr_acl_list_default(const struct xattr_handler *handler,
+ struct dentry *dentry, char *list, size_t list_size, const char *name,
+ size_t name_len)
+{
+ int type = handler->flags;
+ ASSERT3S(type, ==, ACL_TYPE_DEFAULT);
+ return zpl_xattr_acl_list(dentry->d_inode,
+ list, list_size, name, name_len, type);
+}
+
#else
static size_t
@@ -1083,6 +1106,25 @@ zpl_xattr_acl_get_default(struct dentry *dentry, const char *name,
return (zpl_xattr_acl_get(dentry->d_inode, name, buffer, size, type));
}
+#elif defined(HAVE_HANDLER_XATTR_GET)
+static int
+zpl_xattr_acl_get_access(const struct xattr_handler *handler,
+ struct dentry *dentry, const char *name, void *buffer, size_t size)
+{
+ int type = handler->flags;
+ ASSERT3S(type, ==, ACL_TYPE_ACCESS);
+ return (zpl_xattr_acl_get(dentry->d_inode, name, buffer, size, type));
+}
+
+static int
+zpl_xattr_acl_get_default(const struct xattr_handler *handler,
+ struct dentry *dentry, const char *name, void *buffer, size_t size)
+{
+ int type = handler->flags;
+ ASSERT3S(type, ==, ACL_TYPE_DEFAULT);
+ return (zpl_xattr_acl_get(dentry->d_inode, name, buffer, size, type));
+}
+
#else
static int
@@ -1156,6 +1198,29 @@ zpl_xattr_acl_set_default(struct dentry *dentry, const char *name,
name, value, size, flags, type);
}
+#elif defined(HAVE_HANDLER_XATTR_SET)
+static int
+zpl_xattr_acl_set_access(const struct xattr_handler *handler,
+ struct dentry *dentry, const char *name, const void *value, size_t size,
+ int flags)
+{
+ int type = handler->flags;
+ ASSERT3S(type, ==, ACL_TYPE_ACCESS);
+ return (zpl_xattr_acl_set(dentry->d_inode,
+ name, value, size, flags, type));
+}
+
+static int
+zpl_xattr_acl_set_default(const struct xattr_handler *handler,
+ struct dentry *dentry, const char *name, const void *value, size_t size,
+ int flags)
+{
+ int type = handler->flags;
+ ASSERT3S(type, ==, ACL_TYPE_DEFAULT);
+ return zpl_xattr_acl_set(dentry->d_inode,
+ name, value, size, flags, type);
+}
+
#else
static int
@@ -1181,7 +1246,7 @@ struct xattr_handler zpl_xattr_acl_access_handler =
.list = zpl_xattr_acl_list_access,
.get = zpl_xattr_acl_get_access,
.set = zpl_xattr_acl_set_access,
-#ifdef HAVE_DENTRY_XATTR_LIST
+#if defined(HAVE_DENTRY_XATTR_LIST) || defined(HAVE_HANDLER_XATTR_LIST)
.flags = ACL_TYPE_ACCESS,
#endif /* HAVE_DENTRY_XATTR_LIST */
};
@@ -1192,7 +1257,7 @@ struct xattr_handler zpl_xattr_acl_default_handler =
.list = zpl_xattr_acl_list_default,
.get = zpl_xattr_acl_get_default,
.set = zpl_xattr_acl_set_default,
-#ifdef HAVE_DENTRY_XATTR_LIST
+#if defined(HAVE_DENTRY_XATTR_LIST) || defined(HAVE_HANDLER_XATTR_LIST)
.flags = ACL_TYPE_DEFAULT,
#endif /* HAVE_DENTRY_XATTR_LIST */
};