FreeBSD/Linux Kernel Cross Reference
sys/kern/vfs_xattr.c
1 /* $NetBSD: vfs_xattr.c,v 1.19.6.1 2010/06/12 00:59:57 riz Exp $ */
2
3 /*-
4 * Copyright (c) 2005, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe.
9 *
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.
18 *
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.
30 */
31
32 /*
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.
40 *
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.
52 *
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.
64 */
65
66 /*
67 * VFS extended attribute support.
68 */
69
70 #include <sys/cdefs.h>
71 __KERNEL_RCSID(0, "$NetBSD: vfs_xattr.c,v 1.19.6.1 2010/06/12 00:59:57 riz Exp $");
72
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>
88
89 /*
90 * Credential check based on process requesting service, and per-attribute
91 * permissions.
92 *
93 * NOTE: Vnode must be locked.
94 */
95 int
96 extattr_check_cred(struct vnode *vp, int attrnamespace,
97 kauth_cred_t cred, struct lwp *l, int access)
98 {
99
100 if (cred == NOCRED)
101 return (0);
102
103 switch (attrnamespace) {
104 case EXTATTR_NAMESPACE_SYSTEM:
105 /*
106 * Do we really want to allow this, or just require that
107 * these requests come from kernel code (NOCRED case above)?
108 */
109 return (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
110 NULL));
111
112 case EXTATTR_NAMESPACE_USER:
113 return (VOP_ACCESS(vp, access, cred));
114
115 default:
116 return (EPERM);
117 }
118 }
119
120 /*
121 * Default vfs_extattrctl routine for file systems that do not support
122 * it.
123 */
124 /*ARGSUSED*/
125 int
126 vfs_stdextattrctl(struct mount *mp, int cmt, struct vnode *vp,
127 int attrnamespace, const char *attrname)
128 {
129
130 if (vp != NULL)
131 VOP_UNLOCK(vp, 0);
132 return (EOPNOTSUPP);
133 }
134
135 /*
136 * Push extended attribute configuration information into the file
137 * system.
138 *
139 * NOTE: Not all file systems that support extended attributes will
140 * require the use of this system call.
141 */
142 int
143 sys_extattrctl(struct lwp *l, const struct sys_extattrctl_args *uap, register_t *retval)
144 {
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 *vp, *path_vp;
153 struct nameidata nd;
154 char attrname[EXTATTR_MAXNAMELEN];
155 int error;
156
157 if (SCARG(uap, attrname) != NULL) {
158 error = copyinstr(SCARG(uap, attrname), attrname,
159 sizeof(attrname), NULL);
160 if (error)
161 return (error);
162 }
163
164 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path));
165 error = namei(&nd);
166 if (error) {
167 return (error);
168 }
169 path_vp = nd.ni_vp;
170
171 vp = NULL;
172 if (SCARG(uap, filename) != NULL) {
173 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
174 SCARG(uap, filename));
175 error = namei(&nd);
176 if (error) {
177 vrele(path_vp);
178 return (error);
179 }
180 vp = nd.ni_vp;
181 }
182
183 error = VFS_EXTATTRCTL(path_vp->v_mount, SCARG(uap, cmd), vp,
184 SCARG(uap, attrnamespace),
185 SCARG(uap, attrname) != NULL ? attrname : NULL);
186
187 if (vp != NULL)
188 vrele(vp);
189 vrele(path_vp);
190
191 return (error);
192 }
193
194 /*****************************************************************************
195 * Internal routines to manipulate file system extended attributes:
196 * - set
197 * - get
198 * - delete
199 * - list
200 *****************************************************************************/
201
202 /*
203 * extattr_set_vp:
204 *
205 * Set a named extended attribute on a file or directory.
206 */
207 static int
208 extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
209 const void *data, size_t nbytes, struct lwp *l, register_t *retval)
210 {
211 struct uio auio;
212 struct iovec aiov;
213 ssize_t cnt;
214 int error;
215
216 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
217
218 aiov.iov_base = __UNCONST(data); /* XXXUNCONST kills const */
219 aiov.iov_len = nbytes;
220 auio.uio_iov = &aiov;
221 auio.uio_iovcnt = 1;
222 auio.uio_offset = 0;
223 if (nbytes > INT_MAX) {
224 error = EINVAL;
225 goto done;
226 }
227 auio.uio_resid = nbytes;
228 auio.uio_rw = UIO_WRITE;
229 KASSERT(l == curlwp);
230 auio.uio_vmspace = l->l_proc->p_vmspace;
231 cnt = nbytes;
232
233 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio, l->l_cred);
234 cnt -= auio.uio_resid;
235 retval[0] = cnt;
236
237 done:
238 VOP_UNLOCK(vp, 0);
239 return (error);
240 }
241
242 /*
243 * extattr_get_vp:
244 *
245 * Get a named extended attribute on a file or directory.
246 */
247 static int
248 extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
249 void *data, size_t nbytes, struct lwp *l, register_t *retval)
250 {
251 struct uio auio, *auiop;
252 struct iovec aiov;
253 ssize_t cnt;
254 size_t size, *sizep;
255 int error;
256
257 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
258
259 /*
260 * Slightly unusual semantics: if the user provides a NULL data
261 * pointer, they don't want to receive the data, just the maximum
262 * read length.
263 */
264 auiop = NULL;
265 sizep = NULL;
266 cnt = 0;
267 if (data != NULL) {
268 aiov.iov_base = data;
269 aiov.iov_len = nbytes;
270 auio.uio_iov = &aiov;
271 auio.uio_offset = 0;
272 if (nbytes > INT_MAX) {
273 error = EINVAL;
274 goto done;
275 }
276 auio.uio_resid = nbytes;
277 auio.uio_rw = UIO_READ;
278 KASSERT(l == curlwp);
279 auio.uio_vmspace = l->l_proc->p_vmspace;
280 auiop = &auio;
281 cnt = nbytes;
282 } else
283 sizep = &size;
284
285 error = VOP_GETEXTATTR(vp, attrnamespace, attrname, auiop, sizep,
286 l->l_cred);
287
288 if (auiop != NULL) {
289 cnt -= auio.uio_resid;
290 retval[0] = cnt;
291 } else
292 retval[0] = size;
293
294 done:
295 VOP_UNLOCK(vp, 0);
296 return (error);
297 }
298
299 /*
300 * extattr_delete_vp:
301 *
302 * Delete a named extended attribute on a file or directory.
303 */
304 static int
305 extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname,
306 struct lwp *l)
307 {
308 int error;
309
310 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
311
312 error = VOP_DELETEEXTATTR(vp, attrnamespace, attrname, l->l_cred);
313 if (error == EOPNOTSUPP)
314 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL,
315 l->l_cred);
316
317 VOP_UNLOCK(vp, 0);
318 return (error);
319 }
320
321 /*
322 * extattr_list_vp:
323 *
324 * Retrieve a list of extended attributes on a file or directory.
325 */
326 static int
327 extattr_list_vp(struct vnode *vp, int attrnamespace, void *data, size_t nbytes,
328 struct lwp *l, register_t *retval)
329 {
330 struct uio auio, *auiop;
331 size_t size, *sizep;
332 struct iovec aiov;
333 ssize_t cnt;
334 int error;
335
336 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
337
338 auiop = NULL;
339 sizep = NULL;
340 cnt = 0;
341 if (data != NULL) {
342 aiov.iov_base = data;
343 aiov.iov_len = nbytes;
344 auio.uio_iov = &aiov;
345 auio.uio_offset = 0;
346 if (nbytes > INT_MAX) {
347 error = EINVAL;
348 goto done;
349 }
350 auio.uio_resid = nbytes;
351 auio.uio_rw = UIO_READ;
352 KASSERT(l == curlwp);
353 auio.uio_vmspace = l->l_proc->p_vmspace;
354 auiop = &auio;
355 cnt = nbytes;
356 } else
357 sizep = &size;
358
359 error = VOP_LISTEXTATTR(vp, attrnamespace, auiop, sizep, l->l_cred);
360
361 if (auiop != NULL) {
362 cnt -= auio.uio_resid;
363 retval[0] = cnt;
364 } else
365 retval[0] = size;
366
367 done:
368 VOP_UNLOCK(vp, 0);
369 return (error);
370 }
371
372 /*****************************************************************************
373 * BSD <sys/extattr.h> API for file system extended attributes
374 *****************************************************************************/
375
376 int
377 sys_extattr_set_fd(struct lwp *l, const struct sys_extattr_set_fd_args *uap, register_t *retval)
378 {
379 /* {
380 syscallarg(int) fd;
381 syscallarg(int) attrnamespace;
382 syscallarg(const char *) attrname;
383 syscallarg(const void *) data;
384 syscallarg(size_t) nbytes;
385 } */
386 struct file *fp;
387 struct vnode *vp;
388 char attrname[EXTATTR_MAXNAMELEN];
389 int error;
390
391 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
392 NULL);
393 if (error)
394 return (error);
395
396 error = fd_getvnode(SCARG(uap, fd), &fp);
397 if (error)
398 return (error);
399 vp = (struct vnode *) fp->f_data;
400
401 error = extattr_set_vp(vp, SCARG(uap, attrnamespace), attrname,
402 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
403
404 fd_putfile(SCARG(uap, fd));
405 return (error);
406 }
407
408 int
409 sys_extattr_set_file(struct lwp *l, const struct sys_extattr_set_file_args *uap, register_t *retval)
410 {
411 /* {
412 syscallarg(const char *) path;
413 syscallarg(int) attrnamespace;
414 syscallarg(const char *) attrname;
415 syscallarg(const void *) data;
416 syscallarg(size_t) nbytes;
417 } */
418 struct nameidata nd;
419 char attrname[EXTATTR_MAXNAMELEN];
420 int error;
421
422 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
423 NULL);
424 if (error)
425 return (error);
426
427 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path));
428 error = namei(&nd);
429 if (error)
430 return (error);
431
432 error = extattr_set_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
433 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
434
435 vrele(nd.ni_vp);
436 return (error);
437 }
438
439 int
440 sys_extattr_set_link(struct lwp *l, const struct sys_extattr_set_link_args *uap, register_t *retval)
441 {
442 /* {
443 syscallarg(const char *) path;
444 syscallarg(int) attrnamespace;
445 syscallarg(const char *) attrname;
446 syscallarg(const void *) data;
447 syscallarg(size_t) nbytes;
448 } */
449 struct nameidata nd;
450 char attrname[EXTATTR_MAXNAMELEN];
451 int error;
452
453 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
454 NULL);
455 if (error)
456 return (error);
457
458 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path));
459 error = namei(&nd);
460 if (error)
461 return (error);
462
463 error = extattr_set_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
464 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
465
466 vrele(nd.ni_vp);
467 return (error);
468 }
469
470 int
471 sys_extattr_get_fd(struct lwp *l, const struct sys_extattr_get_fd_args *uap, register_t *retval)
472 {
473 /* {
474 syscallarg(int) fd;
475 syscallarg(int) attrnamespace;
476 syscallarg(const char *) attrname;
477 syscallarg(void *) data;
478 syscallarg(size_t) nbytes;
479 } */
480 struct file *fp;
481 struct vnode *vp;
482 char attrname[EXTATTR_MAXNAMELEN];
483 int error;
484
485 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
486 NULL);
487 if (error)
488 return (error);
489
490 error = fd_getvnode(SCARG(uap, fd), &fp);
491 if (error)
492 return (error);
493 vp = (struct vnode *) fp->f_data;
494
495 error = extattr_get_vp(vp, SCARG(uap, attrnamespace), attrname,
496 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
497
498 fd_putfile(SCARG(uap, fd));
499 return (error);
500 }
501
502 int
503 sys_extattr_get_file(struct lwp *l, const struct sys_extattr_get_file_args *uap, register_t *retval)
504 {
505 /* {
506 syscallarg(const char *) path;
507 syscallarg(int) attrnamespace;
508 syscallarg(const char *) attrname;
509 syscallarg(void *) data;
510 syscallarg(size_t) nbytes;
511 } */
512 struct nameidata nd;
513 char attrname[EXTATTR_MAXNAMELEN];
514 int error;
515
516 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
517 NULL);
518 if (error)
519 return (error);
520
521 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path));
522 error = namei(&nd);
523 if (error)
524 return (error);
525
526 error = extattr_get_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
527 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
528
529 vrele(nd.ni_vp);
530 return (error);
531 }
532
533 int
534 sys_extattr_get_link(struct lwp *l, const struct sys_extattr_get_link_args *uap, register_t *retval)
535 {
536 /* {
537 syscallarg(const char *) path;
538 syscallarg(int) attrnamespace;
539 syscallarg(const char *) attrname;
540 syscallarg(void *) data;
541 syscallarg(size_t) nbytes;
542 } */
543 struct nameidata nd;
544 char attrname[EXTATTR_MAXNAMELEN];
545 int error;
546
547 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
548 NULL);
549 if (error)
550 return (error);
551
552 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path));
553 error = namei(&nd);
554 if (error)
555 return (error);
556
557 error = extattr_get_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
558 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
559
560 vrele(nd.ni_vp);
561 return (error);
562 }
563
564 int
565 sys_extattr_delete_fd(struct lwp *l, const struct sys_extattr_delete_fd_args *uap, register_t *retval)
566 {
567 /* {
568 syscallarg(int) fd;
569 syscallarg(int) attrnamespace;
570 syscallarg(const char *) attrname;
571 } */
572 struct file *fp;
573 struct vnode *vp;
574 char attrname[EXTATTR_MAXNAMELEN];
575 int error;
576
577 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
578 NULL);
579 if (error)
580 return (error);
581
582 error = fd_getvnode(SCARG(uap, fd), &fp);
583 if (error)
584 return (error);
585 vp = (struct vnode *) fp->f_data;
586
587 error = extattr_delete_vp(vp, SCARG(uap, attrnamespace), attrname, l);
588
589 fd_putfile(SCARG(uap, fd));
590 return (error);
591 }
592
593 int
594 sys_extattr_delete_file(struct lwp *l, const struct sys_extattr_delete_file_args *uap, register_t *retval)
595 {
596 /* {
597 syscallarg(const char *) path;
598 syscallarg(int) attrnamespace;
599 syscallarg(const char *) attrname;
600 } */
601 struct nameidata nd;
602 char attrname[EXTATTR_MAXNAMELEN];
603 int error;
604
605 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
606 NULL);
607 if (error)
608 return (error);
609
610 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path));
611 error = namei(&nd);
612 if (error)
613 return (error);
614
615 error = extattr_delete_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
616 l);
617
618 vrele(nd.ni_vp);
619 return (error);
620 }
621
622 int
623 sys_extattr_delete_link(struct lwp *l, const struct sys_extattr_delete_link_args *uap, register_t *retval)
624 {
625 /* {
626 syscallarg(const char *) path;
627 syscallarg(int) attrnamespace;
628 syscallarg(const char *) attrname;
629 } */
630 struct nameidata nd;
631 char attrname[EXTATTR_MAXNAMELEN];
632 int error;
633
634 error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
635 NULL);
636 if (error)
637 return (error);
638
639 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path));
640 error = namei(&nd);
641 if (error)
642 return (error);
643
644 error = extattr_delete_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
645 l);
646
647 vrele(nd.ni_vp);
648 return (error);
649 }
650
651 int
652 sys_extattr_list_fd(struct lwp *l, const struct sys_extattr_list_fd_args *uap, register_t *retval)
653 {
654 /* {
655 syscallarg(int) fd;
656 syscallarg(int) attrnamespace;
657 syscallarg(void *) data;
658 syscallarg(size_t) nbytes;
659 } */
660 struct file *fp;
661 struct vnode *vp;
662 int error;
663
664 error = fd_getvnode(SCARG(uap, fd), &fp);
665 if (error)
666 return (error);
667 vp = (struct vnode *) fp->f_data;
668
669 error = extattr_list_vp(vp, SCARG(uap, attrnamespace),
670 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
671
672 fd_putfile(SCARG(uap, fd));
673 return (error);
674 }
675
676 int
677 sys_extattr_list_file(struct lwp *l, const struct sys_extattr_list_file_args *uap, register_t *retval)
678 {
679 /* {
680 syscallarg(const char *) path;
681 syscallarg(int) attrnamespace;
682 syscallarg(void *) data;
683 syscallarg(size_t) nbytes;
684 } */
685 struct nameidata nd;
686 int error;
687
688 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path));
689 error = namei(&nd);
690 if (error)
691 return (error);
692
693 error = extattr_list_vp(nd.ni_vp, SCARG(uap, attrnamespace),
694 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
695
696 vrele(nd.ni_vp);
697 return (error);
698 }
699
700 int
701 sys_extattr_list_link(struct lwp *l, const struct sys_extattr_list_link_args *uap, register_t *retval)
702 {
703 /* {
704 syscallarg(const char *) path;
705 syscallarg(int) attrnamespace;
706 syscallarg(void *) data;
707 syscallarg(size_t) nbytes;
708 } */
709 struct nameidata nd;
710 int error;
711
712 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path));
713 error = namei(&nd);
714 if (error)
715 return (error);
716
717 error = extattr_list_vp(nd.ni_vp, SCARG(uap, attrnamespace),
718 SCARG(uap, data), SCARG(uap, nbytes), l, retval);
719
720 vrele(nd.ni_vp);
721 return (error);
722 }
723
724 /*****************************************************************************
725 * Linux-compatible <sys/xattr.h> API for file system extended attributes
726 *****************************************************************************/
727
728 int
729 sys_setxattr(struct lwp *l, const struct sys_setxattr_args *uap, register_t *retval)
730 {
731 /* {
732 syscallarg(const char *) path;
733 syscallarg(const char *) name;
734 syscallarg(void *) value;
735 syscallarg(size_t) size;
736 syscallarg(int) flags;
737 } */
738 struct nameidata nd;
739 char attrname[XATTR_NAME_MAX];
740 int error;
741
742 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
743 NULL);
744 if (error)
745 return (error);
746
747 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path));
748 error = namei(&nd);
749 if (error)
750 return (error);
751
752 /* XXX flags */
753
754 error = extattr_set_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
755 attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
756
757 vrele(nd.ni_vp);
758 return (error);
759 }
760
761 int
762 sys_lsetxattr(struct lwp *l, const struct sys_lsetxattr_args *uap, register_t *retval)
763 {
764 /* {
765 syscallarg(const char *) path;
766 syscallarg(const char *) name;
767 syscallarg(void *) value;
768 syscallarg(size_t) size;
769 syscallarg(int) flags;
770 } */
771 struct nameidata nd;
772 char attrname[XATTR_NAME_MAX];
773 int error;
774
775 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
776 NULL);
777 if (error)
778 return (error);
779
780 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path));
781 error = namei(&nd);
782 if (error)
783 return (error);
784
785 /* XXX flags */
786
787 error = extattr_set_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
788 attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
789
790 vrele(nd.ni_vp);
791 return (error);
792 }
793
794 int
795 sys_fsetxattr(struct lwp *l, const struct sys_fsetxattr_args *uap, register_t *retval)
796 {
797 /* {
798 syscallarg(int) fd;
799 syscallarg(const char *) name;
800 syscallarg(void *) value;
801 syscallarg(size_t) size;
802 syscallarg(int) flags;
803 } */
804 struct file *fp;
805 struct vnode *vp;
806 char attrname[XATTR_NAME_MAX];
807 int error;
808
809 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
810 NULL);
811 if (error)
812 return (error);
813
814 error = fd_getvnode(SCARG(uap, fd), &fp);
815 if (error)
816 return (error);
817 vp = (struct vnode *) fp->f_data;
818
819 /* XXX flags */
820
821 error = extattr_set_vp(vp, EXTATTR_NAMESPACE_USER,
822 attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
823
824 fd_putfile(SCARG(uap, fd));
825 return (error);
826 }
827
828 int
829 sys_getxattr(struct lwp *l, const struct sys_getxattr_args *uap, register_t *retval)
830 {
831 /* {
832 syscallarg(const char *) path;
833 syscallarg(const char *) name;
834 syscallarg(void *) value;
835 syscallarg(size_t) size;
836 } */
837 struct nameidata nd;
838 char attrname[XATTR_NAME_MAX];
839 int error;
840
841 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
842 NULL);
843 if (error)
844 return (error);
845
846 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path));
847 error = namei(&nd);
848 if (error)
849 return (error);
850
851 error = extattr_get_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
852 attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
853
854 vrele(nd.ni_vp);
855 return (error);
856 }
857
858 int
859 sys_lgetxattr(struct lwp *l, const struct sys_lgetxattr_args *uap, register_t *retval)
860 {
861 /* {
862 syscallarg(const char *) path;
863 syscallarg(const char *) name;
864 syscallarg(void *) value;
865 syscallarg(size_t) size;
866 } */
867 struct nameidata nd;
868 char attrname[XATTR_NAME_MAX];
869 int error;
870
871 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
872 NULL);
873 if (error)
874 return (error);
875
876 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path));
877 error = namei(&nd);
878 if (error)
879 return (error);
880
881 error = extattr_get_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
882 attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
883
884 vrele(nd.ni_vp);
885 return (error);
886 }
887
888 int
889 sys_fgetxattr(struct lwp *l, const struct sys_fgetxattr_args *uap, register_t *retval)
890 {
891 /* {
892 syscallarg(int) fd;
893 syscallarg(const char *) name;
894 syscallarg(void *) value;
895 syscallarg(size_t) size;
896 } */
897 struct file *fp;
898 struct vnode *vp;
899 char attrname[XATTR_NAME_MAX];
900 int error;
901
902 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
903 NULL);
904 if (error)
905 return (error);
906
907 error = fd_getvnode(SCARG(uap, fd), &fp);
908 if (error)
909 return (error);
910 vp = (struct vnode *) fp->f_data;
911
912 error = extattr_get_vp(vp, EXTATTR_NAMESPACE_USER,
913 attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
914
915 fd_putfile(SCARG(uap, fd));
916 return (error);
917 }
918
919 int
920 sys_listxattr(struct lwp *l, const struct sys_listxattr_args *uap, register_t *retval)
921 {
922 /* {
923 syscallarg(const char *) path;
924 syscallarg(char *) list;
925 syscallarg(size_t) size;
926 } */
927 struct nameidata nd;
928 int error;
929
930 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path));
931 error = namei(&nd);
932 if (error)
933 return (error);
934
935 error = extattr_list_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
936 SCARG(uap, list), SCARG(uap, size), l, retval);
937
938 vrele(nd.ni_vp);
939 return (error);
940 }
941
942 int
943 sys_llistxattr(struct lwp *l, const struct sys_llistxattr_args *uap, register_t *retval)
944 {
945 /* {
946 syscallarg(const char *) path;
947 syscallarg(char *) list;
948 syscallarg(size_t) size;
949 } */
950 struct nameidata nd;
951 int error;
952
953 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path));
954 error = namei(&nd);
955 if (error)
956 return (error);
957
958 error = extattr_list_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
959 SCARG(uap, list), SCARG(uap, size), l, retval);
960
961 vrele(nd.ni_vp);
962 return (error);
963 }
964
965 int
966 sys_flistxattr(struct lwp *l, const struct sys_flistxattr_args *uap, register_t *retval)
967 {
968 /* {
969 syscallarg(int) fd;
970 syscallarg(char *) list;
971 syscallarg(size_t) size;
972 } */
973 struct file *fp;
974 struct vnode *vp;
975 int error;
976
977 error = fd_getvnode(SCARG(uap, fd), &fp);
978 if (error)
979 return (error);
980 vp = (struct vnode *) fp->f_data;
981
982 error = extattr_list_vp(vp, EXTATTR_NAMESPACE_USER,
983 SCARG(uap, list), SCARG(uap, size), l, retval);
984
985 fd_putfile(SCARG(uap, fd));
986 return (error);
987 }
988
989 int
990 sys_removexattr(struct lwp *l, const struct sys_removexattr_args *uap, register_t *retval)
991 {
992 /* {
993 syscallarg(const char *) path;
994 syscallarg(const char *) name;
995 } */
996 struct nameidata nd;
997 char attrname[XATTR_NAME_MAX];
998 int error;
999
1000 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
1001 NULL);
1002 if (error)
1003 return (error);
1004
1005 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path));
1006 error = namei(&nd);
1007 if (error)
1008 return (error);
1009
1010 error = extattr_delete_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
1011 attrname, l);
1012
1013 vrele(nd.ni_vp);
1014 return (error);
1015 }
1016
1017 int
1018 sys_lremovexattr(struct lwp *l, const struct sys_lremovexattr_args *uap, register_t *retval)
1019 {
1020 /* {
1021 syscallarg(const char *) path;
1022 syscallarg(const char *) name;
1023 } */
1024 struct nameidata nd;
1025 char attrname[XATTR_NAME_MAX];
1026 int error;
1027
1028 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
1029 NULL);
1030 if (error)
1031 return (error);
1032
1033 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path));
1034 error = namei(&nd);
1035 if (error)
1036 return (error);
1037
1038 error = extattr_delete_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
1039 attrname, l);
1040
1041 vrele(nd.ni_vp);
1042 return (error);
1043 }
1044
1045 int
1046 sys_fremovexattr(struct lwp *l, const struct sys_fremovexattr_args *uap, register_t *retval)
1047 {
1048 /* {
1049 syscallarg(int) fd;
1050 syscallarg(const char *) name;
1051 } */
1052 struct file *fp;
1053 struct vnode *vp;
1054 char attrname[XATTR_NAME_MAX];
1055 int error;
1056
1057 error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
1058 NULL);
1059 if (error)
1060 return (error);
1061
1062 error = fd_getvnode(SCARG(uap, fd), &fp);
1063 if (error)
1064 return (error);
1065 vp = (struct vnode *) fp->f_data;
1066
1067 error = extattr_delete_vp(vp, EXTATTR_NAMESPACE_USER,
1068 attrname, l);
1069
1070 fd_putfile(SCARG(uap, fd));
1071 return (error);
1072 }
Cache object: 5b7458c3ccdd781e41165adf2ae8ab17
|