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 */ 38 typedef 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) \ 45 static bool \ 46 fn(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) \ 55 static size_t \ 56 fn(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) \ 67 static size_t \ 68 fn(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) \ 85 static int \ 86 fn(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) \ 99 static int \ 100 fn(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) \ 112 static int \ 113 fn(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) \ 125 static int \ 126 fn(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) \ 144 static int \ 145 fn(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) \ 159 static int \ 160 fn(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) \ 173 static int \ 174 fn(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) \ 188 static int \ 189 fn(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) \ 202 static int \ 203 fn(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 */ 218 static inline struct posix_acl * 219 zpl_acl_from_xattr(const void *value, int size) 220 { 221 return (posix_acl_from_xattr(kcred->user_ns, value, size)); 222 } 223 224 static inline int 225 zpl_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