Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / kern / vfs_xattr.c
blob89b868779e9f3e790703beb3671370a93c1b621f
1 /* $NetBSD: vfs_xattr.c,v 1.19 2008/06/23 11:30:41 ad Exp $ */
3 /*-
4 * Copyright (c) 2005, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1989, 1993
34 * The Regents of the University of California. All rights reserved.
35 * (c) UNIX System Laboratories, Inc.
36 * All or some portions of this file are derived from material licensed
37 * to the University of California by American Telephone and Telegraph
38 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
39 * the permission of UNIX System Laboratories, Inc.
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. Neither the name of the University nor the names of its contributors
50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission.
53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE.
67 * VFS extended attribute support.
70 #include <sys/cdefs.h>
71 __KERNEL_RCSID(0, "$NetBSD: vfs_xattr.c,v 1.19 2008/06/23 11:30:41 ad Exp $");
73 #include <sys/param.h>
74 #include <sys/systm.h>
75 #include <sys/namei.h>
76 #include <sys/filedesc.h>
77 #include <sys/kernel.h>
78 #include <sys/file.h>
79 #include <sys/vnode.h>
80 #include <sys/mount.h>
81 #include <sys/proc.h>
82 #include <sys/uio.h>
83 #include <sys/extattr.h>
84 #include <sys/xattr.h>
85 #include <sys/sysctl.h>
86 #include <sys/syscallargs.h>
87 #include <sys/kauth.h>
90 * Credential check based on process requesting service, and per-attribute
91 * permissions.
93 * NOTE: Vnode must be locked.
95 int
96 extattr_check_cred(struct vnode *vp, int attrnamespace,
97 kauth_cred_t cred, struct lwp *l, int access)
100 if (cred == NOCRED)
101 return (0);
103 switch (attrnamespace) {
104 case EXTATTR_NAMESPACE_SYSTEM:
106 * Do we really want to allow this, or just require that
107 * these requests come from kernel code (NOCRED case above)?
109 return (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
110 NULL));
112 case EXTATTR_NAMESPACE_USER:
113 return (VOP_ACCESS(vp, access, cred));
115 default:
116 return (EPERM);
121 * Default vfs_extattrctl routine for file systems that do not support
122 * it.
124 /*ARGSUSED*/
126 vfs_stdextattrctl(struct mount *mp, int cmt, struct vnode *vp,
127 int attrnamespace, const char *attrname)
130 if (vp != NULL)
131 VOP_UNLOCK(vp, 0);
132 return (EOPNOTSUPP);
136 * Push extended attribute configuration information into the file
137 * system.
139 * NOTE: Not all file systems that support extended attributes will
140 * require the use of this system call.
143 sys_extattrctl(struct lwp *l, const struct sys_extattrctl_args *uap, register_t *retval)
145 /* {
146 syscallarg(const char *) path;
147 syscallarg(int) cmd;
148 syscallarg(const char *) filename;
149 syscallarg(int) attrnamespace;
150 syscallarg(const char *) attrname;
151 } */
152 struct vnode *path_vp, *file_vp;
153 struct nameidata file_nd;
154 char attrname[EXTATTR_MAXNAMELEN];
155 int error;
157 if (SCARG(uap, attrname) != NULL) {
158 error = copyinstr(SCARG(uap, attrname), attrname,
159 sizeof(attrname), NULL);
160 if (error)
161 return (error);
164 file_vp = NULL;
165 if (SCARG(uap, filename) != NULL) {
166 NDINIT(&file_nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
167 SCARG(uap, filename));
168 error = namei(&file_nd);
169 if (error)
170 return (error);
171 file_vp = file_nd.ni_vp;
174 error = namei_simple_user(SCARG(uap, path),
175 NSM_FOLLOW_NOEMULROOT, &path_vp);
176 if (error) {
177 if (file_vp != NULL)
178 vput(file_vp);
179 return (error);
182 error = VFS_EXTATTRCTL(path_vp->v_mount, SCARG(uap, cmd), file_vp,
183 SCARG(uap, attrnamespace),
184 SCARG(uap, attrname) != NULL ? attrname : NULL);
186 if (file_vp != NULL)
187 vrele(file_vp);
189 /* XXX missing in the original code - am *I* missing something? */
190 vrele(path_vp);
192 return (error);
195 /*****************************************************************************
196 * Internal routines to manipulate file system extended attributes:
197 * - set
198 * - get
199 * - delete
200 * - list
201 *****************************************************************************/
204 * extattr_set_vp:
206 * Set a named extended attribute on a file or directory.
208 static int
209 extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
210 const void *data, size_t nbytes, struct lwp *l, register_t *retval)
212 struct uio auio;
213 struct iovec aiov;
214 ssize_t cnt;
215 int error;
217 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
219 aiov.iov_base = __UNCONST(data); /* XXXUNCONST kills const */
220 aiov.iov_len = nbytes;
221 auio.uio_iov = &aiov;
222 auio.uio_iovcnt = 1;
223 auio.uio_offset = 0;
224 if (nbytes > INT_MAX) {
225 error = EINVAL;
226 goto done;
228 auio.uio_resid = nbytes;
229 auio.uio_rw = UIO_WRITE;
230 KASSERT(l == curlwp);
231 auio.uio_vmspace = l->l_proc->p_vmspace;
232 cnt = nbytes;
234 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio, l->l_cred);
235 cnt -= auio.uio_resid;
236 retval[0] = cnt;
238 done:
239 VOP_UNLOCK(vp, 0);
240 return (error);
244 * extattr_get_vp:
246 * Get a named extended attribute on a file or directory.
248 static int
249 extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
250 void *data, size_t nbytes, struct lwp *l, register_t *retval)
252 struct uio auio, *auiop;
253 struct iovec aiov;
254 ssize_t cnt;
255 size_t size, *sizep;
256 int error;
258 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
261 * Slightly unusual semantics: if the user provides a NULL data
262 * pointer, they don't want to receive the data, just the maximum
263 * read length.
265 auiop = NULL;
266 sizep = NULL;
267 cnt = 0;
268 if (data != NULL) {
269 aiov.iov_base = data;
270 aiov.iov_len = nbytes;
271 auio.uio_iov = &aiov;
272 auio.uio_offset = 0;
273 if (nbytes > INT_MAX) {
274 error = EINVAL;
275 goto done;
277 auio.uio_resid = nbytes;
278 auio.uio_rw = UIO_READ;
279 KASSERT(l == curlwp);
280 auio.uio_vmspace = l->l_proc->p_vmspace;
281 auiop = &auio;
282 cnt = nbytes;
283 } else
284 sizep = &size;
286 error = VOP_GETEXTATTR(vp, attrnamespace, attrname, auiop, sizep,
287 l->l_cred);
289 if (auiop != NULL) {
290 cnt -= auio.uio_resid;
291 retval[0] = cnt;
292 } else
293 retval[0] = size;
295 done:
296 VOP_UNLOCK(vp, 0);
297 return (error);
301 * extattr_delete_vp:
303 * Delete a named extended attribute on a file or directory.
305 static int
306 extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname,
307 struct lwp *l)
309 int error;
311 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
313 error = VOP_DELETEEXTATTR(vp, attrnamespace, attrname, l->l_cred);
314 if (error == EOPNOTSUPP)
315 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL,
316 l->l_cred);
318 VOP_UNLOCK(vp, 0);
319 return (error);
323 * extattr_list_vp:
325 * Retrieve a list of extended attributes on a file or directory.
327 static int
328 extattr_list_vp(struct vnode *vp, int attrnamespace, void *data, size_t nbytes,
329 struct lwp *l, register_t *retval)
331 struct uio auio, *auiop;
332 size_t size, *sizep;
333 struct iovec aiov;
334 ssize_t cnt;
335 int error;
337 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
339 auiop = NULL;
340 sizep = NULL;
341 cnt = 0;
342 if (data != NULL) {
343 aiov.iov_base = data;
344 aiov.iov_len = nbytes;
345 auio.uio_iov = &aiov;
346 auio.uio_offset = 0;
347 if (nbytes > INT_MAX) {
348 error = EINVAL;
349 goto done;
351 auio.uio_resid = nbytes;
352 auio.uio_rw = UIO_READ;
353 KASSERT(l == curlwp);
354 auio.uio_vmspace = l->l_proc->p_vmspace;
355 auiop = &auio;
356 cnt = nbytes;
357 } else
358 sizep = &size;
360 error = VOP_LISTEXTATTR(vp, attrnamespace, auiop, sizep, l->l_cred);
362 if (auiop != NULL) {
363 cnt -= auio.uio_resid;
364 retval[0] = cnt;
365 } else
366 retval[0] = size;
368 done:
369 VOP_UNLOCK(vp, 0);
370 return (error);
373 /*****************************************************************************
374 * BSD <sys/extattr.h> API for file system extended attributes
375 *****************************************************************************/
378 sys_extattr_set_fd(struct lwp *l, const struct sys_extattr_set_fd_args *uap, register_t *retval)
380 /* {
381 syscallarg(int) fd;
382 syscallarg(int) attrnamespace;
383 syscallarg(const char *) attrname;
384 syscallarg(const void *) data;
385 syscallarg(size_t) nbytes;
386 } */
387 struct file *fp;
388 struct vnode *vp;
389 char attrname[EXTATTR_MAXNAMELEN];
390 int error;
392 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
393 NULL);
394 if (error)
395 return (error);
397 error = fd_getvnode(SCARG(uap, fd), &fp);
398 if (error)
399 return (error);
400 vp = (struct vnode *) fp->f_data;
402 error = extattr_set_vp(vp, SCARG(uap, attrnamespace), attrname,
403 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
405 fd_putfile(SCARG(uap, fd));
406 return (error);
410 sys_extattr_set_file(struct lwp *l, const struct sys_extattr_set_file_args *uap, register_t *retval)
412 /* {
413 syscallarg(const char *) path;
414 syscallarg(int) attrnamespace;
415 syscallarg(const char *) attrname;
416 syscallarg(const void *) data;
417 syscallarg(size_t) nbytes;
418 } */
419 struct vnode *vp;
420 char attrname[EXTATTR_MAXNAMELEN];
421 int error;
423 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
424 NULL);
425 if (error)
426 return (error);
428 error = namei_simple_user(SCARG(uap, path),
429 NSM_FOLLOW_NOEMULROOT, &vp);
430 if (error)
431 return (error);
433 error = extattr_set_vp(vp, SCARG(uap, attrnamespace), attrname,
434 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
436 vrele(vp);
437 return (error);
441 sys_extattr_set_link(struct lwp *l, const struct sys_extattr_set_link_args *uap, register_t *retval)
443 /* {
444 syscallarg(const char *) path;
445 syscallarg(int) attrnamespace;
446 syscallarg(const char *) attrname;
447 syscallarg(const void *) data;
448 syscallarg(size_t) nbytes;
449 } */
450 struct vnode *vp;
451 char attrname[EXTATTR_MAXNAMELEN];
452 int error;
454 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
455 NULL);
456 if (error)
457 return (error);
459 error = namei_simple_user(SCARG(uap, path),
460 NSM_NOFOLLOW_NOEMULROOT, &vp);
461 if (error)
462 return (error);
464 error = extattr_set_vp(vp, SCARG(uap, attrnamespace), attrname,
465 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
467 vrele(vp);
468 return (error);
472 sys_extattr_get_fd(struct lwp *l, const struct sys_extattr_get_fd_args *uap, register_t *retval)
474 /* {
475 syscallarg(int) fd;
476 syscallarg(int) attrnamespace;
477 syscallarg(const char *) attrname;
478 syscallarg(void *) data;
479 syscallarg(size_t) nbytes;
480 } */
481 struct file *fp;
482 struct vnode *vp;
483 char attrname[EXTATTR_MAXNAMELEN];
484 int error;
486 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
487 NULL);
488 if (error)
489 return (error);
491 error = fd_getvnode(SCARG(uap, fd), &fp);
492 if (error)
493 return (error);
494 vp = (struct vnode *) fp->f_data;
496 error = extattr_get_vp(vp, SCARG(uap, attrnamespace), attrname,
497 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
499 fd_putfile(SCARG(uap, fd));
500 return (error);
504 sys_extattr_get_file(struct lwp *l, const struct sys_extattr_get_file_args *uap, register_t *retval)
506 /* {
507 syscallarg(const char *) path;
508 syscallarg(int) attrnamespace;
509 syscallarg(const char *) attrname;
510 syscallarg(void *) data;
511 syscallarg(size_t) nbytes;
512 } */
513 struct vnode *vp;
514 char attrname[EXTATTR_MAXNAMELEN];
515 int error;
517 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
518 NULL);
519 if (error)
520 return (error);
522 error = namei_simple_user(SCARG(uap, path),
523 NSM_FOLLOW_NOEMULROOT, &vp);
524 if (error)
525 return (error);
527 error = extattr_get_vp(vp, SCARG(uap, attrnamespace), attrname,
528 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
530 vrele(vp);
531 return (error);
535 sys_extattr_get_link(struct lwp *l, const struct sys_extattr_get_link_args *uap, register_t *retval)
537 /* {
538 syscallarg(const char *) path;
539 syscallarg(int) attrnamespace;
540 syscallarg(const char *) attrname;
541 syscallarg(void *) data;
542 syscallarg(size_t) nbytes;
543 } */
544 struct vnode *vp;
545 char attrname[EXTATTR_MAXNAMELEN];
546 int error;
548 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
549 NULL);
550 if (error)
551 return (error);
553 error = namei_simple_user(SCARG(uap, path),
554 NSM_NOFOLLOW_NOEMULROOT, &vp);
555 if (error)
556 return (error);
558 error = extattr_get_vp(vp, SCARG(uap, attrnamespace), attrname,
559 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
561 vrele(vp);
562 return (error);
566 sys_extattr_delete_fd(struct lwp *l, const struct sys_extattr_delete_fd_args *uap, register_t *retval)
568 /* {
569 syscallarg(int) fd;
570 syscallarg(int) attrnamespace;
571 syscallarg(const char *) attrname;
572 } */
573 struct file *fp;
574 struct vnode *vp;
575 char attrname[EXTATTR_MAXNAMELEN];
576 int error;
578 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
579 NULL);
580 if (error)
581 return (error);
583 error = fd_getvnode(SCARG(uap, fd), &fp);
584 if (error)
585 return (error);
586 vp = (struct vnode *) fp->f_data;
588 error = extattr_delete_vp(vp, SCARG(uap, attrnamespace), attrname, l);
590 fd_putfile(SCARG(uap, fd));
591 return (error);
595 sys_extattr_delete_file(struct lwp *l, const struct sys_extattr_delete_file_args *uap, register_t *retval)
597 /* {
598 syscallarg(const char *) path;
599 syscallarg(int) attrnamespace;
600 syscallarg(const char *) attrname;
601 } */
602 struct vnode *vp;
603 char attrname[EXTATTR_MAXNAMELEN];
604 int error;
606 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
607 NULL);
608 if (error)
609 return (error);
611 error = namei_simple_user(SCARG(uap, path),
612 NSM_FOLLOW_NOEMULROOT, &vp);
613 if (error)
614 return (error);
616 error = extattr_delete_vp(vp, SCARG(uap, attrnamespace), attrname, l);
618 vrele(vp);
619 return (error);
623 sys_extattr_delete_link(struct lwp *l, const struct sys_extattr_delete_link_args *uap, register_t *retval)
625 /* {
626 syscallarg(const char *) path;
627 syscallarg(int) attrnamespace;
628 syscallarg(const char *) attrname;
629 } */
630 struct vnode *vp;
631 char attrname[EXTATTR_MAXNAMELEN];
632 int error;
634 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
635 NULL);
636 if (error)
637 return (error);
639 error = namei_simple_user(SCARG(uap, path),
640 NSM_NOFOLLOW_NOEMULROOT, &vp);
641 if (error)
642 return (error);
644 error = extattr_delete_vp(vp, SCARG(uap, attrnamespace), attrname, l);
646 vrele(vp);
647 return (error);
651 sys_extattr_list_fd(struct lwp *l, const struct sys_extattr_list_fd_args *uap, register_t *retval)
653 /* {
654 syscallarg(int) fd;
655 syscallarg(int) attrnamespace;
656 syscallarg(void *) data;
657 syscallarg(size_t) nbytes;
658 } */
659 struct file *fp;
660 struct vnode *vp;
661 int error;
663 error = fd_getvnode(SCARG(uap, fd), &fp);
664 if (error)
665 return (error);
666 vp = (struct vnode *) fp->f_data;
668 error = extattr_list_vp(vp, SCARG(uap, attrnamespace),
669 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
671 fd_putfile(SCARG(uap, fd));
672 return (error);
676 sys_extattr_list_file(struct lwp *l, const struct sys_extattr_list_file_args *uap, register_t *retval)
678 /* {
679 syscallarg(const char *) path;
680 syscallarg(int) attrnamespace;
681 syscallarg(void *) data;
682 syscallarg(size_t) nbytes;
683 } */
684 struct vnode *vp;
685 int error;
687 error = namei_simple_user(SCARG(uap, path),
688 NSM_FOLLOW_NOEMULROOT, &vp);
689 if (error)
690 return (error);
692 error = extattr_list_vp(vp, SCARG(uap, attrnamespace),
693 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
695 vrele(vp);
696 return (error);
700 sys_extattr_list_link(struct lwp *l, const struct sys_extattr_list_link_args *uap, register_t *retval)
702 /* {
703 syscallarg(const char *) path;
704 syscallarg(int) attrnamespace;
705 syscallarg(void *) data;
706 syscallarg(size_t) nbytes;
707 } */
708 struct vnode *vp;
709 int error;
711 error = namei_simple_user(SCARG(uap, path),
712 NSM_NOFOLLOW_NOEMULROOT, &vp);
713 if (error)
714 return (error);
716 error = extattr_list_vp(vp, SCARG(uap, attrnamespace),
717 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
719 vrele(vp);
720 return (error);
723 /*****************************************************************************
724 * Linux-compatible <sys/xattr.h> API for file system extended attributes
725 *****************************************************************************/
728 sys_setxattr(struct lwp *l, const struct sys_setxattr_args *uap, register_t *retval)
730 /* {
731 syscallarg(const char *) path;
732 syscallarg(const char *) name;
733 syscallarg(void *) value;
734 syscallarg(size_t) size;
735 syscallarg(int) flags;
736 } */
737 struct vnode *vp;
738 char attrname[XATTR_NAME_MAX];
739 int error;
741 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
742 NULL);
743 if (error)
744 return (error);
746 error = namei_simple_user(SCARG(uap, path),
747 NSM_FOLLOW_NOEMULROOT, &vp);
748 if (error)
749 return (error);
751 /* XXX flags */
753 error = extattr_set_vp(vp, EXTATTR_NAMESPACE_USER,
754 attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
756 vrele(vp);
757 return (error);
761 sys_lsetxattr(struct lwp *l, const struct sys_lsetxattr_args *uap, register_t *retval)
763 /* {
764 syscallarg(const char *) path;
765 syscallarg(const char *) name;
766 syscallarg(void *) value;
767 syscallarg(size_t) size;
768 syscallarg(int) flags;
769 } */
770 struct vnode *vp;
771 char attrname[XATTR_NAME_MAX];
772 int error;
774 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
775 NULL);
776 if (error)
777 return (error);
779 error = namei_simple_user(SCARG(uap, path),
780 NSM_NOFOLLOW_NOEMULROOT, &vp);
781 if (error)
782 return (error);
784 /* XXX flags */
786 error = extattr_set_vp(vp, EXTATTR_NAMESPACE_USER,
787 attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
789 vrele(vp);
790 return (error);
794 sys_fsetxattr(struct lwp *l, const struct sys_fsetxattr_args *uap, register_t *retval)
796 /* {
797 syscallarg(int) fd;
798 syscallarg(const char *) name;
799 syscallarg(void *) value;
800 syscallarg(size_t) size;
801 syscallarg(int) flags;
802 } */
803 struct file *fp;
804 struct vnode *vp;
805 char attrname[XATTR_NAME_MAX];
806 int error;
808 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
809 NULL);
810 if (error)
811 return (error);
813 error = fd_getvnode(SCARG(uap, fd), &fp);
814 if (error)
815 return (error);
816 vp = (struct vnode *) fp->f_data;
818 /* XXX flags */
820 error = extattr_set_vp(vp, EXTATTR_NAMESPACE_USER,
821 attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
823 fd_putfile(SCARG(uap, fd));
824 return (error);
828 sys_getxattr(struct lwp *l, const struct sys_getxattr_args *uap, register_t *retval)
830 /* {
831 syscallarg(const char *) path;
832 syscallarg(const char *) name;
833 syscallarg(void *) value;
834 syscallarg(size_t) size;
835 } */
836 struct vnode *vp;
837 char attrname[XATTR_NAME_MAX];
838 int error;
840 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
841 NULL);
842 if (error)
843 return (error);
845 error = namei_simple_user(SCARG(uap, path),
846 NSM_FOLLOW_NOEMULROOT, &vp);
847 if (error)
848 return (error);
850 error = extattr_get_vp(vp, EXTATTR_NAMESPACE_USER,
851 attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
853 vrele(vp);
854 return (error);
858 sys_lgetxattr(struct lwp *l, const struct sys_lgetxattr_args *uap, register_t *retval)
860 /* {
861 syscallarg(const char *) path;
862 syscallarg(const char *) name;
863 syscallarg(void *) value;
864 syscallarg(size_t) size;
865 } */
866 struct vnode *vp;
867 char attrname[XATTR_NAME_MAX];
868 int error;
870 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
871 NULL);
872 if (error)
873 return (error);
875 error = namei_simple_user(SCARG(uap, path),
876 NSM_NOFOLLOW_NOEMULROOT, &vp);
877 if (error)
878 return (error);
880 error = extattr_get_vp(vp, EXTATTR_NAMESPACE_USER,
881 attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
883 vrele(vp);
884 return (error);
888 sys_fgetxattr(struct lwp *l, const struct sys_fgetxattr_args *uap, register_t *retval)
890 /* {
891 syscallarg(int) fd;
892 syscallarg(const char *) name;
893 syscallarg(void *) value;
894 syscallarg(size_t) size;
895 } */
896 struct file *fp;
897 struct vnode *vp;
898 char attrname[XATTR_NAME_MAX];
899 int error;
901 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
902 NULL);
903 if (error)
904 return (error);
906 error = fd_getvnode(SCARG(uap, fd), &fp);
907 if (error)
908 return (error);
909 vp = (struct vnode *) fp->f_data;
911 error = extattr_get_vp(vp, EXTATTR_NAMESPACE_USER,
912 attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
914 fd_putfile(SCARG(uap, fd));
915 return (error);
919 sys_listxattr(struct lwp *l, const struct sys_listxattr_args *uap, register_t *retval)
921 /* {
922 syscallarg(const char *) path;
923 syscallarg(char *) list;
924 syscallarg(size_t) size;
925 } */
926 struct vnode *vp;
927 int error;
929 error = namei_simple_user(SCARG(uap, path),
930 NSM_FOLLOW_NOEMULROOT, &vp);
931 if (error)
932 return (error);
934 error = extattr_list_vp(vp, EXTATTR_NAMESPACE_USER,
935 SCARG(uap, list), SCARG(uap, size), l, retval);
937 vrele(vp);
938 return (error);
942 sys_llistxattr(struct lwp *l, const struct sys_llistxattr_args *uap, register_t *retval)
944 /* {
945 syscallarg(const char *) path;
946 syscallarg(char *) list;
947 syscallarg(size_t) size;
948 } */
949 struct vnode *vp;
950 int error;
952 error = namei_simple_user(SCARG(uap, path),
953 NSM_NOFOLLOW_NOEMULROOT, &vp);
954 if (error)
955 return (error);
957 error = extattr_list_vp(vp, EXTATTR_NAMESPACE_USER,
958 SCARG(uap, list), SCARG(uap, size), l, retval);
960 vrele(vp);
961 return (error);
965 sys_flistxattr(struct lwp *l, const struct sys_flistxattr_args *uap, register_t *retval)
967 /* {
968 syscallarg(int) fd;
969 syscallarg(char *) list;
970 syscallarg(size_t) size;
971 } */
972 struct file *fp;
973 struct vnode *vp;
974 int error;
976 error = fd_getvnode(SCARG(uap, fd), &fp);
977 if (error)
978 return (error);
979 vp = (struct vnode *) fp->f_data;
981 error = extattr_list_vp(vp, EXTATTR_NAMESPACE_USER,
982 SCARG(uap, list), SCARG(uap, size), l, retval);
984 fd_putfile(SCARG(uap, fd));
985 return (error);
989 sys_removexattr(struct lwp *l, const struct sys_removexattr_args *uap, register_t *retval)
991 /* {
992 syscallarg(const char *) path;
993 syscallarg(const char *) name;
994 } */
995 struct vnode *vp;
996 char attrname[XATTR_NAME_MAX];
997 int error;
999 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
1000 NULL);
1001 if (error)
1002 return (error);
1004 error = namei_simple_user(SCARG(uap, path),
1005 NSM_FOLLOW_NOEMULROOT, &vp);
1006 if (error)
1007 return (error);
1009 error = extattr_delete_vp(vp, EXTATTR_NAMESPACE_USER,
1010 attrname, l);
1012 vrele(vp);
1013 return (error);
1017 sys_lremovexattr(struct lwp *l, const struct sys_lremovexattr_args *uap, register_t *retval)
1019 /* {
1020 syscallarg(const char *) path;
1021 syscallarg(const char *) name;
1022 } */
1023 struct vnode *vp;
1024 char attrname[XATTR_NAME_MAX];
1025 int error;
1027 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
1028 NULL);
1029 if (error)
1030 return (error);
1032 error = namei_simple_user(SCARG(uap, path),
1033 NSM_NOFOLLOW_NOEMULROOT, &vp);
1034 if (error)
1035 return (error);
1037 error = extattr_delete_vp(vp, EXTATTR_NAMESPACE_USER,
1038 attrname, l);
1040 vrele(vp);
1041 return (error);
1045 sys_fremovexattr(struct lwp *l, const struct sys_fremovexattr_args *uap, register_t *retval)
1047 /* {
1048 syscallarg(int) fd;
1049 syscallarg(const char *) name;
1050 } */
1051 struct file *fp;
1052 struct vnode *vp;
1053 char attrname[XATTR_NAME_MAX];
1054 int error;
1056 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
1057 NULL);
1058 if (error)
1059 return (error);
1061 error = fd_getvnode(SCARG(uap, fd), &fp);
1062 if (error)
1063 return (error);
1064 vp = (struct vnode *) fp->f_data;
1066 error = extattr_delete_vp(vp, EXTATTR_NAMESPACE_USER,
1067 attrname, l);
1069 fd_putfile(SCARG(uap, fd));
1070 return (error);