]> git.proxmox.com Git - mirror_zfs.git/blame - module/zfs/zpl_xattr.c
cstyle: Resolve C style issues
[mirror_zfs.git] / module / zfs / zpl_xattr.c
CommitLineData
cc5f931c
BB
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 http://www.opensolaris.org/os/licensing.
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 * Copyright (c) 2011, Lawrence Livermore National Security, LLC.
23 *
24 * Extended attributes (xattr) on Solaris are implemented as files
25 * which exist in a hidden xattr directory. These extended attributes
26 * can be accessed using the attropen() system call which opens
27 * the extended attribute. It can then be manipulated just like
28 * a standard file descriptor. This has a couple advantages such
29 * as practically no size limit on the file, and the extended
30 * attributes permissions may differ from those of the parent file.
31 * This interface is really quite clever, but it's also completely
82a37189
BB
32 * different than what is supported on Linux. It also comes with a
33 * steep performance penalty when accessing small xattrs because they
34 * are not stored with the parent file.
cc5f931c
BB
35 *
36 * Under Linux extended attributes are manipulated by the system
37 * calls getxattr(2), setxattr(2), and listxattr(2). They consider
38 * extended attributes to be name/value pairs where the name is a
39 * NULL terminated string. The name must also include one of the
82a37189 40 * following namespace prefixes:
cc5f931c
BB
41 *
42 * user - No restrictions and is available to user applications.
43 * trusted - Restricted to kernel and root (CAP_SYS_ADMIN) use.
44 * system - Used for access control lists (system.nfs4_acl, etc).
45 * security - Used by SELinux to store a files security context.
46 *
82a37189
BB
47 * The value under Linux to limited to 65536 bytes of binary data.
48 * In practice, individual xattrs tend to be much smaller than this
49 * and are typically less than 100 bytes. A good example of this
50 * are the security.selinux xattrs which are less than 100 bytes and
51 * exist for every file when xattr labeling is enabled.
cc5f931c 52 *
82a37189
BB
53 * The Linux xattr implemenation has been written to take advantage of
54 * this typical usage. When the dataset property 'xattr=sa' is set,
55 * then xattrs will be preferentially stored as System Attributes (SA).
56 * This allows tiny xattrs (~100 bytes) to be stored with the dnode and
57 * up to 64k of xattrs to be stored in the spill block. If additional
58 * xattr space is required, which is unlikely under Linux, they will
59 * be stored using the traditional directory approach.
cc5f931c 60 *
82a37189
BB
61 * This optimization results in roughly a 3x performance improvement
62 * when accessing xattrs because it avoids the need to perform a seek
63 * for every xattr value. When multiple xattrs are stored per-file
64 * the performance improvements are even greater because all of the
65 * xattrs stored in the spill block will be cached.
66 *
67 * However, by default SA based xattrs are disabled in the Linux port
68 * to maximize compatibility with other implementations. If you do
69 * enable SA based xattrs then they will not be visible on platforms
70 * which do not support this feature.
71 *
72 * NOTE: One additional consequence of the xattr directory implementation
73 * is that when an extended attribute is manipulated an inode is created.
74 * This inode will exist in the Linux inode cache but there will be no
75 * associated entry in the dentry cache which references it. This is
76 * safe but it may result in some confusion. Enabling SA based xattrs
77 * largely avoids the issue except in the overflow case.
cc5f931c
BB
78 */
79
cc5f931c
BB
80#include <sys/zfs_vfsops.h>
81#include <sys/zfs_vnops.h>
82#include <sys/zfs_znode.h>
0f37d0c8 83#include <sys/zap.h>
cc5f931c
BB
84#include <sys/vfs.h>
85#include <sys/zpl.h>
86
87typedef struct xattr_filldir {
88 size_t size;
89 size_t offset;
90 char *buf;
91 struct inode *inode;
92} xattr_filldir_t;
93
94static int
0f37d0c8 95zpl_xattr_filldir(xattr_filldir_t *xf, const char *name, int name_len)
cc5f931c 96{
d1d7e268 97 if (strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) == 0)
2cf7f52b 98 if (!(ITOZSB(xf->inode)->z_flags & ZSB_XATTR))
cc5f931c
BB
99 return (0);
100
d1d7e268 101 if (strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0)
cc5f931c
BB
102 if (!capable(CAP_SYS_ADMIN))
103 return (0);
104
105 /* When xf->buf is NULL only calculate the required size. */
106 if (xf->buf) {
107 if (xf->offset + name_len + 1 > xf->size)
108 return (-ERANGE);
109
110 memcpy(xf->buf + xf->offset, name, name_len);
111 xf->buf[xf->offset + name_len] = '\0';
112 }
113
114 xf->offset += (name_len + 1);
115
116 return (0);
117}
118
0f37d0c8
RY
119/*
120 * Read as many directory entry names as will fit in to the provided buffer,
121 * or when no buffer is provided calculate the required buffer size.
122 */
123int
124zpl_xattr_readdir(struct inode *dxip, xattr_filldir_t *xf)
125{
126 zap_cursor_t zc;
127 zap_attribute_t zap;
128 int error;
129
130 zap_cursor_init(&zc, ITOZSB(dxip)->z_os, ITOZ(dxip)->z_id);
131
132 while ((error = -zap_cursor_retrieve(&zc, &zap)) == 0) {
133
134 if (zap.za_integer_length != 8 || zap.za_num_integers != 1) {
135 error = -ENXIO;
136 break;
137 }
138
139 error = zpl_xattr_filldir(xf, zap.za_name, strlen(zap.za_name));
140 if (error)
141 break;
142
143 zap_cursor_advance(&zc);
144 }
145
146 zap_cursor_fini(&zc);
147
148 if (error == -ENOENT)
149 error = 0;
150
151 return (error);
152}
153
82a37189
BB
154static ssize_t
155zpl_xattr_list_dir(xattr_filldir_t *xf, cred_t *cr)
cc5f931c 156{
82a37189 157 struct inode *ip = xf->inode;
cc5f931c 158 struct inode *dxip = NULL;
cc5f931c 159 int error;
cc5f931c
BB
160
161 /* Lookup the xattr directory */
162 error = -zfs_lookup(ip, NULL, &dxip, LOOKUP_XATTR, cr, NULL, NULL);
163 if (error) {
164 if (error == -ENOENT)
165 error = 0;
166
82a37189 167 return (error);
cc5f931c
BB
168 }
169
0f37d0c8 170 error = zpl_xattr_readdir(dxip, xf);
82a37189
BB
171 iput(dxip);
172
173 return (error);
174}
175
176static ssize_t
177zpl_xattr_list_sa(xattr_filldir_t *xf)
178{
179 znode_t *zp = ITOZ(xf->inode);
180 nvpair_t *nvp = NULL;
181 int error = 0;
182
183 mutex_enter(&zp->z_lock);
184 if (zp->z_xattr_cached == NULL)
185 error = -zfs_sa_get_xattr(zp);
186 mutex_exit(&zp->z_lock);
187
188 if (error)
189 return (error);
190
191 ASSERT(zp->z_xattr_cached);
192
193 while ((nvp = nvlist_next_nvpair(zp->z_xattr_cached, nvp)) != NULL) {
194 ASSERT3U(nvpair_type(nvp), ==, DATA_TYPE_BYTE_ARRAY);
195
0f37d0c8 196 error = zpl_xattr_filldir(xf, nvpair_name(nvp),
d1d7e268 197 strlen(nvpair_name(nvp)));
82a37189
BB
198 if (error)
199 return (error);
200 }
201
202 return (0);
203}
204
205ssize_t
206zpl_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
207{
208 znode_t *zp = ITOZ(dentry->d_inode);
209 zfs_sb_t *zsb = ZTOZSB(zp);
210 xattr_filldir_t xf = { buffer_size, 0, buffer, dentry->d_inode };
211 cred_t *cr = CRED();
212 int error = 0;
213
214 crhold(cr);
215 rw_enter(&zp->z_xattr_lock, RW_READER);
216
217 if (zsb->z_use_sa && zp->z_is_sa) {
218 error = zpl_xattr_list_sa(&xf);
219 if (error)
220 goto out;
221 }
222
223 error = zpl_xattr_list_dir(&xf, cr);
cc5f931c
BB
224 if (error)
225 goto out;
226
227 error = xf.offset;
228out:
cc5f931c 229
82a37189 230 rw_exit(&zp->z_xattr_lock);
81e97e21 231 crfree(cr);
cc5f931c
BB
232
233 return (error);
234}
235
236static int
82a37189
BB
237zpl_xattr_get_dir(struct inode *ip, const char *name, void *value,
238 size_t size, cred_t *cr)
cc5f931c
BB
239{
240 struct inode *dxip = NULL;
241 struct inode *xip = NULL;
cc5f931c
BB
242 int error;
243
cc5f931c
BB
244 /* Lookup the xattr directory */
245 error = -zfs_lookup(ip, NULL, &dxip, LOOKUP_XATTR, cr, NULL, NULL);
246 if (error)
247 goto out;
248
249 /* Lookup a specific xattr name in the directory */
250 error = -zfs_lookup(dxip, (char *)name, &xip, 0, cr, NULL, NULL);
251 if (error)
252 goto out;
253
254 if (!size) {
255 error = i_size_read(xip);
256 goto out;
257 }
258
f7064211
BB
259 if (size < i_size_read(xip)) {
260 error = -ERANGE;
261 goto out;
262 }
263
82a37189 264 error = zpl_read_common(xip, value, size, 0, UIO_SYSSPACE, 0, cr);
cc5f931c
BB
265out:
266 if (xip)
267 iput(xip);
268
269 if (dxip)
270 iput(dxip);
271
82a37189
BB
272 return (error);
273}
274
275static int
276zpl_xattr_get_sa(struct inode *ip, const char *name, void *value, size_t size)
277{
278 znode_t *zp = ITOZ(ip);
279 uchar_t *nv_value;
280 uint_t nv_size;
281 int error = 0;
cc5f931c 282
82a37189
BB
283 ASSERT(RW_LOCK_HELD(&zp->z_xattr_lock));
284
285 mutex_enter(&zp->z_lock);
286 if (zp->z_xattr_cached == NULL)
287 error = -zfs_sa_get_xattr(zp);
288 mutex_exit(&zp->z_lock);
289
290 if (error)
291 return (error);
292
293 ASSERT(zp->z_xattr_cached);
294 error = -nvlist_lookup_byte_array(zp->z_xattr_cached, name,
295 &nv_value, &nv_size);
296 if (error)
297 return (error);
298
299 if (!size)
300 return (nv_size);
301
f7064211
BB
302 if (size < nv_size)
303 return (-ERANGE);
304
305 memcpy(value, nv_value, nv_size);
82a37189 306
f7064211 307 return (nv_size);
82a37189
BB
308}
309
310static int
311__zpl_xattr_get(struct inode *ip, const char *name, void *value, size_t size,
312 cred_t *cr)
313{
314 znode_t *zp = ITOZ(ip);
315 zfs_sb_t *zsb = ZTOZSB(zp);
316 int error;
317
318 ASSERT(RW_LOCK_HELD(&zp->z_xattr_lock));
319
320 if (zsb->z_use_sa && zp->z_is_sa) {
321 error = zpl_xattr_get_sa(ip, name, value, size);
0377189b 322 if (error != -ENOENT)
82a37189
BB
323 goto out;
324 }
325
326 error = zpl_xattr_get_dir(ip, name, value, size, cr);
327out:
cc5f931c
BB
328 if (error == -ENOENT)
329 error = -ENODATA;
330
331 return (error);
332}
333
334static int
82a37189
BB
335zpl_xattr_get(struct inode *ip, const char *name, void *value, size_t size)
336{
337 znode_t *zp = ITOZ(ip);
338 cred_t *cr = CRED();
339 int error;
340
341 crhold(cr);
342 rw_enter(&zp->z_xattr_lock, RW_READER);
343 error = __zpl_xattr_get(ip, name, value, size, cr);
344 rw_exit(&zp->z_xattr_lock);
345 crfree(cr);
346
347 return (error);
348}
349
350static int
351zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
352 size_t size, int flags, cred_t *cr)
cc5f931c
BB
353{
354 struct inode *dxip = NULL;
355 struct inode *xip = NULL;
356 vattr_t *vap = NULL;
cc5f931c 357 ssize_t wrote;
fc9e0530 358 int lookup_flags, error;
bec30953 359 const int xattr_mode = S_IFREG | 0644;
cc5f931c 360
fc9e0530
BB
361 /*
362 * Lookup the xattr directory. When we're adding an entry pass
363 * CREATE_XATTR_DIR to ensure the xattr directory is created.
364 * When removing an entry this flag is not passed to avoid
365 * unnecessarily creating a new xattr directory.
366 */
367 lookup_flags = LOOKUP_XATTR;
368 if (value != NULL)
369 lookup_flags |= CREATE_XATTR_DIR;
370
371 error = -zfs_lookup(ip, NULL, &dxip, lookup_flags, cr, NULL, NULL);
cc5f931c
BB
372 if (error)
373 goto out;
374
82a37189 375 /* Lookup a specific xattr name in the directory */
cc5f931c 376 error = -zfs_lookup(dxip, (char *)name, &xip, 0, cr, NULL, NULL);
82a37189
BB
377 if (error && (error != -ENOENT))
378 goto out;
cc5f931c 379
cc5f931c
BB
380 error = 0;
381
382 /* Remove a specific name xattr when value is set to NULL. */
383 if (value == NULL) {
384 if (xip)
385 error = -zfs_remove(dxip, (char *)name, cr);
386
387 goto out;
388 }
389
390 /* Lookup failed create a new xattr. */
391 if (xip == NULL) {
d1d7e268 392 vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
bec30953 393 vap->va_mode = xattr_mode;
cc5f931c 394 vap->va_mask = ATTR_MODE;
81e97e21
BB
395 vap->va_uid = crgetfsuid(cr);
396 vap->va_gid = crgetfsgid(cr);
cc5f931c
BB
397
398 error = -zfs_create(dxip, (char *)name, vap, 0, 0644, &xip,
399 cr, 0, NULL);
400 if (error)
401 goto out;
402 }
403
404 ASSERT(xip != NULL);
bec30953
GB
405
406 error = -zfs_freesp(ITOZ(xip), 0, 0, xattr_mode, TRUE);
407 if (error)
408 goto out;
409
cc5f931c
BB
410 wrote = zpl_write_common(xip, value, size, 0, UIO_SYSSPACE, 0, cr);
411 if (wrote < 0)
412 error = wrote;
413
414out:
415 if (vap)
d1d7e268 416 kmem_free(vap, sizeof (vattr_t));
cc5f931c
BB
417
418 if (xip)
419 iput(xip);
420
421 if (dxip)
422 iput(dxip);
423
cc5f931c
BB
424 if (error == -ENOENT)
425 error = -ENODATA;
426
427 ASSERT3S(error, <=, 0);
428
429 return (error);
430}
431
82a37189
BB
432static int
433zpl_xattr_set_sa(struct inode *ip, const char *name, const void *value,
434 size_t size, int flags, cred_t *cr)
435{
436 znode_t *zp = ITOZ(ip);
437 nvlist_t *nvl;
438 size_t sa_size;
439 int error;
440
441 ASSERT(zp->z_xattr_cached);
442 nvl = zp->z_xattr_cached;
443
444 if (value == NULL) {
445 error = -nvlist_remove(nvl, name, DATA_TYPE_BYTE_ARRAY);
446 if (error == -ENOENT)
447 error = zpl_xattr_set_dir(ip, name, NULL, 0, flags, cr);
448 } else {
449 /* Limited to 32k to keep nvpair memory allocations small */
450 if (size > DXATTR_MAX_ENTRY_SIZE)
451 return (-EFBIG);
452
453 /* Prevent the DXATTR SA from consuming the entire SA region */
454 error = -nvlist_size(nvl, &sa_size, NV_ENCODE_XDR);
455 if (error)
456 return (error);
457
458 if (sa_size > DXATTR_MAX_SA_SIZE)
459 return (-EFBIG);
460
461 error = -nvlist_add_byte_array(nvl, name,
462 (uchar_t *)value, size);
463 if (error)
464 return (error);
465 }
466
467 /* Update the SA for additions, modifications, and removals. */
468 if (!error)
469 error = -zfs_sa_set_xattr(zp);
470
471 ASSERT3S(error, <=, 0);
472
473 return (error);
474}
475
476static int
477zpl_xattr_set(struct inode *ip, const char *name, const void *value,
478 size_t size, int flags)
479{
480 znode_t *zp = ITOZ(ip);
481 zfs_sb_t *zsb = ZTOZSB(zp);
482 cred_t *cr = CRED();
483 int error;
484
485 crhold(cr);
486 rw_enter(&ITOZ(ip)->z_xattr_lock, RW_WRITER);
487
488 /*
489 * Before setting the xattr check to see if it already exists.
490 * This is done to ensure the following optional flags are honored.
491 *
492 * XATTR_CREATE: fail if xattr already exists
493 * XATTR_REPLACE: fail if xattr does not exist
494 */
495 error = __zpl_xattr_get(ip, name, NULL, 0, cr);
496 if (error < 0) {
497 if (error != -ENODATA)
498 goto out;
499
fc9e0530
BB
500 if (flags & XATTR_REPLACE)
501 goto out;
502
503 /* The xattr to be removed already doesn't exist */
504 error = 0;
505 if (value == NULL)
82a37189
BB
506 goto out;
507 } else {
508 error = -EEXIST;
509 if (flags & XATTR_CREATE)
510 goto out;
511 }
512
513 /* Preferentially store the xattr as a SA for better performance */
514 if (zsb->z_use_sa && zsb->z_xattr_sa && zp->z_is_sa) {
515 error = zpl_xattr_set_sa(ip, name, value, size, flags, cr);
516 if (error == 0)
517 goto out;
518 }
519
520 error = zpl_xattr_set_dir(ip, name, value, size, flags, cr);
521out:
522 rw_exit(&ITOZ(ip)->z_xattr_lock);
523 crfree(cr);
524 ASSERT3S(error, <=, 0);
525
526 return (error);
527}
528
cc5f931c 529static int
f9637c6c 530__zpl_xattr_user_get(struct inode *ip, const char *name,
82a37189 531 void *value, size_t size)
cc5f931c
BB
532{
533 char *xattr_name;
534 int error;
535
536 if (strcmp(name, "") == 0)
d1d7e268 537 return (-EINVAL);
cc5f931c 538
2cf7f52b 539 if (!(ITOZSB(ip)->z_flags & ZSB_XATTR))
d1d7e268 540 return (-EOPNOTSUPP);
cc5f931c
BB
541
542 xattr_name = kmem_asprintf("%s%s", XATTR_USER_PREFIX, name);
82a37189 543 error = zpl_xattr_get(ip, xattr_name, value, size);
cc5f931c
BB
544 strfree(xattr_name);
545
546 return (error);
547}
f9637c6c 548ZPL_XATTR_GET_WRAPPER(zpl_xattr_user_get);
cc5f931c
BB
549
550static int
f9637c6c 551__zpl_xattr_user_set(struct inode *ip, const char *name,
cc5f931c
BB
552 const void *value, size_t size, int flags)
553{
554 char *xattr_name;
555 int error;
556
557 if (strcmp(name, "") == 0)
d1d7e268 558 return (-EINVAL);
cc5f931c 559
2cf7f52b 560 if (!(ITOZSB(ip)->z_flags & ZSB_XATTR))
d1d7e268 561 return (-EOPNOTSUPP);
cc5f931c
BB
562
563 xattr_name = kmem_asprintf("%s%s", XATTR_USER_PREFIX, name);
564 error = zpl_xattr_set(ip, xattr_name, value, size, flags);
565 strfree(xattr_name);
566
567 return (error);
568}
f9637c6c 569ZPL_XATTR_SET_WRAPPER(zpl_xattr_user_set);
cc5f931c 570
777d4af8 571xattr_handler_t zpl_xattr_user_handler = {
cc5f931c
BB
572 .prefix = XATTR_USER_PREFIX,
573 .get = zpl_xattr_user_get,
574 .set = zpl_xattr_user_set,
575};
576
577static int
f9637c6c 578__zpl_xattr_trusted_get(struct inode *ip, const char *name,
82a37189 579 void *value, size_t size)
cc5f931c
BB
580{
581 char *xattr_name;
582 int error;
583
584 if (!capable(CAP_SYS_ADMIN))
d1d7e268 585 return (-EACCES);
cc5f931c
BB
586
587 if (strcmp(name, "") == 0)
d1d7e268 588 return (-EINVAL);
cc5f931c
BB
589
590 xattr_name = kmem_asprintf("%s%s", XATTR_TRUSTED_PREFIX, name);
82a37189 591 error = zpl_xattr_get(ip, xattr_name, value, size);
cc5f931c
BB
592 strfree(xattr_name);
593
594 return (error);
595}
f9637c6c 596ZPL_XATTR_GET_WRAPPER(zpl_xattr_trusted_get);
cc5f931c
BB
597
598static int
f9637c6c 599__zpl_xattr_trusted_set(struct inode *ip, const char *name,
cc5f931c
BB
600 const void *value, size_t size, int flags)
601{
602 char *xattr_name;
603 int error;
604
605 if (!capable(CAP_SYS_ADMIN))
d1d7e268 606 return (-EACCES);
cc5f931c
BB
607
608 if (strcmp(name, "") == 0)
d1d7e268 609 return (-EINVAL);
cc5f931c
BB
610
611 xattr_name = kmem_asprintf("%s%s", XATTR_TRUSTED_PREFIX, name);
612 error = zpl_xattr_set(ip, xattr_name, value, size, flags);
613 strfree(xattr_name);
614
615 return (error);
616}
f9637c6c 617ZPL_XATTR_SET_WRAPPER(zpl_xattr_trusted_set);
cc5f931c 618
777d4af8 619xattr_handler_t zpl_xattr_trusted_handler = {
cc5f931c
BB
620 .prefix = XATTR_TRUSTED_PREFIX,
621 .get = zpl_xattr_trusted_get,
622 .set = zpl_xattr_trusted_set,
623};
624
625static int
f9637c6c 626__zpl_xattr_security_get(struct inode *ip, const char *name,
82a37189 627 void *value, size_t size)
cc5f931c
BB
628{
629 char *xattr_name;
630 int error;
631
632 if (strcmp(name, "") == 0)
d1d7e268 633 return (-EINVAL);
cc5f931c
BB
634
635 xattr_name = kmem_asprintf("%s%s", XATTR_SECURITY_PREFIX, name);
82a37189 636 error = zpl_xattr_get(ip, xattr_name, value, size);
cc5f931c
BB
637 strfree(xattr_name);
638
639 return (error);
640}
f9637c6c 641ZPL_XATTR_GET_WRAPPER(zpl_xattr_security_get);
cc5f931c
BB
642
643static int
f9637c6c 644__zpl_xattr_security_set(struct inode *ip, const char *name,
cc5f931c
BB
645 const void *value, size_t size, int flags)
646{
647 char *xattr_name;
648 int error;
649
650 if (strcmp(name, "") == 0)
d1d7e268 651 return (-EINVAL);
cc5f931c
BB
652
653 xattr_name = kmem_asprintf("%s%s", XATTR_SECURITY_PREFIX, name);
654 error = zpl_xattr_set(ip, xattr_name, value, size, flags);
655 strfree(xattr_name);
656
657 return (error);
658}
f9637c6c 659ZPL_XATTR_SET_WRAPPER(zpl_xattr_security_set);
cc5f931c 660
166dd49d
BB
661#ifdef HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY
662static int
663__zpl_xattr_security_init(struct inode *ip, const struct xattr *xattrs,
664 void *fs_info)
665{
666 const struct xattr *xattr;
667 int error = 0;
668
669 for (xattr = xattrs; xattr->name != NULL; xattr++) {
670 error = __zpl_xattr_security_set(ip,
671 xattr->name, xattr->value, xattr->value_len, 0);
672
673 if (error < 0)
674 break;
675 }
676
96b91ef0 677 return (error);
166dd49d
BB
678}
679
680int
681zpl_xattr_security_init(struct inode *ip, struct inode *dip,
682 const struct qstr *qstr)
683{
684 return security_inode_init_security(ip, dip, qstr,
685 &__zpl_xattr_security_init, NULL);
686}
687
688#else
cc5f931c 689int
5c03efc3
BB
690zpl_xattr_security_init(struct inode *ip, struct inode *dip,
691 const struct qstr *qstr)
cc5f931c 692{
96b91ef0
DH
693 int error;
694 size_t len;
695 void *value;
696 char *name;
cc5f931c 697
96b91ef0 698 error = zpl_security_inode_init_security(ip, dip, qstr,
d1d7e268 699 &name, &value, &len);
96b91ef0
DH
700 if (error) {
701 if (error == -EOPNOTSUPP)
d1d7e268
MK
702 return (0);
703
96b91ef0
DH
704 return (error);
705 }
cc5f931c 706
f9637c6c 707 error = __zpl_xattr_security_set(ip, name, value, len, 0);
cc5f931c 708
96b91ef0
DH
709 kfree(name);
710 kfree(value);
cc5f931c 711
96b91ef0 712 return (error);
cc5f931c 713}
166dd49d 714#endif /* HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY */
cc5f931c 715
777d4af8 716xattr_handler_t zpl_xattr_security_handler = {
cc5f931c
BB
717 .prefix = XATTR_SECURITY_PREFIX,
718 .get = zpl_xattr_security_get,
719 .set = zpl_xattr_security_set,
720};
721
b695c34e
MM
722#ifdef CONFIG_FS_POSIX_ACL
723
023699cd
MM
724int
725zpl_set_acl(struct inode *ip, int type, struct posix_acl *acl)
726{
727 struct super_block *sb = ITOZSB(ip)->z_sb;
728 char *name, *value = NULL;
729 int error = 0;
730 size_t size = 0;
731
732 if (S_ISLNK(ip->i_mode))
733 return (-EOPNOTSUPP);
734
d1d7e268 735 switch (type) {
023699cd
MM
736 case ACL_TYPE_ACCESS:
737 name = POSIX_ACL_XATTR_ACCESS;
738 if (acl) {
739 zpl_equivmode_t mode = ip->i_mode;
740 error = posix_acl_equiv_mode(acl, &mode);
741 if (error < 0) {
742 return (error);
743 } else {
744 /*
745 * The mode bits will have been set by
746 * ->zfs_setattr()->zfs_acl_chmod_setattr()
747 * using the ZFS ACL conversion. If they
748 * differ from the Posix ACL conversion dirty
749 * the inode to write the Posix mode bits.
750 */
751 if (ip->i_mode != mode) {
752 ip->i_mode = mode;
753 ip->i_ctime = current_fs_time(sb);
754 mark_inode_dirty(ip);
755 }
756
757 if (error == 0)
758 acl = NULL;
759 }
760 }
761 break;
762
763 case ACL_TYPE_DEFAULT:
764 name = POSIX_ACL_XATTR_DEFAULT;
765 if (!S_ISDIR(ip->i_mode))
766 return (acl ? -EACCES : 0);
767 break;
768
769 default:
770 return (-EINVAL);
771 }
772
773 if (acl) {
774 size = posix_acl_xattr_size(acl->a_count);
775 value = kmem_alloc(size, KM_SLEEP);
776
777 error = zpl_acl_to_xattr(acl, value, size);
778 if (error < 0) {
779 kmem_free(value, size);
780 return (error);
781 }
782 }
783
784 error = zpl_xattr_set(ip, name, value, size, 0);
785 if (value)
786 kmem_free(value, size);
787
788 if (!error) {
789 if (acl)
790 zpl_set_cached_acl(ip, type, acl);
791 else
792 zpl_forget_cached_acl(ip, type);
793 }
794
795 return (error);
796}
797
798struct posix_acl *
799zpl_get_acl(struct inode *ip, int type)
800{
801 struct posix_acl *acl;
802 void *value = NULL;
803 char *name;
804 int size;
805
806#ifdef HAVE_POSIX_ACL_CACHING
807 acl = get_cached_acl(ip, type);
808 if (acl != ACL_NOT_CACHED)
809 return (acl);
810#endif /* HAVE_POSIX_ACL_CACHING */
811
812 switch (type) {
813 case ACL_TYPE_ACCESS:
814 name = POSIX_ACL_XATTR_ACCESS;
815 break;
816 case ACL_TYPE_DEFAULT:
817 name = POSIX_ACL_XATTR_DEFAULT;
818 break;
819 default:
d1d7e268 820 return (ERR_PTR(-EINVAL));
023699cd
MM
821 }
822
823 size = zpl_xattr_get(ip, name, NULL, 0);
824 if (size > 0) {
825 value = kmem_alloc(size, KM_PUSHPAGE);
826 size = zpl_xattr_get(ip, name, value, size);
827 }
828
829 if (size > 0) {
830 acl = zpl_acl_from_xattr(value, size);
831 } else if (size == -ENODATA || size == -ENOSYS) {
832 acl = NULL;
833 } else {
834 acl = ERR_PTR(-EIO);
835 }
836
837 if (size > 0)
838 kmem_free(value, size);
839
840 if (!IS_ERR(acl))
841 zpl_set_cached_acl(ip, type, acl);
842
843 return (acl);
844}
845
846#if !defined(HAVE_GET_ACL)
847static int
848__zpl_check_acl(struct inode *ip, int mask)
849{
850 struct posix_acl *acl;
851 int error;
852
853 acl = zpl_get_acl(ip, ACL_TYPE_ACCESS);
854 if (IS_ERR(acl))
855 return (PTR_ERR(acl));
856
857 if (acl) {
858 error = posix_acl_permission(ip, acl, mask);
859 zpl_posix_acl_release(acl);
860 return (error);
861 }
862
863 return (-EAGAIN);
864}
865
866#if defined(HAVE_CHECK_ACL_WITH_FLAGS)
867int
868zpl_check_acl(struct inode *ip, int mask, unsigned int flags)
869{
d1d7e268 870 return (__zpl_check_acl(ip, mask));
023699cd
MM
871}
872#elif defined(HAVE_CHECK_ACL)
873int
874zpl_check_acl(struct inode *ip, int mask)
875{
d1d7e268 876 return (__zpl_check_acl(ip, mask));
023699cd
MM
877}
878#elif defined(HAVE_PERMISSION_WITH_NAMEIDATA)
879int
880zpl_permission(struct inode *ip, int mask, struct nameidata *nd)
881{
d1d7e268 882 return (generic_permission(ip, mask, __zpl_check_acl));
023699cd
MM
883}
884#elif defined(HAVE_PERMISSION)
885int
886zpl_permission(struct inode *ip, int mask)
887{
d1d7e268 888 return (generic_permission(ip, mask, __zpl_check_acl));
023699cd
MM
889}
890#endif /* HAVE_CHECK_ACL | HAVE_PERMISSION */
891#endif /* !HAVE_GET_ACL */
892
893int
894zpl_init_acl(struct inode *ip, struct inode *dir)
895{
896 struct posix_acl *acl = NULL;
897 int error = 0;
898
899 if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
900 return (0);
901
902 if (!S_ISLNK(ip->i_mode)) {
903 if (ITOZSB(ip)->z_acl_type == ZFS_ACLTYPE_POSIXACL) {
904 acl = zpl_get_acl(dir, ACL_TYPE_DEFAULT);
905 if (IS_ERR(acl))
906 return (PTR_ERR(acl));
907 }
908
909 if (!acl) {
910 ip->i_mode &= ~current_umask();
911 ip->i_ctime = current_fs_time(ITOZSB(ip)->z_sb);
912 mark_inode_dirty(ip);
913 return (0);
914 }
915 }
916
917 if ((ITOZSB(ip)->z_acl_type == ZFS_ACLTYPE_POSIXACL) && acl) {
918 umode_t mode;
919
920 if (S_ISDIR(ip->i_mode)) {
921 error = zpl_set_acl(ip, ACL_TYPE_DEFAULT, acl);
922 if (error)
923 goto out;
924 }
925
926 mode = ip->i_mode;
d1d7e268 927 error = posix_acl_create(&acl, GFP_KERNEL, &mode);
023699cd
MM
928 if (error >= 0) {
929 ip->i_mode = mode;
930 mark_inode_dirty(ip);
931 if (error > 0)
932 error = zpl_set_acl(ip, ACL_TYPE_ACCESS, acl);
933 }
934 }
935out:
936 zpl_posix_acl_release(acl);
937
938 return (error);
939}
940
941int
942zpl_chmod_acl(struct inode *ip)
943{
944 struct posix_acl *acl;
945 int error;
946
947 if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
948 return (0);
949
950 if (S_ISLNK(ip->i_mode))
951 return (-EOPNOTSUPP);
952
953 acl = zpl_get_acl(ip, ACL_TYPE_ACCESS);
954 if (IS_ERR(acl) || !acl)
955 return (PTR_ERR(acl));
956
d1d7e268 957 error = posix_acl_chmod(&acl, GFP_KERNEL, ip->i_mode);
023699cd 958 if (!error)
d1d7e268 959 error = zpl_set_acl(ip, ACL_TYPE_ACCESS, acl);
023699cd
MM
960
961 zpl_posix_acl_release(acl);
962
963 return (error);
964}
965
966static size_t
967zpl_xattr_acl_list(struct inode *ip, char *list, size_t list_size,
968 const char *name, size_t name_len, int type)
969{
970 char *xattr_name;
971 size_t xattr_size;
972
973 if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
974 return (0);
975
976 switch (type) {
977 case ACL_TYPE_ACCESS:
978 xattr_name = POSIX_ACL_XATTR_ACCESS;
d1d7e268 979 xattr_size = sizeof (xattr_name);
023699cd
MM
980 break;
981 case ACL_TYPE_DEFAULT:
982 xattr_name = POSIX_ACL_XATTR_DEFAULT;
d1d7e268 983 xattr_size = sizeof (xattr_name);
023699cd
MM
984 break;
985 default:
986 return (0);
987 }
988
989 if (list && xattr_size <= list_size)
990 memcpy(list, xattr_name, xattr_size);
991
992 return (xattr_size);
993}
994
995#ifdef HAVE_DENTRY_XATTR_LIST
996static size_t
997zpl_xattr_acl_list_access(struct dentry *dentry, char *list,
998 size_t list_size, const char *name, size_t name_len, int type)
999{
1000 ASSERT3S(type, ==, ACL_TYPE_ACCESS);
1001 return zpl_xattr_acl_list(dentry->d_inode,
1002 list, list_size, name, name_len, type);
1003}
1004
1005static size_t
1006zpl_xattr_acl_list_default(struct dentry *dentry, char *list,
1007 size_t list_size, const char *name, size_t name_len, int type)
1008{
1009 ASSERT3S(type, ==, ACL_TYPE_DEFAULT);
1010 return zpl_xattr_acl_list(dentry->d_inode,
1011 list, list_size, name, name_len, type);
1012}
1013
1014#else
1015
1016static size_t
1017zpl_xattr_acl_list_access(struct inode *ip, char *list, size_t list_size,
1018 const char *name, size_t name_len)
1019{
1020 return zpl_xattr_acl_list(ip,
1021 list, list_size, name, name_len, ACL_TYPE_ACCESS);
1022}
1023
1024static size_t
1025zpl_xattr_acl_list_default(struct inode *ip, char *list, size_t list_size,
1026 const char *name, size_t name_len)
1027{
1028 return zpl_xattr_acl_list(ip,
1029 list, list_size, name, name_len, ACL_TYPE_DEFAULT);
1030}
1031#endif /* HAVE_DENTRY_XATTR_LIST */
1032
1033static int
1034zpl_xattr_acl_get(struct inode *ip, const char *name,
1035 void *buffer, size_t size, int type)
1036{
1037 struct posix_acl *acl;
1038 int error;
1039
1040 if (strcmp(name, "") != 0)
1041 return (-EINVAL);
1042
1043 if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
1044 return (-EOPNOTSUPP);
1045
1046 acl = zpl_get_acl(ip, type);
1047 if (IS_ERR(acl))
1048 return (PTR_ERR(acl));
1049 if (acl == NULL)
1050 return (-ENODATA);
1051
1052 error = zpl_acl_to_xattr(acl, buffer, size);
1053 zpl_posix_acl_release(acl);
1054
1055 return (error);
1056}
1057
1058#ifdef HAVE_DENTRY_XATTR_GET
1059static int
1060zpl_xattr_acl_get_access(struct dentry *dentry, const char *name,
1061 void *buffer, size_t size, int type)
1062{
1063 ASSERT3S(type, ==, ACL_TYPE_ACCESS);
d1d7e268 1064 return (zpl_xattr_acl_get(dentry->d_inode, name, buffer, size, type));
023699cd
MM
1065}
1066
1067static int
1068zpl_xattr_acl_get_default(struct dentry *dentry, const char *name,
1069 void *buffer, size_t size, int type)
1070{
1071 ASSERT3S(type, ==, ACL_TYPE_DEFAULT);
d1d7e268 1072 return (zpl_xattr_acl_get(dentry->d_inode, name, buffer, size, type));
023699cd
MM
1073}
1074
1075#else
1076
1077static int
1078zpl_xattr_acl_get_access(struct inode *ip, const char *name,
1079 void *buffer, size_t size)
1080{
d1d7e268 1081 return (zpl_xattr_acl_get(ip, name, buffer, size, ACL_TYPE_ACCESS));
023699cd
MM
1082}
1083
1084static int
1085zpl_xattr_acl_get_default(struct inode *ip, const char *name,
1086 void *buffer, size_t size)
1087{
d1d7e268 1088 return (zpl_xattr_acl_get(ip, name, buffer, size, ACL_TYPE_DEFAULT));
023699cd
MM
1089}
1090#endif /* HAVE_DENTRY_XATTR_GET */
1091
1092static int
1093zpl_xattr_acl_set(struct inode *ip, const char *name,
1094 const void *value, size_t size, int flags, int type)
1095{
1096 struct posix_acl *acl;
1097 int error = 0;
1098
1099 if (strcmp(name, "") != 0)
1100 return (-EINVAL);
1101
1102 if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
1103 return (-EOPNOTSUPP);
1104
1105 if (!zpl_inode_owner_or_capable(ip))
1106 return (-EPERM);
1107
1108 if (value) {
1109 acl = zpl_acl_from_xattr(value, size);
1110 if (IS_ERR(acl))
1111 return (PTR_ERR(acl));
1112 else if (acl) {
1113 error = posix_acl_valid(acl);
1114 if (error) {
1115 zpl_posix_acl_release(acl);
1116 return (error);
1117 }
1118 }
1119 } else {
1120 acl = NULL;
1121 }
1122
1123 error = zpl_set_acl(ip, type, acl);
1124 zpl_posix_acl_release(acl);
1125
1126 return (error);
1127}
1128
1129#ifdef HAVE_DENTRY_XATTR_SET
1130static int
1131zpl_xattr_acl_set_access(struct dentry *dentry, const char *name,
1132 const void *value, size_t size, int flags, int type)
1133{
d1d7e268
MK
1134 ASSERT3S(type, ==, ACL_TYPE_ACCESS);
1135 return (zpl_xattr_acl_set(dentry->d_inode,
1136 name, value, size, flags, type));
023699cd
MM
1137}
1138
1139static int
1140zpl_xattr_acl_set_default(struct dentry *dentry, const char *name,
d1d7e268 1141 const void *value, size_t size, int flags, int type)
023699cd 1142{
d1d7e268
MK
1143 ASSERT3S(type, ==, ACL_TYPE_DEFAULT);
1144 return zpl_xattr_acl_set(dentry->d_inode,
023699cd
MM
1145 name, value, size, flags, type);
1146}
1147
1148#else
1149
1150static int
1151zpl_xattr_acl_set_access(struct inode *ip, const char *name,
1152 const void *value, size_t size, int flags)
1153{
d1d7e268 1154 return zpl_xattr_acl_set(ip,
023699cd
MM
1155 name, value, size, flags, ACL_TYPE_ACCESS);
1156}
1157
1158static int
1159zpl_xattr_acl_set_default(struct inode *ip, const char *name,
1160 const void *value, size_t size, int flags)
1161{
d1d7e268 1162 return zpl_xattr_acl_set(ip,
023699cd
MM
1163 name, value, size, flags, ACL_TYPE_DEFAULT);
1164}
1165#endif /* HAVE_DENTRY_XATTR_SET */
1166
1167struct xattr_handler zpl_xattr_acl_access_handler =
1168{
1169 .prefix = POSIX_ACL_XATTR_ACCESS,
1170 .list = zpl_xattr_acl_list_access,
1171 .get = zpl_xattr_acl_get_access,
1172 .set = zpl_xattr_acl_set_access,
1173#ifdef HAVE_DENTRY_XATTR_LIST
1174 .flags = ACL_TYPE_ACCESS,
1175#endif /* HAVE_DENTRY_XATTR_LIST */
1176};
1177
1178struct xattr_handler zpl_xattr_acl_default_handler =
1179{
1180 .prefix = POSIX_ACL_XATTR_DEFAULT,
1181 .list = zpl_xattr_acl_list_default,
1182 .get = zpl_xattr_acl_get_default,
1183 .set = zpl_xattr_acl_set_default,
1184#ifdef HAVE_DENTRY_XATTR_LIST
1185 .flags = ACL_TYPE_DEFAULT,
1186#endif /* HAVE_DENTRY_XATTR_LIST */
1187};
1188
b695c34e
MM
1189#endif /* CONFIG_FS_POSIX_ACL */
1190
777d4af8 1191xattr_handler_t *zpl_xattr_handlers[] = {
cc5f931c
BB
1192 &zpl_xattr_security_handler,
1193 &zpl_xattr_trusted_handler,
1194 &zpl_xattr_user_handler,
b695c34e 1195#ifdef CONFIG_FS_POSIX_ACL
cc5f931c 1196 &zpl_xattr_acl_access_handler,
96b91ef0 1197 &zpl_xattr_acl_default_handler,
b695c34e 1198#endif /* CONFIG_FS_POSIX_ACL */
77a405ae 1199 NULL
cc5f931c 1200};