]> git.proxmox.com Git - mirror_zfs-debian.git/blame - module/zfs/zpl_xattr.c
Imported Upstream version 0.6.4.2
[mirror_zfs-debian.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>
c06d4368 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
c06d4368 95zpl_xattr_filldir(xattr_filldir_t *xf, const char *name, int name_len)
cc5f931c 96{
a08ee875 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
a08ee875 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
c06d4368
AX
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
c06d4368 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
c06d4368 196 error = zpl_xattr_filldir(xf, nvpair_name(nvp),
a08ee875 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();
ea04106b 212 fstrans_cookie_t cookie;
82a37189
BB
213 int error = 0;
214
215 crhold(cr);
ea04106b 216 cookie = spl_fstrans_mark();
82a37189
BB
217 rw_enter(&zp->z_xattr_lock, RW_READER);
218
219 if (zsb->z_use_sa && zp->z_is_sa) {
220 error = zpl_xattr_list_sa(&xf);
221 if (error)
222 goto out;
223 }
224
225 error = zpl_xattr_list_dir(&xf, cr);
cc5f931c
BB
226 if (error)
227 goto out;
228
229 error = xf.offset;
230out:
cc5f931c 231
82a37189 232 rw_exit(&zp->z_xattr_lock);
ea04106b 233 spl_fstrans_unmark(cookie);
81e97e21 234 crfree(cr);
cc5f931c
BB
235
236 return (error);
237}
238
239static int
82a37189
BB
240zpl_xattr_get_dir(struct inode *ip, const char *name, void *value,
241 size_t size, cred_t *cr)
cc5f931c
BB
242{
243 struct inode *dxip = NULL;
244 struct inode *xip = NULL;
ea04106b 245 loff_t pos = 0;
cc5f931c
BB
246 int error;
247
cc5f931c
BB
248 /* Lookup the xattr directory */
249 error = -zfs_lookup(ip, NULL, &dxip, LOOKUP_XATTR, cr, NULL, NULL);
250 if (error)
251 goto out;
252
253 /* Lookup a specific xattr name in the directory */
254 error = -zfs_lookup(dxip, (char *)name, &xip, 0, cr, NULL, NULL);
255 if (error)
256 goto out;
257
258 if (!size) {
259 error = i_size_read(xip);
260 goto out;
261 }
262
c06d4368
AX
263 if (size < i_size_read(xip)) {
264 error = -ERANGE;
265 goto out;
266 }
267
ea04106b 268 error = zpl_read_common(xip, value, size, &pos, UIO_SYSSPACE, 0, cr);
cc5f931c
BB
269out:
270 if (xip)
271 iput(xip);
272
273 if (dxip)
274 iput(dxip);
275
82a37189
BB
276 return (error);
277}
278
279static int
280zpl_xattr_get_sa(struct inode *ip, const char *name, void *value, size_t size)
281{
282 znode_t *zp = ITOZ(ip);
283 uchar_t *nv_value;
284 uint_t nv_size;
285 int error = 0;
cc5f931c 286
82a37189
BB
287 ASSERT(RW_LOCK_HELD(&zp->z_xattr_lock));
288
289 mutex_enter(&zp->z_lock);
290 if (zp->z_xattr_cached == NULL)
291 error = -zfs_sa_get_xattr(zp);
292 mutex_exit(&zp->z_lock);
293
294 if (error)
295 return (error);
296
297 ASSERT(zp->z_xattr_cached);
298 error = -nvlist_lookup_byte_array(zp->z_xattr_cached, name,
299 &nv_value, &nv_size);
300 if (error)
301 return (error);
302
303 if (!size)
304 return (nv_size);
305
c06d4368
AX
306 if (size < nv_size)
307 return (-ERANGE);
308
309 memcpy(value, nv_value, nv_size);
82a37189 310
c06d4368 311 return (nv_size);
82a37189
BB
312}
313
314static int
315__zpl_xattr_get(struct inode *ip, const char *name, void *value, size_t size,
316 cred_t *cr)
317{
318 znode_t *zp = ITOZ(ip);
319 zfs_sb_t *zsb = ZTOZSB(zp);
320 int error;
321
322 ASSERT(RW_LOCK_HELD(&zp->z_xattr_lock));
323
324 if (zsb->z_use_sa && zp->z_is_sa) {
325 error = zpl_xattr_get_sa(ip, name, value, size);
c06d4368 326 if (error != -ENOENT)
82a37189
BB
327 goto out;
328 }
329
330 error = zpl_xattr_get_dir(ip, name, value, size, cr);
331out:
cc5f931c
BB
332 if (error == -ENOENT)
333 error = -ENODATA;
334
335 return (error);
336}
337
338static int
82a37189
BB
339zpl_xattr_get(struct inode *ip, const char *name, void *value, size_t size)
340{
341 znode_t *zp = ITOZ(ip);
342 cred_t *cr = CRED();
ea04106b 343 fstrans_cookie_t cookie;
82a37189
BB
344 int error;
345
346 crhold(cr);
ea04106b 347 cookie = spl_fstrans_mark();
82a37189
BB
348 rw_enter(&zp->z_xattr_lock, RW_READER);
349 error = __zpl_xattr_get(ip, name, value, size, cr);
350 rw_exit(&zp->z_xattr_lock);
ea04106b 351 spl_fstrans_unmark(cookie);
82a37189
BB
352 crfree(cr);
353
354 return (error);
355}
356
357static int
358zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
359 size_t size, int flags, cred_t *cr)
cc5f931c
BB
360{
361 struct inode *dxip = NULL;
362 struct inode *xip = NULL;
363 vattr_t *vap = NULL;
cc5f931c 364 ssize_t wrote;
a08ee875 365 int lookup_flags, error;
bec30953 366 const int xattr_mode = S_IFREG | 0644;
ea04106b 367 loff_t pos = 0;
cc5f931c 368
a08ee875
LG
369 /*
370 * Lookup the xattr directory. When we're adding an entry pass
371 * CREATE_XATTR_DIR to ensure the xattr directory is created.
372 * When removing an entry this flag is not passed to avoid
373 * unnecessarily creating a new xattr directory.
374 */
375 lookup_flags = LOOKUP_XATTR;
376 if (value != NULL)
377 lookup_flags |= CREATE_XATTR_DIR;
378
379 error = -zfs_lookup(ip, NULL, &dxip, lookup_flags, cr, NULL, NULL);
cc5f931c
BB
380 if (error)
381 goto out;
382
82a37189 383 /* Lookup a specific xattr name in the directory */
cc5f931c 384 error = -zfs_lookup(dxip, (char *)name, &xip, 0, cr, NULL, NULL);
82a37189
BB
385 if (error && (error != -ENOENT))
386 goto out;
cc5f931c 387
cc5f931c
BB
388 error = 0;
389
390 /* Remove a specific name xattr when value is set to NULL. */
391 if (value == NULL) {
392 if (xip)
393 error = -zfs_remove(dxip, (char *)name, cr);
394
395 goto out;
396 }
397
398 /* Lookup failed create a new xattr. */
399 if (xip == NULL) {
a08ee875 400 vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
bec30953 401 vap->va_mode = xattr_mode;
cc5f931c 402 vap->va_mask = ATTR_MODE;
81e97e21
BB
403 vap->va_uid = crgetfsuid(cr);
404 vap->va_gid = crgetfsgid(cr);
cc5f931c
BB
405
406 error = -zfs_create(dxip, (char *)name, vap, 0, 0644, &xip,
407 cr, 0, NULL);
408 if (error)
409 goto out;
410 }
411
412 ASSERT(xip != NULL);
bec30953
GB
413
414 error = -zfs_freesp(ITOZ(xip), 0, 0, xattr_mode, TRUE);
415 if (error)
416 goto out;
417
ea04106b 418 wrote = zpl_write_common(xip, value, size, &pos, UIO_SYSSPACE, 0, cr);
cc5f931c
BB
419 if (wrote < 0)
420 error = wrote;
421
422out:
423 if (vap)
a08ee875 424 kmem_free(vap, sizeof (vattr_t));
cc5f931c
BB
425
426 if (xip)
427 iput(xip);
428
429 if (dxip)
430 iput(dxip);
431
cc5f931c
BB
432 if (error == -ENOENT)
433 error = -ENODATA;
434
435 ASSERT3S(error, <=, 0);
436
437 return (error);
438}
439
82a37189
BB
440static int
441zpl_xattr_set_sa(struct inode *ip, const char *name, const void *value,
442 size_t size, int flags, cred_t *cr)
443{
444 znode_t *zp = ITOZ(ip);
445 nvlist_t *nvl;
446 size_t sa_size;
447 int error;
448
449 ASSERT(zp->z_xattr_cached);
450 nvl = zp->z_xattr_cached;
451
452 if (value == NULL) {
453 error = -nvlist_remove(nvl, name, DATA_TYPE_BYTE_ARRAY);
454 if (error == -ENOENT)
455 error = zpl_xattr_set_dir(ip, name, NULL, 0, flags, cr);
456 } else {
457 /* Limited to 32k to keep nvpair memory allocations small */
458 if (size > DXATTR_MAX_ENTRY_SIZE)
459 return (-EFBIG);
460
461 /* Prevent the DXATTR SA from consuming the entire SA region */
462 error = -nvlist_size(nvl, &sa_size, NV_ENCODE_XDR);
463 if (error)
464 return (error);
465
466 if (sa_size > DXATTR_MAX_SA_SIZE)
467 return (-EFBIG);
468
469 error = -nvlist_add_byte_array(nvl, name,
470 (uchar_t *)value, size);
471 if (error)
472 return (error);
473 }
474
475 /* Update the SA for additions, modifications, and removals. */
476 if (!error)
477 error = -zfs_sa_set_xattr(zp);
478
479 ASSERT3S(error, <=, 0);
480
481 return (error);
482}
483
484static int
485zpl_xattr_set(struct inode *ip, const char *name, const void *value,
486 size_t size, int flags)
487{
488 znode_t *zp = ITOZ(ip);
489 zfs_sb_t *zsb = ZTOZSB(zp);
490 cred_t *cr = CRED();
ea04106b 491 fstrans_cookie_t cookie;
82a37189
BB
492 int error;
493
494 crhold(cr);
ea04106b 495 cookie = spl_fstrans_mark();
82a37189
BB
496 rw_enter(&ITOZ(ip)->z_xattr_lock, RW_WRITER);
497
498 /*
499 * Before setting the xattr check to see if it already exists.
500 * This is done to ensure the following optional flags are honored.
501 *
502 * XATTR_CREATE: fail if xattr already exists
503 * XATTR_REPLACE: fail if xattr does not exist
504 */
505 error = __zpl_xattr_get(ip, name, NULL, 0, cr);
506 if (error < 0) {
507 if (error != -ENODATA)
508 goto out;
509
a08ee875
LG
510 if (flags & XATTR_REPLACE)
511 goto out;
512
513 /* The xattr to be removed already doesn't exist */
514 error = 0;
515 if (value == NULL)
82a37189
BB
516 goto out;
517 } else {
518 error = -EEXIST;
519 if (flags & XATTR_CREATE)
520 goto out;
521 }
522
523 /* Preferentially store the xattr as a SA for better performance */
524 if (zsb->z_use_sa && zsb->z_xattr_sa && zp->z_is_sa) {
525 error = zpl_xattr_set_sa(ip, name, value, size, flags, cr);
526 if (error == 0)
527 goto out;
528 }
529
530 error = zpl_xattr_set_dir(ip, name, value, size, flags, cr);
531out:
532 rw_exit(&ITOZ(ip)->z_xattr_lock);
ea04106b 533 spl_fstrans_unmark(cookie);
82a37189
BB
534 crfree(cr);
535 ASSERT3S(error, <=, 0);
536
537 return (error);
538}
539
cc5f931c 540static int
f9637c6c 541__zpl_xattr_user_get(struct inode *ip, const char *name,
82a37189 542 void *value, size_t size)
cc5f931c
BB
543{
544 char *xattr_name;
545 int error;
546
547 if (strcmp(name, "") == 0)
a08ee875 548 return (-EINVAL);
cc5f931c 549
2cf7f52b 550 if (!(ITOZSB(ip)->z_flags & ZSB_XATTR))
a08ee875 551 return (-EOPNOTSUPP);
cc5f931c
BB
552
553 xattr_name = kmem_asprintf("%s%s", XATTR_USER_PREFIX, name);
82a37189 554 error = zpl_xattr_get(ip, xattr_name, value, size);
cc5f931c
BB
555 strfree(xattr_name);
556
557 return (error);
558}
f9637c6c 559ZPL_XATTR_GET_WRAPPER(zpl_xattr_user_get);
cc5f931c
BB
560
561static int
f9637c6c 562__zpl_xattr_user_set(struct inode *ip, const char *name,
cc5f931c
BB
563 const void *value, size_t size, int flags)
564{
565 char *xattr_name;
566 int error;
567
568 if (strcmp(name, "") == 0)
a08ee875 569 return (-EINVAL);
cc5f931c 570
2cf7f52b 571 if (!(ITOZSB(ip)->z_flags & ZSB_XATTR))
a08ee875 572 return (-EOPNOTSUPP);
cc5f931c
BB
573
574 xattr_name = kmem_asprintf("%s%s", XATTR_USER_PREFIX, name);
575 error = zpl_xattr_set(ip, xattr_name, value, size, flags);
576 strfree(xattr_name);
577
578 return (error);
579}
f9637c6c 580ZPL_XATTR_SET_WRAPPER(zpl_xattr_user_set);
cc5f931c 581
777d4af8 582xattr_handler_t zpl_xattr_user_handler = {
cc5f931c
BB
583 .prefix = XATTR_USER_PREFIX,
584 .get = zpl_xattr_user_get,
585 .set = zpl_xattr_user_set,
586};
587
588static int
f9637c6c 589__zpl_xattr_trusted_get(struct inode *ip, const char *name,
82a37189 590 void *value, size_t size)
cc5f931c
BB
591{
592 char *xattr_name;
593 int error;
594
595 if (!capable(CAP_SYS_ADMIN))
a08ee875 596 return (-EACCES);
cc5f931c
BB
597
598 if (strcmp(name, "") == 0)
a08ee875 599 return (-EINVAL);
cc5f931c
BB
600
601 xattr_name = kmem_asprintf("%s%s", XATTR_TRUSTED_PREFIX, name);
82a37189 602 error = zpl_xattr_get(ip, xattr_name, value, size);
cc5f931c
BB
603 strfree(xattr_name);
604
605 return (error);
606}
f9637c6c 607ZPL_XATTR_GET_WRAPPER(zpl_xattr_trusted_get);
cc5f931c
BB
608
609static int
f9637c6c 610__zpl_xattr_trusted_set(struct inode *ip, const char *name,
cc5f931c
BB
611 const void *value, size_t size, int flags)
612{
613 char *xattr_name;
614 int error;
615
616 if (!capable(CAP_SYS_ADMIN))
a08ee875 617 return (-EACCES);
cc5f931c
BB
618
619 if (strcmp(name, "") == 0)
a08ee875 620 return (-EINVAL);
cc5f931c
BB
621
622 xattr_name = kmem_asprintf("%s%s", XATTR_TRUSTED_PREFIX, name);
623 error = zpl_xattr_set(ip, xattr_name, value, size, flags);
624 strfree(xattr_name);
625
626 return (error);
627}
f9637c6c 628ZPL_XATTR_SET_WRAPPER(zpl_xattr_trusted_set);
cc5f931c 629
777d4af8 630xattr_handler_t zpl_xattr_trusted_handler = {
cc5f931c
BB
631 .prefix = XATTR_TRUSTED_PREFIX,
632 .get = zpl_xattr_trusted_get,
633 .set = zpl_xattr_trusted_set,
634};
635
636static int
f9637c6c 637__zpl_xattr_security_get(struct inode *ip, const char *name,
82a37189 638 void *value, size_t size)
cc5f931c
BB
639{
640 char *xattr_name;
641 int error;
642
643 if (strcmp(name, "") == 0)
a08ee875 644 return (-EINVAL);
cc5f931c
BB
645
646 xattr_name = kmem_asprintf("%s%s", XATTR_SECURITY_PREFIX, name);
82a37189 647 error = zpl_xattr_get(ip, xattr_name, value, size);
cc5f931c
BB
648 strfree(xattr_name);
649
650 return (error);
651}
f9637c6c 652ZPL_XATTR_GET_WRAPPER(zpl_xattr_security_get);
cc5f931c
BB
653
654static int
f9637c6c 655__zpl_xattr_security_set(struct inode *ip, const char *name,
cc5f931c
BB
656 const void *value, size_t size, int flags)
657{
658 char *xattr_name;
659 int error;
660
661 if (strcmp(name, "") == 0)
a08ee875 662 return (-EINVAL);
cc5f931c
BB
663
664 xattr_name = kmem_asprintf("%s%s", XATTR_SECURITY_PREFIX, name);
665 error = zpl_xattr_set(ip, xattr_name, value, size, flags);
666 strfree(xattr_name);
667
668 return (error);
669}
f9637c6c 670ZPL_XATTR_SET_WRAPPER(zpl_xattr_security_set);
cc5f931c 671
166dd49d
BB
672#ifdef HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY
673static int
674__zpl_xattr_security_init(struct inode *ip, const struct xattr *xattrs,
675 void *fs_info)
676{
677 const struct xattr *xattr;
678 int error = 0;
679
680 for (xattr = xattrs; xattr->name != NULL; xattr++) {
681 error = __zpl_xattr_security_set(ip,
682 xattr->name, xattr->value, xattr->value_len, 0);
683
684 if (error < 0)
685 break;
686 }
687
96b91ef0 688 return (error);
166dd49d
BB
689}
690
691int
692zpl_xattr_security_init(struct inode *ip, struct inode *dip,
693 const struct qstr *qstr)
694{
695 return security_inode_init_security(ip, dip, qstr,
696 &__zpl_xattr_security_init, NULL);
697}
698
699#else
cc5f931c 700int
5c03efc3
BB
701zpl_xattr_security_init(struct inode *ip, struct inode *dip,
702 const struct qstr *qstr)
cc5f931c 703{
96b91ef0
DH
704 int error;
705 size_t len;
706 void *value;
707 char *name;
cc5f931c 708
96b91ef0 709 error = zpl_security_inode_init_security(ip, dip, qstr,
a08ee875 710 &name, &value, &len);
96b91ef0
DH
711 if (error) {
712 if (error == -EOPNOTSUPP)
a08ee875
LG
713 return (0);
714
96b91ef0
DH
715 return (error);
716 }
cc5f931c 717
f9637c6c 718 error = __zpl_xattr_security_set(ip, name, value, len, 0);
cc5f931c 719
96b91ef0
DH
720 kfree(name);
721 kfree(value);
cc5f931c 722
96b91ef0 723 return (error);
cc5f931c 724}
166dd49d 725#endif /* HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY */
cc5f931c 726
777d4af8 727xattr_handler_t zpl_xattr_security_handler = {
cc5f931c
BB
728 .prefix = XATTR_SECURITY_PREFIX,
729 .get = zpl_xattr_security_get,
730 .set = zpl_xattr_security_set,
731};
732
a08ee875
LG
733#ifdef CONFIG_FS_POSIX_ACL
734
735int
736zpl_set_acl(struct inode *ip, int type, struct posix_acl *acl)
737{
738 struct super_block *sb = ITOZSB(ip)->z_sb;
739 char *name, *value = NULL;
740 int error = 0;
741 size_t size = 0;
742
743 if (S_ISLNK(ip->i_mode))
744 return (-EOPNOTSUPP);
745
746 switch (type) {
747 case ACL_TYPE_ACCESS:
748 name = POSIX_ACL_XATTR_ACCESS;
749 if (acl) {
750 zpl_equivmode_t mode = ip->i_mode;
751 error = posix_acl_equiv_mode(acl, &mode);
752 if (error < 0) {
753 return (error);
754 } else {
755 /*
756 * The mode bits will have been set by
757 * ->zfs_setattr()->zfs_acl_chmod_setattr()
758 * using the ZFS ACL conversion. If they
759 * differ from the Posix ACL conversion dirty
760 * the inode to write the Posix mode bits.
761 */
762 if (ip->i_mode != mode) {
763 ip->i_mode = mode;
764 ip->i_ctime = current_fs_time(sb);
ea04106b 765 zfs_mark_inode_dirty(ip);
a08ee875
LG
766 }
767
768 if (error == 0)
769 acl = NULL;
770 }
771 }
772 break;
773
774 case ACL_TYPE_DEFAULT:
775 name = POSIX_ACL_XATTR_DEFAULT;
776 if (!S_ISDIR(ip->i_mode))
777 return (acl ? -EACCES : 0);
778 break;
779
780 default:
781 return (-EINVAL);
782 }
783
784 if (acl) {
785 size = posix_acl_xattr_size(acl->a_count);
786 value = kmem_alloc(size, KM_SLEEP);
787
788 error = zpl_acl_to_xattr(acl, value, size);
789 if (error < 0) {
790 kmem_free(value, size);
791 return (error);
792 }
793 }
794
795 error = zpl_xattr_set(ip, name, value, size, 0);
796 if (value)
797 kmem_free(value, size);
798
799 if (!error) {
800 if (acl)
801 zpl_set_cached_acl(ip, type, acl);
802 else
803 zpl_forget_cached_acl(ip, type);
804 }
805
806 return (error);
807}
808
809struct posix_acl *
810zpl_get_acl(struct inode *ip, int type)
811{
812 struct posix_acl *acl;
813 void *value = NULL;
814 char *name;
815 int size;
816
817#ifdef HAVE_POSIX_ACL_CACHING
818 acl = get_cached_acl(ip, type);
819 if (acl != ACL_NOT_CACHED)
820 return (acl);
821#endif /* HAVE_POSIX_ACL_CACHING */
822
823 switch (type) {
824 case ACL_TYPE_ACCESS:
825 name = POSIX_ACL_XATTR_ACCESS;
826 break;
827 case ACL_TYPE_DEFAULT:
828 name = POSIX_ACL_XATTR_DEFAULT;
829 break;
830 default:
831 return (ERR_PTR(-EINVAL));
832 }
833
834 size = zpl_xattr_get(ip, name, NULL, 0);
835 if (size > 0) {
ea04106b 836 value = kmem_alloc(size, KM_SLEEP);
a08ee875
LG
837 size = zpl_xattr_get(ip, name, value, size);
838 }
839
840 if (size > 0) {
841 acl = zpl_acl_from_xattr(value, size);
842 } else if (size == -ENODATA || size == -ENOSYS) {
843 acl = NULL;
844 } else {
845 acl = ERR_PTR(-EIO);
846 }
847
848 if (size > 0)
849 kmem_free(value, size);
850
851 if (!IS_ERR(acl))
852 zpl_set_cached_acl(ip, type, acl);
853
854 return (acl);
855}
856
857#if !defined(HAVE_GET_ACL)
858static int
859__zpl_check_acl(struct inode *ip, int mask)
860{
861 struct posix_acl *acl;
862 int error;
863
864 acl = zpl_get_acl(ip, ACL_TYPE_ACCESS);
865 if (IS_ERR(acl))
866 return (PTR_ERR(acl));
867
868 if (acl) {
869 error = posix_acl_permission(ip, acl, mask);
870 zpl_posix_acl_release(acl);
871 return (error);
872 }
873
874 return (-EAGAIN);
875}
876
877#if defined(HAVE_CHECK_ACL_WITH_FLAGS)
878int
879zpl_check_acl(struct inode *ip, int mask, unsigned int flags)
880{
881 return (__zpl_check_acl(ip, mask));
882}
883#elif defined(HAVE_CHECK_ACL)
884int
885zpl_check_acl(struct inode *ip, int mask)
886{
887 return (__zpl_check_acl(ip, mask));
888}
889#elif defined(HAVE_PERMISSION_WITH_NAMEIDATA)
890int
891zpl_permission(struct inode *ip, int mask, struct nameidata *nd)
892{
893 return (generic_permission(ip, mask, __zpl_check_acl));
894}
895#elif defined(HAVE_PERMISSION)
896int
897zpl_permission(struct inode *ip, int mask)
898{
899 return (generic_permission(ip, mask, __zpl_check_acl));
900}
901#endif /* HAVE_CHECK_ACL | HAVE_PERMISSION */
902#endif /* !HAVE_GET_ACL */
903
904int
905zpl_init_acl(struct inode *ip, struct inode *dir)
906{
907 struct posix_acl *acl = NULL;
908 int error = 0;
909
910 if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
911 return (0);
912
913 if (!S_ISLNK(ip->i_mode)) {
914 if (ITOZSB(ip)->z_acl_type == ZFS_ACLTYPE_POSIXACL) {
915 acl = zpl_get_acl(dir, ACL_TYPE_DEFAULT);
916 if (IS_ERR(acl))
917 return (PTR_ERR(acl));
918 }
919
920 if (!acl) {
921 ip->i_mode &= ~current_umask();
922 ip->i_ctime = current_fs_time(ITOZSB(ip)->z_sb);
ea04106b 923 zfs_mark_inode_dirty(ip);
a08ee875
LG
924 return (0);
925 }
926 }
927
928 if ((ITOZSB(ip)->z_acl_type == ZFS_ACLTYPE_POSIXACL) && acl) {
929 umode_t mode;
930
931 if (S_ISDIR(ip->i_mode)) {
932 error = zpl_set_acl(ip, ACL_TYPE_DEFAULT, acl);
933 if (error)
934 goto out;
935 }
936
937 mode = ip->i_mode;
ea04106b 938 error = __posix_acl_create(&acl, GFP_KERNEL, &mode);
a08ee875
LG
939 if (error >= 0) {
940 ip->i_mode = mode;
ea04106b 941 zfs_mark_inode_dirty(ip);
a08ee875
LG
942 if (error > 0)
943 error = zpl_set_acl(ip, ACL_TYPE_ACCESS, acl);
944 }
945 }
946out:
947 zpl_posix_acl_release(acl);
948
949 return (error);
950}
951
952int
953zpl_chmod_acl(struct inode *ip)
954{
955 struct posix_acl *acl;
956 int error;
957
958 if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
959 return (0);
960
961 if (S_ISLNK(ip->i_mode))
962 return (-EOPNOTSUPP);
963
964 acl = zpl_get_acl(ip, ACL_TYPE_ACCESS);
965 if (IS_ERR(acl) || !acl)
966 return (PTR_ERR(acl));
967
ea04106b 968 error = __posix_acl_chmod(&acl, GFP_KERNEL, ip->i_mode);
a08ee875
LG
969 if (!error)
970 error = zpl_set_acl(ip, ACL_TYPE_ACCESS, acl);
971
972 zpl_posix_acl_release(acl);
973
974 return (error);
975}
976
977static size_t
978zpl_xattr_acl_list(struct inode *ip, char *list, size_t list_size,
979 const char *name, size_t name_len, int type)
980{
981 char *xattr_name;
982 size_t xattr_size;
983
984 if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
985 return (0);
986
987 switch (type) {
988 case ACL_TYPE_ACCESS:
989 xattr_name = POSIX_ACL_XATTR_ACCESS;
990 xattr_size = sizeof (xattr_name);
991 break;
992 case ACL_TYPE_DEFAULT:
993 xattr_name = POSIX_ACL_XATTR_DEFAULT;
994 xattr_size = sizeof (xattr_name);
995 break;
996 default:
997 return (0);
998 }
999
1000 if (list && xattr_size <= list_size)
1001 memcpy(list, xattr_name, xattr_size);
1002
1003 return (xattr_size);
1004}
1005
1006#ifdef HAVE_DENTRY_XATTR_LIST
1007static size_t
1008zpl_xattr_acl_list_access(struct dentry *dentry, char *list,
1009 size_t list_size, const char *name, size_t name_len, int type)
1010{
1011 ASSERT3S(type, ==, ACL_TYPE_ACCESS);
1012 return zpl_xattr_acl_list(dentry->d_inode,
1013 list, list_size, name, name_len, type);
1014}
1015
1016static size_t
1017zpl_xattr_acl_list_default(struct dentry *dentry, char *list,
1018 size_t list_size, const char *name, size_t name_len, int type)
1019{
1020 ASSERT3S(type, ==, ACL_TYPE_DEFAULT);
1021 return zpl_xattr_acl_list(dentry->d_inode,
1022 list, list_size, name, name_len, type);
1023}
1024
1025#else
1026
1027static size_t
1028zpl_xattr_acl_list_access(struct inode *ip, char *list, size_t list_size,
1029 const char *name, size_t name_len)
1030{
1031 return zpl_xattr_acl_list(ip,
1032 list, list_size, name, name_len, ACL_TYPE_ACCESS);
1033}
1034
1035static size_t
1036zpl_xattr_acl_list_default(struct inode *ip, char *list, size_t list_size,
1037 const char *name, size_t name_len)
1038{
1039 return zpl_xattr_acl_list(ip,
1040 list, list_size, name, name_len, ACL_TYPE_DEFAULT);
1041}
1042#endif /* HAVE_DENTRY_XATTR_LIST */
1043
1044static int
1045zpl_xattr_acl_get(struct inode *ip, const char *name,
1046 void *buffer, size_t size, int type)
1047{
1048 struct posix_acl *acl;
1049 int error;
1050
1051 if (strcmp(name, "") != 0)
1052 return (-EINVAL);
1053
1054 if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
1055 return (-EOPNOTSUPP);
1056
1057 acl = zpl_get_acl(ip, type);
1058 if (IS_ERR(acl))
1059 return (PTR_ERR(acl));
1060 if (acl == NULL)
1061 return (-ENODATA);
1062
1063 error = zpl_acl_to_xattr(acl, buffer, size);
1064 zpl_posix_acl_release(acl);
1065
1066 return (error);
1067}
1068
1069#ifdef HAVE_DENTRY_XATTR_GET
1070static int
1071zpl_xattr_acl_get_access(struct dentry *dentry, const char *name,
1072 void *buffer, size_t size, int type)
1073{
1074 ASSERT3S(type, ==, ACL_TYPE_ACCESS);
1075 return (zpl_xattr_acl_get(dentry->d_inode, name, buffer, size, type));
1076}
1077
1078static int
1079zpl_xattr_acl_get_default(struct dentry *dentry, const char *name,
1080 void *buffer, size_t size, int type)
1081{
1082 ASSERT3S(type, ==, ACL_TYPE_DEFAULT);
1083 return (zpl_xattr_acl_get(dentry->d_inode, name, buffer, size, type));
1084}
1085
1086#else
1087
1088static int
1089zpl_xattr_acl_get_access(struct inode *ip, const char *name,
1090 void *buffer, size_t size)
1091{
1092 return (zpl_xattr_acl_get(ip, name, buffer, size, ACL_TYPE_ACCESS));
1093}
1094
1095static int
1096zpl_xattr_acl_get_default(struct inode *ip, const char *name,
1097 void *buffer, size_t size)
1098{
1099 return (zpl_xattr_acl_get(ip, name, buffer, size, ACL_TYPE_DEFAULT));
1100}
1101#endif /* HAVE_DENTRY_XATTR_GET */
1102
1103static int
1104zpl_xattr_acl_set(struct inode *ip, const char *name,
1105 const void *value, size_t size, int flags, int type)
1106{
1107 struct posix_acl *acl;
1108 int error = 0;
1109
1110 if (strcmp(name, "") != 0)
1111 return (-EINVAL);
1112
1113 if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
1114 return (-EOPNOTSUPP);
1115
1116 if (!zpl_inode_owner_or_capable(ip))
1117 return (-EPERM);
1118
1119 if (value) {
1120 acl = zpl_acl_from_xattr(value, size);
1121 if (IS_ERR(acl))
1122 return (PTR_ERR(acl));
1123 else if (acl) {
1124 error = posix_acl_valid(acl);
1125 if (error) {
1126 zpl_posix_acl_release(acl);
1127 return (error);
1128 }
1129 }
1130 } else {
1131 acl = NULL;
1132 }
1133
1134 error = zpl_set_acl(ip, type, acl);
1135 zpl_posix_acl_release(acl);
1136
1137 return (error);
1138}
1139
1140#ifdef HAVE_DENTRY_XATTR_SET
1141static int
1142zpl_xattr_acl_set_access(struct dentry *dentry, const char *name,
1143 const void *value, size_t size, int flags, int type)
1144{
1145 ASSERT3S(type, ==, ACL_TYPE_ACCESS);
1146 return (zpl_xattr_acl_set(dentry->d_inode,
1147 name, value, size, flags, type));
1148}
1149
1150static int
1151zpl_xattr_acl_set_default(struct dentry *dentry, const char *name,
1152 const void *value, size_t size, int flags, int type)
1153{
1154 ASSERT3S(type, ==, ACL_TYPE_DEFAULT);
1155 return zpl_xattr_acl_set(dentry->d_inode,
1156 name, value, size, flags, type);
1157}
1158
1159#else
1160
1161static int
1162zpl_xattr_acl_set_access(struct inode *ip, const char *name,
1163 const void *value, size_t size, int flags)
1164{
1165 return zpl_xattr_acl_set(ip,
1166 name, value, size, flags, ACL_TYPE_ACCESS);
1167}
1168
1169static int
1170zpl_xattr_acl_set_default(struct inode *ip, const char *name,
1171 const void *value, size_t size, int flags)
1172{
1173 return zpl_xattr_acl_set(ip,
1174 name, value, size, flags, ACL_TYPE_DEFAULT);
1175}
1176#endif /* HAVE_DENTRY_XATTR_SET */
1177
1178struct xattr_handler zpl_xattr_acl_access_handler =
1179{
1180 .prefix = POSIX_ACL_XATTR_ACCESS,
1181 .list = zpl_xattr_acl_list_access,
1182 .get = zpl_xattr_acl_get_access,
1183 .set = zpl_xattr_acl_set_access,
1184#ifdef HAVE_DENTRY_XATTR_LIST
1185 .flags = ACL_TYPE_ACCESS,
1186#endif /* HAVE_DENTRY_XATTR_LIST */
1187};
1188
1189struct xattr_handler zpl_xattr_acl_default_handler =
1190{
1191 .prefix = POSIX_ACL_XATTR_DEFAULT,
1192 .list = zpl_xattr_acl_list_default,
1193 .get = zpl_xattr_acl_get_default,
1194 .set = zpl_xattr_acl_set_default,
1195#ifdef HAVE_DENTRY_XATTR_LIST
1196 .flags = ACL_TYPE_DEFAULT,
1197#endif /* HAVE_DENTRY_XATTR_LIST */
1198};
1199
1200#endif /* CONFIG_FS_POSIX_ACL */
1201
777d4af8 1202xattr_handler_t *zpl_xattr_handlers[] = {
cc5f931c
BB
1203 &zpl_xattr_security_handler,
1204 &zpl_xattr_trusted_handler,
1205 &zpl_xattr_user_handler,
a08ee875 1206#ifdef CONFIG_FS_POSIX_ACL
cc5f931c 1207 &zpl_xattr_acl_access_handler,
96b91ef0 1208 &zpl_xattr_acl_default_handler,
a08ee875 1209#endif /* CONFIG_FS_POSIX_ACL */
77a405ae 1210 NULL
cc5f931c 1211};