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