1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or https://opensource.org/licenses/CDDL-1.0. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright (C) 2011 Lawrence Livermore National Security, LLC. 24 */ 25 26#ifndef _ZFS_XATTR_H 27#define _ZFS_XATTR_H 28 29#include <linux/posix_acl_xattr.h> 30 31/* 32 * 2.6.35 API change, 33 * The const keyword was added to the 'struct xattr_handler' in the 34 * generic Linux super_block structure. To handle this we define an 35 * appropriate xattr_handler_t typedef which can be used. This was 36 * the preferred solution because it keeps the code clean and readable. 37 */ 38typedef const struct xattr_handler xattr_handler_t; 39 40/* 41 * 4.5 API change, 42 */ 43#if defined(HAVE_XATTR_LIST_SIMPLE) 44#define ZPL_XATTR_LIST_WRAPPER(fn) \ 45static bool \ 46fn(struct dentry *dentry) \ 47{ \ 48 return (!!__ ## fn(dentry->d_inode, NULL, 0, NULL, 0)); \ 49} 50/* 51 * 4.4 API change, 52 */ 53#elif defined(HAVE_XATTR_LIST_DENTRY) 54#define ZPL_XATTR_LIST_WRAPPER(fn) \ 55static size_t \ 56fn(struct dentry *dentry, char *list, size_t list_size, \ 57 const char *name, size_t name_len, int type) \ 58{ \ 59 return (__ ## fn(dentry->d_inode, \ 60 list, list_size, name, name_len)); \ 61} 62/* 63 * 2.6.33 API change, 64 */ 65#elif defined(HAVE_XATTR_LIST_HANDLER) 66#define ZPL_XATTR_LIST_WRAPPER(fn) \ 67static size_t \ 68fn(const struct xattr_handler *handler, struct dentry *dentry, \ 69 char *list, size_t list_size, const char *name, size_t name_len) \ 70{ \ 71 return (__ ## fn(dentry->d_inode, \ 72 list, list_size, name, name_len)); \ 73} 74#else 75#error "Unsupported kernel" 76#endif 77 78/* 79 * 4.7 API change, 80 * The xattr_handler->get() callback was changed to take a both dentry and 81 * inode, because the dentry might not be attached to an inode yet. 82 */ 83#if defined(HAVE_XATTR_GET_DENTRY_INODE) 84#define ZPL_XATTR_GET_WRAPPER(fn) \ 85static int \ 86fn(const struct xattr_handler *handler, struct dentry *dentry, \ 87 struct inode *inode, const char *name, void *buffer, size_t size) \ 88{ \ 89 return (__ ## fn(inode, name, buffer, size)); \ 90} 91/* 92 * 4.4 API change, 93 * The xattr_handler->get() callback was changed to take a xattr_handler, 94 * and handler_flags argument was removed and should be accessed by 95 * handler->flags. 96 */ 97#elif defined(HAVE_XATTR_GET_HANDLER) 98#define ZPL_XATTR_GET_WRAPPER(fn) \ 99static int \ 100fn(const struct xattr_handler *handler, struct dentry *dentry, \ 101 const char *name, void *buffer, size_t size) \ 102{ \ 103 return (__ ## fn(dentry->d_inode, name, buffer, size)); \ 104} 105/* 106 * 2.6.33 API change, 107 * The xattr_handler->get() callback was changed to take a dentry 108 * instead of an inode, and a handler_flags argument was added. 109 */ 110#elif defined(HAVE_XATTR_GET_DENTRY) 111#define ZPL_XATTR_GET_WRAPPER(fn) \ 112static int \ 113fn(struct dentry *dentry, const char *name, void *buffer, size_t size, \ 114 int unused_handler_flags) \ 115{ \ 116 return (__ ## fn(dentry->d_inode, name, buffer, size)); \ 117} 118/* 119 * Android API change, 120 * The xattr_handler->get() callback was changed to take a dentry and inode 121 * and flags, because the dentry might not be attached to an inode yet. 122 */ 123#elif defined(HAVE_XATTR_GET_DENTRY_INODE_FLAGS) 124#define ZPL_XATTR_GET_WRAPPER(fn) \ 125static int \ 126fn(const struct xattr_handler *handler, struct dentry *dentry, \ 127 struct inode *inode, const char *name, void *buffer, \ 128 size_t size, int flags) \ 129{ \ 130 return (__ ## fn(inode, name, buffer, size)); \ 131} 132#else 133#error "Unsupported kernel" 134#endif 135 136/* 137 * 6.3 API change, 138 * The xattr_handler->set() callback was changed to take the 139 * struct mnt_idmap* as the first arg, to support idmapped 140 * mounts. 141 */ 142#if defined(HAVE_XATTR_SET_IDMAP) 143#define ZPL_XATTR_SET_WRAPPER(fn) \ 144static int \ 145fn(const struct xattr_handler *handler, struct mnt_idmap *user_ns, \ 146 struct dentry *dentry, struct inode *inode, const char *name, \ 147 const void *buffer, size_t size, int flags) \ 148{ \ 149 return (__ ## fn(user_ns, inode, name, buffer, size, flags)); \ 150} 151/* 152 * 5.12 API change, 153 * The xattr_handler->set() callback was changed to take the 154 * struct user_namespace* as the first arg, to support idmapped 155 * mounts. 156 */ 157#elif defined(HAVE_XATTR_SET_USERNS) 158#define ZPL_XATTR_SET_WRAPPER(fn) \ 159static int \ 160fn(const struct xattr_handler *handler, struct user_namespace *user_ns, \ 161 struct dentry *dentry, struct inode *inode, const char *name, \ 162 const void *buffer, size_t size, int flags) \ 163{ \ 164 return (__ ## fn(user_ns, inode, name, buffer, size, flags)); \ 165} 166/* 167 * 4.7 API change, 168 * The xattr_handler->set() callback was changed to take a both dentry and 169 * inode, because the dentry might not be attached to an inode yet. 170 */ 171#elif defined(HAVE_XATTR_SET_DENTRY_INODE) 172#define ZPL_XATTR_SET_WRAPPER(fn) \ 173static int \ 174fn(const struct xattr_handler *handler, struct dentry *dentry, \ 175 struct inode *inode, const char *name, const void *buffer, \ 176 size_t size, int flags) \ 177{ \ 178 return (__ ## fn(kcred->user_ns, inode, name, buffer, size, flags));\ 179} 180/* 181 * 4.4 API change, 182 * The xattr_handler->set() callback was changed to take a xattr_handler, 183 * and handler_flags argument was removed and should be accessed by 184 * handler->flags. 185 */ 186#elif defined(HAVE_XATTR_SET_HANDLER) 187#define ZPL_XATTR_SET_WRAPPER(fn) \ 188static int \ 189fn(const struct xattr_handler *handler, struct dentry *dentry, \ 190 const char *name, const void *buffer, size_t size, int flags) \ 191{ \ 192 return (__ ## fn(kcred->user_ns, dentry->d_inode, name, \ 193 buffer, size, flags)); \ 194} 195/* 196 * 2.6.33 API change, 197 * The xattr_handler->set() callback was changed to take a dentry 198 * instead of an inode, and a handler_flags argument was added. 199 */ 200#elif defined(HAVE_XATTR_SET_DENTRY) 201#define ZPL_XATTR_SET_WRAPPER(fn) \ 202static int \ 203fn(struct dentry *dentry, const char *name, const void *buffer, \ 204 size_t size, int flags, int unused_handler_flags) \ 205{ \ 206 return (__ ## fn(kcred->user_ns, dentry->d_inode, name, \ 207 buffer, size, flags)); \ 208} 209#else 210#error "Unsupported kernel" 211#endif 212 213/* 214 * Linux 3.7 API change. posix_acl_{from,to}_xattr gained the user_ns 215 * parameter. All callers are expected to pass the &init_user_ns which 216 * is available through the init credential (kcred). 217 */ 218static inline struct posix_acl * 219zpl_acl_from_xattr(const void *value, int size) 220{ 221 return (posix_acl_from_xattr(kcred->user_ns, value, size)); 222} 223 224static inline int 225zpl_acl_to_xattr(struct posix_acl *acl, void *value, int size) 226{ 227 return (posix_acl_to_xattr(kcred->user_ns, acl, value, size)); 228} 229 230#endif /* _ZFS_XATTR_H */ 231