FreeBSD kernel kern code
vfs_extattr.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1999-2001 Robert N. M. Watson
5 * All rights reserved.
6 *
7 * This software was developed by Robert Watson for the TrustedBSD Project.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD$");
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/capsicum.h>
37#include <sys/lock.h>
38#include <sys/mount.h>
39#include <sys/mutex.h>
40#include <sys/sysproto.h>
41#include <sys/fcntl.h>
42#include <sys/namei.h>
43#include <sys/filedesc.h>
44#include <sys/limits.h>
45#include <sys/vnode.h>
46#include <sys/proc.h>
47#include <sys/extattr.h>
48
49#include <security/audit/audit.h>
50#include <security/mac/mac_framework.h>
51
52static int kern_extattr_set_path(struct thread *td, const char *path,
53 int attrnamespace, const char *attrname, void *data,
54 size_t nbytes, int follow);
55static int kern_extattr_get_path(struct thread *td, const char *path,
56 int attrnamespace, const char *attrname, void *data,
57 size_t nbytes, int follow);
58static int kern_extattr_delete_path(struct thread *td, const char *path,
59 int attrnamespace, const char *attrname, int follow);
60static int kern_extattr_list_path(struct thread *td, const char *path,
61 int attrnamespace, void *data, size_t nbytes, int follow);
62
63/*
64 * Syscall to push extended attribute configuration information into the VFS.
65 * Accepts a path, which it converts to a mountpoint, as well as a command
66 * (int cmd), and attribute name and misc data.
67 *
68 * Currently this is used only by UFS1 extended attributes.
69 */
70#ifndef _SYS_SYSPROTO_H_
72 const char *path;
73 int cmd;
74 const char *filename;
76 const char *attrname;
77};
78#endif
79int
80sys_extattrctl(struct thread *td, struct extattrctl_args *uap)
81{
82 struct vnode *filename_vp;
83 struct nameidata nd;
84 struct mount *mp, *mp_writable;
85 char attrname[EXTATTR_MAXNAMELEN + 1];
86 int error;
87
88 AUDIT_ARG_CMD(uap->cmd);
89 AUDIT_ARG_VALUE(uap->attrnamespace);
90 /*
91 * uap->attrname is not always defined. We check again later when we
92 * invoke the VFS call so as to pass in NULL there if needed.
93 */
94 if (uap->attrname != NULL) {
95 error = copyinstr(uap->attrname, attrname, sizeof(attrname),
96 NULL);
97 if (error)
98 return (error);
99 }
100 AUDIT_ARG_TEXT(attrname);
101
102 mp = NULL;
103 filename_vp = NULL;
104 if (uap->filename != NULL) {
105 NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE2, UIO_USERSPACE,
106 uap->filename);
107 error = namei(&nd);
108 if (error)
109 return (error);
110 filename_vp = nd.ni_vp;
111 NDFREE(&nd, NDF_NO_VP_RELE);
112 }
113
114 /* uap->path is always defined. */
115 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, UIO_USERSPACE,
116 uap->path);
117 error = namei(&nd);
118 if (error)
119 goto out;
120 mp = nd.ni_vp->v_mount;
121 error = vfs_busy(mp, 0);
122 if (error) {
123 NDFREE(&nd, 0);
124 mp = NULL;
125 goto out;
126 }
127 VOP_UNLOCK(nd.ni_vp);
128 error = vn_start_write(nd.ni_vp, &mp_writable, V_WAIT | PCATCH);
129 NDFREE(&nd, NDF_NO_VP_UNLOCK);
130 if (error)
131 goto out;
132 if (filename_vp != NULL) {
133 /*
134 * uap->filename is not always defined. If it is,
135 * grab a vnode lock, which VFS_EXTATTRCTL() will
136 * later release.
137 */
138 error = vn_lock(filename_vp, LK_EXCLUSIVE);
139 if (error) {
140 vn_finished_write(mp_writable);
141 goto out;
142 }
143 }
144
145 error = VFS_EXTATTRCTL(mp, uap->cmd, filename_vp, uap->attrnamespace,
146 uap->attrname != NULL ? attrname : NULL);
147
148 vn_finished_write(mp_writable);
149out:
150 if (mp != NULL)
151 vfs_unbusy(mp);
152
153 /*
154 * VFS_EXTATTRCTL will have unlocked, but not de-ref'd, filename_vp,
155 * so vrele it if it is defined.
156 */
157 if (filename_vp != NULL)
158 vrele(filename_vp);
159 return (error);
160}
161
162/*-
163 * Set a named extended attribute on a file or directory
164 *
165 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
166 * kernelspace string pointer "attrname", userspace buffer
167 * pointer "data", buffer length "nbytes", thread "td".
168 * Returns: 0 on success, an error number otherwise
169 * Locks: none
170 * References: vp must be a valid reference for the duration of the call
171 */
172static int
173extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
174 void *data, size_t nbytes, struct thread *td)
175{
176 struct mount *mp;
177 struct uio auio;
178 struct iovec aiov;
179 ssize_t cnt;
180 int error;
181
182 if (nbytes > IOSIZE_MAX)
183 return (EINVAL);
184
185 error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
186 if (error)
187 return (error);
188 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
189
190 aiov.iov_base = data;
191 aiov.iov_len = nbytes;
192 auio.uio_iov = &aiov;
193 auio.uio_iovcnt = 1;
194 auio.uio_offset = 0;
195 auio.uio_resid = nbytes;
196 auio.uio_rw = UIO_WRITE;
197 auio.uio_segflg = UIO_USERSPACE;
198 auio.uio_td = td;
199 cnt = nbytes;
200
201#ifdef MAC
202 error = mac_vnode_check_setextattr(td->td_ucred, vp, attrnamespace,
203 attrname);
204 if (error)
205 goto done;
206#endif
207
208 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio,
209 td->td_ucred, td);
210 cnt -= auio.uio_resid;
211 td->td_retval[0] = cnt;
212
213#ifdef MAC
214done:
215#endif
216 VOP_UNLOCK(vp);
218 return (error);
219}
220
221#ifndef _SYS_SYSPROTO_H_
223 int fd;
225 const char *attrname;
226 void *data;
227 size_t nbytes;
228};
229#endif
230int
231sys_extattr_set_fd(struct thread *td, struct extattr_set_fd_args *uap)
232{
233 struct file *fp;
234 char attrname[EXTATTR_MAXNAMELEN + 1];
235 cap_rights_t rights;
236 int error;
237
238 AUDIT_ARG_FD(uap->fd);
239 AUDIT_ARG_VALUE(uap->attrnamespace);
240 error = copyinstr(uap->attrname, attrname, sizeof(attrname), NULL);
241 if (error)
242 return (error);
243 AUDIT_ARG_TEXT(attrname);
244
245 error = getvnode_path(td, uap->fd,
246 cap_rights_init_one(&rights, CAP_EXTATTR_SET), &fp);
247 if (error)
248 return (error);
249
250 error = extattr_set_vp(fp->f_vnode, uap->attrnamespace,
251 attrname, uap->data, uap->nbytes, td);
252 fdrop(fp, td);
253
254 return (error);
255}
256
257#ifndef _SYS_SYSPROTO_H_
259 const char *path;
261 const char *attrname;
262 void *data;
263 size_t nbytes;
264};
265#endif
266int
267sys_extattr_set_file(struct thread *td, struct extattr_set_file_args *uap)
268{
269
270 return (kern_extattr_set_path(td, uap->path, uap->attrnamespace,
271 uap->attrname, uap->data, uap->nbytes, FOLLOW));
272}
273
274#ifndef _SYS_SYSPROTO_H_
276 const char *path;
278 const char *attrname;
279 void *data;
280 size_t nbytes;
281};
282#endif
283int
284sys_extattr_set_link(struct thread *td, struct extattr_set_link_args *uap)
285{
286
287 return (kern_extattr_set_path(td, uap->path, uap->attrnamespace,
288 uap->attrname, uap->data, uap->nbytes, NOFOLLOW));
289}
290
291static int
292kern_extattr_set_path(struct thread *td, const char *path, int attrnamespace,
293 const char *uattrname, void *data, size_t nbytes, int follow)
294{
295 struct nameidata nd;
296 char attrname[EXTATTR_MAXNAMELEN + 1];
297 int error;
298
299 AUDIT_ARG_VALUE(attrnamespace);
300 error = copyinstr(uattrname, attrname, sizeof(attrname), NULL);
301 if (error)
302 return (error);
303 AUDIT_ARG_TEXT(attrname);
304
305 NDINIT(&nd, LOOKUP, follow | AUDITVNODE1, UIO_USERSPACE, path);
306 error = namei(&nd);
307 if (error)
308 return (error);
309 NDFREE(&nd, NDF_ONLY_PNBUF);
310
311 error = extattr_set_vp(nd.ni_vp, attrnamespace, attrname, data,
312 nbytes, td);
313
314 vrele(nd.ni_vp);
315 return (error);
316}
317
318/*-
319 * Get a named extended attribute on a file or directory
320 *
321 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
322 * kernelspace string pointer "attrname", userspace buffer
323 * pointer "data", buffer length "nbytes", thread "td".
324 * Returns: 0 on success, an error number otherwise
325 * Locks: none
326 * References: vp must be a valid reference for the duration of the call
327 */
328static int
329extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
330 void *data, size_t nbytes, struct thread *td)
331{
332 struct uio auio, *auiop;
333 struct iovec aiov;
334 ssize_t cnt;
335 size_t size, *sizep;
336 int error;
337
338 if (nbytes > IOSIZE_MAX)
339 return (EINVAL);
340
341 vn_lock(vp, LK_SHARED | LK_RETRY);
342
343 /*
344 * Slightly unusual semantics: if the user provides a NULL data
345 * pointer, they don't want to receive the data, just the maximum
346 * read length.
347 */
348 auiop = NULL;
349 sizep = NULL;
350 cnt = 0;
351 if (data != NULL) {
352 aiov.iov_base = data;
353 aiov.iov_len = nbytes;
354 auio.uio_iov = &aiov;
355 auio.uio_iovcnt = 1;
356 auio.uio_offset = 0;
357 auio.uio_resid = nbytes;
358 auio.uio_rw = UIO_READ;
359 auio.uio_segflg = UIO_USERSPACE;
360 auio.uio_td = td;
361 auiop = &auio;
362 cnt = nbytes;
363 } else
364 sizep = &size;
365
366#ifdef MAC
367 error = mac_vnode_check_getextattr(td->td_ucred, vp, attrnamespace,
368 attrname);
369 if (error)
370 goto done;
371#endif
372
373 error = VOP_GETEXTATTR(vp, attrnamespace, attrname, auiop, sizep,
374 td->td_ucred, td);
375
376 if (auiop != NULL) {
377 cnt -= auio.uio_resid;
378 td->td_retval[0] = cnt;
379 } else
380 td->td_retval[0] = size;
381#ifdef MAC
382done:
383#endif
384 VOP_UNLOCK(vp);
385 return (error);
386}
387
388#ifndef _SYS_SYSPROTO_H_
390 int fd;
392 const char *attrname;
393 void *data;
394 size_t nbytes;
395};
396#endif
397int
398sys_extattr_get_fd(struct thread *td, struct extattr_get_fd_args *uap)
399{
400 struct file *fp;
401 char attrname[EXTATTR_MAXNAMELEN + 1];
402 cap_rights_t rights;
403 int error;
404
405 AUDIT_ARG_FD(uap->fd);
406 AUDIT_ARG_VALUE(uap->attrnamespace);
407 error = copyinstr(uap->attrname, attrname, sizeof(attrname), NULL);
408 if (error)
409 return (error);
410 AUDIT_ARG_TEXT(attrname);
411
412 error = getvnode_path(td, uap->fd,
413 cap_rights_init_one(&rights, CAP_EXTATTR_GET), &fp);
414 if (error)
415 return (error);
416
417 error = extattr_get_vp(fp->f_vnode, uap->attrnamespace,
418 attrname, uap->data, uap->nbytes, td);
419
420 fdrop(fp, td);
421 return (error);
422}
423
424#ifndef _SYS_SYSPROTO_H_
426 const char *path;
428 const char *attrname;
429 void *data;
430 size_t nbytes;
431};
432#endif
433int
434sys_extattr_get_file(struct thread *td, struct extattr_get_file_args *uap)
435{
436 return (kern_extattr_get_path(td, uap->path, uap->attrnamespace,
437 uap->attrname, uap->data, uap->nbytes, FOLLOW));
438}
439
440#ifndef _SYS_SYSPROTO_H_
442 const char *path;
444 const char *attrname;
445 void *data;
446 size_t nbytes;
447};
448#endif
449int
450sys_extattr_get_link(struct thread *td, struct extattr_get_link_args *uap)
451{
452 return (kern_extattr_get_path(td, uap->path, uap->attrnamespace,
453 uap->attrname, uap->data, uap->nbytes, NOFOLLOW));
454}
455
456static int
457kern_extattr_get_path(struct thread *td, const char *path, int attrnamespace,
458 const char *uattrname, void *data, size_t nbytes, int follow)
459{
460 struct nameidata nd;
461 char attrname[EXTATTR_MAXNAMELEN + 1];
462 int error;
463
464 AUDIT_ARG_VALUE(attrnamespace);
465 error = copyinstr(uattrname, attrname, sizeof(attrname), NULL);
466 if (error)
467 return (error);
468 AUDIT_ARG_TEXT(attrname);
469
470 NDINIT(&nd, LOOKUP, follow | AUDITVNODE1, UIO_USERSPACE, path);
471 error = namei(&nd);
472 if (error)
473 return (error);
474 NDFREE(&nd, NDF_ONLY_PNBUF);
475
476 error = extattr_get_vp(nd.ni_vp, attrnamespace, attrname, data,
477 nbytes, td);
478
479 vrele(nd.ni_vp);
480 return (error);
481}
482
483/*
484 * extattr_delete_vp(): Delete a named extended attribute on a file or
485 * directory
486 *
487 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
488 * kernelspace string pointer "attrname", proc "p"
489 * Returns: 0 on success, an error number otherwise
490 * Locks: none
491 * References: vp must be a valid reference for the duration of the call
492 */
493static int
494extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname,
495 struct thread *td)
496{
497 struct mount *mp;
498 int error;
499
500 error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
501 if (error)
502 return (error);
503 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
504
505#ifdef MAC
506 error = mac_vnode_check_deleteextattr(td->td_ucred, vp, attrnamespace,
507 attrname);
508 if (error)
509 goto done;
510#endif
511
512 error = VOP_DELETEEXTATTR(vp, attrnamespace, attrname, td->td_ucred,
513 td);
514 if (error == EOPNOTSUPP)
515 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL,
516 td->td_ucred, td);
517#ifdef MAC
518done:
519#endif
520 VOP_UNLOCK(vp);
522 return (error);
523}
524
525#ifndef _SYS_SYSPROTO_H_
527 int fd;
529 const char *attrname;
530};
531#endif
532int
533sys_extattr_delete_fd(struct thread *td, struct extattr_delete_fd_args *uap)
534{
535 struct file *fp;
536 char attrname[EXTATTR_MAXNAMELEN + 1];
537 cap_rights_t rights;
538 int error;
539
540 AUDIT_ARG_FD(uap->fd);
541 AUDIT_ARG_VALUE(uap->attrnamespace);
542 error = copyinstr(uap->attrname, attrname, sizeof(attrname), NULL);
543 if (error)
544 return (error);
545 AUDIT_ARG_TEXT(attrname);
546
547 error = getvnode_path(td, uap->fd,
548 cap_rights_init_one(&rights, CAP_EXTATTR_DELETE), &fp);
549 if (error)
550 return (error);
551
552 error = extattr_delete_vp(fp->f_vnode, uap->attrnamespace,
553 attrname, td);
554 fdrop(fp, td);
555 return (error);
556}
557
558#ifndef _SYS_SYSPROTO_H_
560 const char *path;
562 const char *attrname;
563};
564#endif
565int
567{
568
569 return (kern_extattr_delete_path(td, uap->path, uap->attrnamespace,
570 uap->attrname, FOLLOW));
571}
572
573#ifndef _SYS_SYSPROTO_H_
575 const char *path;
577 const char *attrname;
578};
579#endif
580int
582{
583
584 return (kern_extattr_delete_path(td, uap->path, uap->attrnamespace,
585 uap->attrname, NOFOLLOW));
586}
587
588static int
589kern_extattr_delete_path(struct thread *td, const char *path, int attrnamespace,
590 const char *uattrname, int follow)
591{
592 struct nameidata nd;
593 char attrname[EXTATTR_MAXNAMELEN + 1];
594 int error;
595
596 AUDIT_ARG_VALUE(attrnamespace);
597 error = copyinstr(uattrname, attrname, sizeof(attrname), NULL);
598 if (error)
599 return(error);
600 AUDIT_ARG_TEXT(attrname);
601
602 NDINIT(&nd, LOOKUP, follow | AUDITVNODE1, UIO_USERSPACE, path);
603 error = namei(&nd);
604 if (error)
605 return(error);
606 NDFREE(&nd, NDF_ONLY_PNBUF);
607
608 error = extattr_delete_vp(nd.ni_vp, attrnamespace, attrname, td);
609 vrele(nd.ni_vp);
610 return(error);
611}
612
613/*-
614 * Retrieve a list of extended attributes on a file or directory.
615 *
616 * Arguments: unlocked vnode "vp", attribute namespace 'attrnamespace",
617 * userspace buffer pointer "data", buffer length "nbytes",
618 * thread "td".
619 * Returns: 0 on success, an error number otherwise
620 * Locks: none
621 * References: vp must be a valid reference for the duration of the call
622 */
623static int
624extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
625 size_t nbytes, struct thread *td)
626{
627 struct uio auio, *auiop;
628 size_t size, *sizep;
629 struct iovec aiov;
630 ssize_t cnt;
631 int error;
632
633 if (nbytes > IOSIZE_MAX)
634 return (EINVAL);
635
636 auiop = NULL;
637 sizep = NULL;
638 cnt = 0;
639 if (data != NULL) {
640 aiov.iov_base = data;
641 aiov.iov_len = nbytes;
642 auio.uio_iov = &aiov;
643 auio.uio_iovcnt = 1;
644 auio.uio_offset = 0;
645 auio.uio_resid = nbytes;
646 auio.uio_rw = UIO_READ;
647 auio.uio_segflg = UIO_USERSPACE;
648 auio.uio_td = td;
649 auiop = &auio;
650 cnt = nbytes;
651 } else
652 sizep = &size;
653
654 vn_lock(vp, LK_SHARED | LK_RETRY);
655
656#ifdef MAC
657 error = mac_vnode_check_listextattr(td->td_ucred, vp, attrnamespace);
658 if (error) {
659 VOP_UNLOCK(vp);
660 return (error);
661 }
662#endif
663
664 error = VOP_LISTEXTATTR(vp, attrnamespace, auiop, sizep,
665 td->td_ucred, td);
666 VOP_UNLOCK(vp);
667
668 if (auiop != NULL) {
669 cnt -= auio.uio_resid;
670 td->td_retval[0] = cnt;
671 } else
672 td->td_retval[0] = size;
673 return (error);
674}
675
676#ifndef _SYS_SYSPROTO_H_
678 int fd;
680 void *data;
681 size_t nbytes;
682};
683#endif
684int
685sys_extattr_list_fd(struct thread *td, struct extattr_list_fd_args *uap)
686{
687 struct file *fp;
688 cap_rights_t rights;
689 int error;
690
691 AUDIT_ARG_FD(uap->fd);
692 AUDIT_ARG_VALUE(uap->attrnamespace);
693 error = getvnode_path(td, uap->fd,
694 cap_rights_init_one(&rights, CAP_EXTATTR_LIST), &fp);
695 if (error)
696 return (error);
697
698 error = extattr_list_vp(fp->f_vnode, uap->attrnamespace, uap->data,
699 uap->nbytes, td);
700
701 fdrop(fp, td);
702 return (error);
703}
704
705#ifndef _SYS_SYSPROTO_H_
707 const char *path;
709 void *data;
710 size_t nbytes;
711}
712#endif
713int
714sys_extattr_list_file(struct thread *td, struct extattr_list_file_args *uap)
718 uap->data, uap->nbytes, FOLLOW));
719}
720
721#ifndef _SYS_SYSPROTO_H_
723 const char *path;
725 void *data;
726 size_t nbytes;
728#endif
729int
730sys_extattr_list_link(struct thread *td, struct extattr_list_link_args *uap)
731{
732
733 return (kern_extattr_list_path(td, uap->path, uap->attrnamespace,
734 uap->data, uap->nbytes, NOFOLLOW));
735}
736
737static int
738kern_extattr_list_path(struct thread *td, const char *path, int attrnamespace,
739 void *data, size_t nbytes, int follow)
740{
741 struct nameidata nd;
742 int error;
743
744 AUDIT_ARG_VALUE(attrnamespace);
745 NDINIT(&nd, LOOKUP, follow | AUDITVNODE1, UIO_USERSPACE, path);
746 error = namei(&nd);
747 if (error)
748 return (error);
749 NDFREE(&nd, NDF_ONLY_PNBUF);
750
751 error = extattr_list_vp(nd.ni_vp, attrnamespace, data, nbytes, td);
752
753 vrele(nd.ni_vp);
754 return (error);
755}
const char * attrname
Definition: vfs_extattr.c:529
const char * attrname
Definition: vfs_extattr.c:392
const char * attrname
Definition: vfs_extattr.c:428
const char * attrname
Definition: vfs_extattr.c:225
const char * attrname
Definition: vfs_extattr.c:261
const char * attrname
Definition: vfs_extattr.c:76
const char * path
Definition: vfs_extattr.c:72
const char * filename
Definition: vfs_extattr.c:74
int sys_extattr_set_fd(struct thread *td, struct extattr_set_fd_args *uap)
Definition: vfs_extattr.c:231
struct extattr_list_link_args sys_extattr_list_file
int sys_extattr_get_file(struct thread *td, struct extattr_get_file_args *uap)
Definition: vfs_extattr.c:434
int sys_extattr_get_link(struct thread *td, struct extattr_get_link_args *uap)
Definition: vfs_extattr.c:450
static int extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname, void *data, size_t nbytes, struct thread *td)
Definition: vfs_extattr.c:329
int sys_extattr_delete_file(struct thread *td, struct extattr_delete_file_args *uap)
Definition: vfs_extattr.c:566
int sys_extattr_list_fd(struct thread *td, struct extattr_list_fd_args *uap)
Definition: vfs_extattr.c:685
const char * path
Definition: vfs_extattr.c:715
static int kern_extattr_set_path(struct thread *td, const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes, int follow)
Definition: vfs_extattr.c:292
static int extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname, void *data, size_t nbytes, struct thread *td)
Definition: vfs_extattr.c:173
int sys_extattr_delete_link(struct thread *td, struct extattr_delete_link_args *uap)
Definition: vfs_extattr.c:581
int sys_extattr_list_link(struct thread *td, struct extattr_list_link_args *uap)
Definition: vfs_extattr.c:730
int sys_extattr_delete_fd(struct thread *td, struct extattr_delete_fd_args *uap)
Definition: vfs_extattr.c:533
void * data
Definition: vfs_extattr.c:717
static int kern_extattr_delete_path(struct thread *td, const char *path, int attrnamespace, const char *attrname, int follow)
Definition: vfs_extattr.c:589
size_t nbytes
Definition: vfs_extattr.c:718
int sys_extattr_set_file(struct thread *td, struct extattr_set_file_args *uap)
Definition: vfs_extattr.c:267
__FBSDID("$FreeBSD$")
static int kern_extattr_get_path(struct thread *td, const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes, int follow)
Definition: vfs_extattr.c:457
int attrnamespace
Definition: vfs_extattr.c:716
int sys_extattr_set_link(struct thread *td, struct extattr_set_link_args *uap)
Definition: vfs_extattr.c:284
static int kern_extattr_list_path(struct thread *td, const char *path, int attrnamespace, void *data, size_t nbytes, int follow)
Definition: vfs_extattr.c:738
int sys_extattr_get_fd(struct thread *td, struct extattr_get_fd_args *uap)
Definition: vfs_extattr.c:398
static int extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname, struct thread *td)
Definition: vfs_extattr.c:494
int sys_extattrctl(struct thread *td, struct extattrctl_args *uap)
Definition: vfs_extattr.c:80
static int extattr_list_vp(struct vnode *vp, int attrnamespace, void *data, size_t nbytes, struct thread *td)
Definition: vfs_extattr.c:624
void() NDFREE(struct nameidata *ndp, const u_int flags)
Definition: vfs_lookup.c:1555
int namei(struct nameidata *ndp)
Definition: vfs_lookup.c:535
void vfs_unbusy(struct mount *mp)
Definition: vfs_subr.c:850
void vrele(struct vnode *vp)
Definition: vfs_subr.c:3334
int vfs_busy(struct mount *mp, int flags)
Definition: vfs_subr.c:786
int getvnode_path(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp)
int vn_start_write(struct vnode *vp, struct mount **mpp, int flags)
Definition: vfs_vnops.c:1901
void vn_finished_write(struct mount *mp)
Definition: vfs_vnops.c:2009