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 + + 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 + + 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 + + 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 */ };