diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4 index 00b1e74a9ccb..b6cbfa155007 100644 --- a/config/kernel-xattr-handler.m4 +++ b/config/kernel-xattr-handler.m4 @@ -100,6 +100,19 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_GET], [ .get = get, }; ],[]) + + ZFS_LINUX_TEST_SRC([xattr_handler_get_dentry_inode_flags], [ + #include + + int get(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, void *buffer, + size_t size, int flags) { return 0; } + static const struct xattr_handler + xops __attribute__ ((unused)) = { + .get = get, + }; + ],[]) ]) AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [ @@ -142,7 +155,21 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [ AC_DEFINE(HAVE_XATTR_GET_DENTRY, 1, [xattr_handler->get() wants dentry]) ],[ - ZFS_LINUX_TEST_ERROR([xattr get()]) + dnl # + dnl # Android API change, + dnl # The xattr_handler->get() callback was + dnl # changed to take dentry, inode and flags. + dnl # + AC_MSG_RESULT(no) + AC_MSG_CHECKING( + [whether xattr_handler->get() wants dentry and inode and flags]) + ZFS_LINUX_TEST_RESULT([xattr_handler_get_dentry_inode_flags], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_XATTR_GET_DENTRY_INODE_FLAGS, 1, + [xattr_handler->get() wants dentry and inode and flags]) + ],[ + ZFS_LINUX_TEST_ERROR([xattr get()]) + ]) ]) ]) ]) diff --git a/include/os/linux/kernel/linux/xattr_compat.h b/include/os/linux/kernel/linux/xattr_compat.h index 54690727eab9..30403fe87397 100644 --- a/include/os/linux/kernel/linux/xattr_compat.h +++ b/include/os/linux/kernel/linux/xattr_compat.h @@ -115,6 +115,20 @@ fn(struct dentry *dentry, const char *name, void *buffer, size_t size, \ { \ return (__ ## fn(dentry->d_inode, name, buffer, size)); \ } +/* + * Android API change, + * The xattr_handler->get() callback was changed to take a dentry and inode + * and flags, because the dentry might not be attached to an inode yet. + */ +#elif defined(HAVE_XATTR_GET_DENTRY_INODE_FLAGS) +#define ZPL_XATTR_GET_WRAPPER(fn) \ +static int \ +fn(const struct xattr_handler *handler, struct dentry *dentry, \ + struct inode *inode, const char *name, void *buffer, \ + size_t size, int flags) \ +{ \ + return (__ ## fn(inode, name, buffer, size)); \ +} #else #error "Unsupported kernel" #endif