2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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 * 4. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD$");
40 #include "opt_compat.h"
43 #include <sys/param.h>
44 #include <sys/systm.h>
47 #include <sys/sysent.h>
49 #include <sys/malloc.h>
50 #include <sys/mount.h>
51 #include <sys/mutex.h>
52 #include <sys/sysproto.h>
53 #include <sys/namei.h>
54 #include <sys/filedesc.h>
55 #include <sys/kernel.h>
56 #include <sys/fcntl.h>
58 #include <sys/limits.h>
59 #include <sys/linker.h>
62 #include <sys/unistd.h>
63 #include <sys/vnode.h>
65 #include <sys/dirent.h>
66 #include <sys/extattr.h>
68 #include <sys/syscallsubr.h>
69 #include <sys/sysctl.h>
71 #include <machine/stdarg.h>
73 #include <security/audit/audit.h>
76 #include <vm/vm_object.h>
77 #include <vm/vm_page.h>
80 static int chroot_refuse_vdir_fds(struct filedesc *fdp);
81 static int getutimes(const struct timeval *, enum uio_seg, struct timespec *);
82 static int setfown(struct thread *td, struct vnode *, uid_t, gid_t);
83 static int setfmode(struct thread *td, struct vnode *, int);
84 static int setfflags(struct thread *td, struct vnode *, int);
85 static int setutimes(struct thread *td, struct vnode *,
86 const struct timespec *, int, int);
87 static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred,
90 static int extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
91 size_t nbytes, struct thread *td);
93 int (*union_dircheckp)(struct thread *td, struct vnode **, struct file *);
96 * The module initialization routine for POSIX asynchronous I/O will
97 * set this to the version of AIO that it implements. (Zero means
98 * that it is not implemented.) This value is used here by pathconf()
99 * and in kern_descrip.c by fpathconf().
101 int async_io_version;
104 * Sync each mounted filesystem.
106 #ifndef _SYS_SYSPROTO_H_
113 static int syncprt = 0;
114 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, "");
121 struct sync_args *uap;
123 struct mount *mp, *nmp;
127 mtx_lock(&mountlist_mtx);
128 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
129 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
130 nmp = TAILQ_NEXT(mp, mnt_list);
133 if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
134 vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
135 asyncflag = mp->mnt_flag & MNT_ASYNC;
136 mp->mnt_flag &= ~MNT_ASYNC;
137 vfs_msync(mp, MNT_NOWAIT);
138 VFS_SYNC(mp, MNT_NOWAIT, td);
139 mp->mnt_flag |= asyncflag;
140 vn_finished_write(mp);
142 mtx_lock(&mountlist_mtx);
143 nmp = TAILQ_NEXT(mp, mnt_list);
146 mtx_unlock(&mountlist_mtx);
149 * XXX don't call vfs_bufstats() yet because that routine
150 * was not imported in the Lite2 merge.
155 #endif /* DIAGNOSTIC */
161 /* XXX PRISON: could be per prison flag */
162 static int prison_quotas;
164 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, "");
168 * Change filesystem quotas.
172 #ifndef _SYS_SYSPROTO_H_
173 struct quotactl_args {
183 register struct quotactl_args /* {
190 struct mount *mp, *vmp;
194 if (jailed(td->td_ucred) && !prison_quotas)
197 NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, uap->path, td);
198 if ((error = namei(&nd)) != 0) {
202 NDFREE(&nd, NDF_ONLY_PNBUF);
203 error = vn_start_write(nd.ni_vp, &vmp, V_WAIT | PCATCH);
204 mp = nd.ni_vp->v_mount;
210 error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg, td);
211 vn_finished_write(vmp);
217 * Get filesystem statistics.
219 #ifndef _SYS_SYSPROTO_H_
228 register struct statfs_args /* {
236 error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
238 error = copyout(&sf, uap->buf, sizeof(sf));
243 kern_statfs(struct thread *td, char *path, enum uio_seg pathseg,
247 struct statfs *sp, sb;
252 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, pathseg, path, td);
258 mp = nd.ni_vp->v_mount;
260 NDFREE(&nd, NDF_ONLY_PNBUF);
263 error = mac_check_mount_stat(td->td_ucred, mp);
271 * Set these in case the underlying filesystem fails to do so.
274 sp->f_version = STATFS_VERSION;
275 sp->f_namemax = NAME_MAX;
276 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
277 error = VFS_STATFS(mp, sp, td);
284 bcopy(sp, &sb, sizeof(sb));
285 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
286 prison_enforce_statfs(td->td_ucred, mp, &sb);
295 * Get filesystem statistics.
297 #ifndef _SYS_SYSPROTO_H_
298 struct fstatfs_args {
306 register struct fstatfs_args /* {
314 error = kern_fstatfs(td, uap->fd, &sf);
316 error = copyout(&sf, uap->buf, sizeof(sf));
321 kern_fstatfs(struct thread *td, int fd, struct statfs *buf)
325 struct statfs *sp, sb;
330 error = getvnode(td->td_proc->p_fd, fd, &fp);
335 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
337 AUDIT_ARG(vnode, vp, ARG_VNODE1);
342 VOP_UNLOCK(vp, 0, td);
344 if (vp->v_iflag & VI_DOOMED) {
351 error = mac_check_mount_stat(td->td_ucred, mp);
359 * Set these in case the underlying filesystem fails to do so.
362 sp->f_version = STATFS_VERSION;
363 sp->f_namemax = NAME_MAX;
364 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
365 error = VFS_STATFS(mp, sp, td);
372 bcopy(sp, &sb, sizeof(sb));
373 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
374 prison_enforce_statfs(td->td_ucred, mp, &sb);
383 * Get statistics on all filesystems.
385 #ifndef _SYS_SYSPROTO_H_
386 struct getfsstat_args {
395 register struct getfsstat_args /* {
402 return (kern_getfsstat(td, &uap->buf, uap->bufsize, UIO_USERSPACE,
407 * If (bufsize > 0 && bufseg == UIO_SYSSPACE)
408 * The caller is responsible for freeing memory which will be allocated
412 kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
413 enum uio_seg bufseg, int flags)
415 struct mount *mp, *nmp;
416 struct statfs *sfsp, *sp, sb;
417 size_t count, maxcount;
420 maxcount = bufsize / sizeof(struct statfs);
423 else if (bufseg == UIO_USERSPACE)
425 else /* if (bufseg == UIO_SYSSPACE) */ {
427 mtx_lock(&mountlist_mtx);
428 TAILQ_FOREACH(mp, &mountlist, mnt_list) {
431 mtx_unlock(&mountlist_mtx);
432 if (maxcount > count)
434 sfsp = *buf = malloc(maxcount * sizeof(struct statfs), M_TEMP,
439 mtx_lock(&mountlist_mtx);
440 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
441 if (prison_canseemount(td->td_ucred, mp) != 0) {
442 nmp = TAILQ_NEXT(mp, mnt_list);
446 if (mac_check_mount_stat(td->td_ucred, mp) != 0) {
447 nmp = TAILQ_NEXT(mp, mnt_list);
451 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
452 nmp = TAILQ_NEXT(mp, mnt_list);
455 if (sfsp && count < maxcount) {
458 * Set these in case the underlying filesystem
461 sp->f_version = STATFS_VERSION;
462 sp->f_namemax = NAME_MAX;
463 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
465 * If MNT_NOWAIT or MNT_LAZY is specified, do not
466 * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
467 * overrides MNT_WAIT.
469 if (((flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
470 (flags & MNT_WAIT)) &&
471 (error = VFS_STATFS(mp, sp, td))) {
472 mtx_lock(&mountlist_mtx);
473 nmp = TAILQ_NEXT(mp, mnt_list);
478 bcopy(sp, &sb, sizeof(sb));
479 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
480 prison_enforce_statfs(td->td_ucred, mp, &sb);
483 if (bufseg == UIO_SYSSPACE)
484 bcopy(sp, sfsp, sizeof(*sp));
485 else /* if (bufseg == UIO_USERSPACE) */ {
486 error = copyout(sp, sfsp, sizeof(*sp));
496 mtx_lock(&mountlist_mtx);
497 nmp = TAILQ_NEXT(mp, mnt_list);
500 mtx_unlock(&mountlist_mtx);
502 if (sfsp && count > maxcount)
503 td->td_retval[0] = maxcount;
505 td->td_retval[0] = count;
509 #ifdef COMPAT_FREEBSD4
511 * Get old format filesystem statistics.
513 static void cvtstatfs(struct statfs *, struct ostatfs *);
515 #ifndef _SYS_SYSPROTO_H_
516 struct freebsd4_statfs_args {
522 freebsd4_statfs(td, uap)
524 struct freebsd4_statfs_args /* {
533 error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
536 cvtstatfs(&sf, &osb);
537 return (copyout(&osb, uap->buf, sizeof(osb)));
541 * Get filesystem statistics.
543 #ifndef _SYS_SYSPROTO_H_
544 struct freebsd4_fstatfs_args {
550 freebsd4_fstatfs(td, uap)
552 struct freebsd4_fstatfs_args /* {
561 error = kern_fstatfs(td, uap->fd, &sf);
564 cvtstatfs(&sf, &osb);
565 return (copyout(&osb, uap->buf, sizeof(osb)));
569 * Get statistics on all filesystems.
571 #ifndef _SYS_SYSPROTO_H_
572 struct freebsd4_getfsstat_args {
579 freebsd4_getfsstat(td, uap)
581 register struct freebsd4_getfsstat_args /* {
587 struct statfs *buf, *sp;
592 count = uap->bufsize / sizeof(struct ostatfs);
593 size = count * sizeof(struct statfs);
594 error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags);
596 count = td->td_retval[0];
598 while (count > 0 && error == 0) {
600 error = copyout(&osb, uap->buf, sizeof(osb));
611 * Implement fstatfs() for (NFS) file handles.
613 #ifndef _SYS_SYSPROTO_H_
614 struct freebsd4_fhstatfs_args {
615 struct fhandle *u_fhp;
620 freebsd4_fhstatfs(td, uap)
622 struct freebsd4_fhstatfs_args /* {
623 struct fhandle *u_fhp;
632 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
635 error = kern_fhstatfs(td, fh, &sf);
638 cvtstatfs(&sf, &osb);
639 return (copyout(&osb, uap->buf, sizeof(osb)));
643 * Convert a new format statfs structure to an old format statfs structure.
651 bzero(osp, sizeof(*osp));
652 osp->f_bsize = MIN(nsp->f_bsize, LONG_MAX);
653 osp->f_iosize = MIN(nsp->f_iosize, LONG_MAX);
654 osp->f_blocks = MIN(nsp->f_blocks, LONG_MAX);
655 osp->f_bfree = MIN(nsp->f_bfree, LONG_MAX);
656 osp->f_bavail = MIN(nsp->f_bavail, LONG_MAX);
657 osp->f_files = MIN(nsp->f_files, LONG_MAX);
658 osp->f_ffree = MIN(nsp->f_ffree, LONG_MAX);
659 osp->f_owner = nsp->f_owner;
660 osp->f_type = nsp->f_type;
661 osp->f_flags = nsp->f_flags;
662 osp->f_syncwrites = MIN(nsp->f_syncwrites, LONG_MAX);
663 osp->f_asyncwrites = MIN(nsp->f_asyncwrites, LONG_MAX);
664 osp->f_syncreads = MIN(nsp->f_syncreads, LONG_MAX);
665 osp->f_asyncreads = MIN(nsp->f_asyncreads, LONG_MAX);
666 bcopy(nsp->f_fstypename, osp->f_fstypename,
667 MIN(MFSNAMELEN, OMNAMELEN));
668 bcopy(nsp->f_mntonname, osp->f_mntonname,
669 MIN(MFSNAMELEN, OMNAMELEN));
670 bcopy(nsp->f_mntfromname, osp->f_mntfromname,
671 MIN(MFSNAMELEN, OMNAMELEN));
672 osp->f_fsid = nsp->f_fsid;
674 #endif /* COMPAT_FREEBSD4 */
677 * Change current working directory to a given file descriptor.
679 #ifndef _SYS_SYSPROTO_H_
687 struct fchdir_args /* {
691 register struct filedesc *fdp = td->td_proc->p_fd;
692 struct vnode *vp, *tdp, *vpold;
698 AUDIT_ARG(fd, uap->fd);
699 if ((error = getvnode(fdp, uap->fd, &fp)) != 0)
704 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
705 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
706 AUDIT_ARG(vnode, vp, ARG_VNODE1);
707 if (vp->v_type != VDIR)
710 else if ((error = mac_check_vnode_chdir(td->td_ucred, vp)) != 0) {
714 error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td);
715 while (!error && (mp = vp->v_mountedhere) != NULL) {
717 if (vfs_busy(mp, 0, 0, td))
719 tvfslocked = VFS_LOCK_GIANT(mp);
720 error = VFS_ROOT(mp, LK_EXCLUSIVE, &tdp, td);
723 VFS_UNLOCK_GIANT(tvfslocked);
727 VFS_UNLOCK_GIANT(vfslocked);
729 vfslocked = tvfslocked;
733 VFS_UNLOCK_GIANT(vfslocked);
736 VOP_UNLOCK(vp, 0, td);
737 VFS_UNLOCK_GIANT(vfslocked);
738 FILEDESC_LOCK_FAST(fdp);
739 vpold = fdp->fd_cdir;
741 FILEDESC_UNLOCK_FAST(fdp);
742 vfslocked = VFS_LOCK_GIANT(vpold->v_mount);
744 VFS_UNLOCK_GIANT(vfslocked);
749 * Change current working directory (``.'').
751 #ifndef _SYS_SYSPROTO_H_
759 struct chdir_args /* {
764 return (kern_chdir(td, uap->path, UIO_USERSPACE));
768 kern_chdir(struct thread *td, char *path, enum uio_seg pathseg)
770 register struct filedesc *fdp = td->td_proc->p_fd;
776 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1 | MPSAFE,
778 if ((error = namei(&nd)) != 0)
780 vfslocked = NDHASGIANT(&nd);
781 if ((error = change_dir(nd.ni_vp, td)) != 0) {
783 VFS_UNLOCK_GIANT(vfslocked);
784 NDFREE(&nd, NDF_ONLY_PNBUF);
787 VOP_UNLOCK(nd.ni_vp, 0, td);
788 VFS_UNLOCK_GIANT(vfslocked);
789 NDFREE(&nd, NDF_ONLY_PNBUF);
790 FILEDESC_LOCK_FAST(fdp);
792 fdp->fd_cdir = nd.ni_vp;
793 FILEDESC_UNLOCK_FAST(fdp);
794 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
796 VFS_UNLOCK_GIANT(vfslocked);
801 * Helper function for raised chroot(2) security function: Refuse if
802 * any filedescriptors are open directories.
805 chroot_refuse_vdir_fds(fdp)
806 struct filedesc *fdp;
812 FILEDESC_LOCK_ASSERT(fdp, MA_OWNED);
813 for (fd = 0; fd < fdp->fd_nfiles ; fd++) {
814 fp = fget_locked(fdp, fd);
817 if (fp->f_type == DTYPE_VNODE) {
819 if (vp->v_type == VDIR)
827 * This sysctl determines if we will allow a process to chroot(2) if it
828 * has a directory open:
829 * 0: disallowed for all processes.
830 * 1: allowed for processes that were not already chroot(2)'ed.
831 * 2: allowed for all processes.
834 static int chroot_allow_open_directories = 1;
836 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW,
837 &chroot_allow_open_directories, 0, "");
840 * Change notion of root (``/'') directory.
842 #ifndef _SYS_SYSPROTO_H_
850 struct chroot_args /* {
858 error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
861 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
862 UIO_USERSPACE, uap->path, td);
866 vfslocked = NDHASGIANT(&nd);
867 if ((error = change_dir(nd.ni_vp, td)) != 0)
870 if ((error = mac_check_vnode_chroot(td->td_ucred, nd.ni_vp)))
873 VOP_UNLOCK(nd.ni_vp, 0, td);
874 error = change_root(nd.ni_vp, td);
876 VFS_UNLOCK_GIANT(vfslocked);
877 NDFREE(&nd, NDF_ONLY_PNBUF);
881 VFS_UNLOCK_GIANT(vfslocked);
883 NDFREE(&nd, NDF_ONLY_PNBUF);
888 * Common routine for chroot and chdir. Callers must provide a locked vnode
898 ASSERT_VOP_LOCKED(vp, "change_dir(): vp not locked");
899 if (vp->v_type != VDIR)
902 error = mac_check_vnode_chdir(td->td_ucred, vp);
906 error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td);
911 * Common routine for kern_chroot() and jail_attach(). The caller is
912 * responsible for invoking suser() and mac_check_chroot() to authorize this
920 struct filedesc *fdp;
925 VFS_ASSERT_GIANT(vp->v_mount);
926 fdp = td->td_proc->p_fd;
928 if (chroot_allow_open_directories == 0 ||
929 (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) {
930 error = chroot_refuse_vdir_fds(fdp);
932 FILEDESC_UNLOCK(fdp);
936 oldvp = fdp->fd_rdir;
943 FILEDESC_UNLOCK(fdp);
944 vfslocked = VFS_LOCK_GIANT(oldvp->v_mount);
946 VFS_UNLOCK_GIANT(vfslocked);
951 * Check permissions, allocate an open file structure,
952 * and call the device open routine if any.
956 #ifndef _SYS_SYSPROTO_H_
966 register struct open_args /* {
974 error = kern_open(td, uap->path, UIO_USERSPACE, uap->flags, uap->mode);
975 if (mtx_owned(&Giant))
976 printf("open: %s: %d\n", uap->path, error);
981 kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags,
984 struct proc *p = td->td_proc;
985 struct filedesc *fdp = p->p_fd;
992 int type, indx, error;
997 AUDIT_ARG(fflags, flags);
998 AUDIT_ARG(mode, mode);
999 if ((flags & O_ACCMODE) == O_ACCMODE)
1001 flags = FFLAGS(flags);
1002 error = falloc(td, &nfp, &indx);
1005 /* An extra reference on `nfp' has been held for us by falloc(). */
1007 cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
1008 NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, td);
1009 td->td_dupfd = -1; /* XXX check for fdopen */
1010 error = vn_open(&nd, &flags, cmode, indx);
1013 * If the vn_open replaced the method vector, something
1014 * wonderous happened deep below and we just pass it up
1015 * pretending we know what we do.
1017 if (error == ENXIO && fp->f_ops != &badfileops) {
1019 td->td_retval[0] = indx;
1024 * release our own reference
1029 * handle special fdopen() case. bleh. dupfdopen() is
1030 * responsible for dropping the old contents of ofiles[indx]
1033 if ((error == ENODEV || error == ENXIO) &&
1034 td->td_dupfd >= 0 && /* XXX from fdopen */
1036 dupfdopen(td, fdp, indx, td->td_dupfd, flags, error)) == 0) {
1037 td->td_retval[0] = indx;
1041 * Clean up the descriptor, but only if another thread hadn't
1042 * replaced or closed it.
1044 fdclose(fdp, fp, indx, td);
1046 if (error == ERESTART)
1051 vfslocked = NDHASGIANT(&nd);
1052 NDFREE(&nd, NDF_ONLY_PNBUF);
1056 * There should be 2 references on the file, one from the descriptor
1057 * table, and one for us.
1059 * Handle the case where someone closed the file (via its file
1060 * descriptor) while we were blocked. The end result should look
1061 * like opening the file succeeded but it was immediately closed.
1062 * We call vn_close() manually because we haven't yet hooked up
1063 * the various 'struct file' fields.
1067 if (fp->f_count == 1) {
1069 KASSERT(fdp->fd_ofiles[indx] != fp,
1070 ("Open file descriptor lost all refs"));
1072 FILEDESC_UNLOCK(fdp);
1073 VOP_UNLOCK(vp, 0, td);
1074 vn_close(vp, flags & FMASK, fp->f_cred, td);
1075 VFS_UNLOCK_GIANT(vfslocked);
1077 td->td_retval[0] = indx;
1081 if (fp->f_data == NULL)
1083 fp->f_flag = flags & FMASK;
1084 if (fp->f_ops == &badfileops)
1087 fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE);
1089 FILEDESC_UNLOCK(fdp);
1091 VOP_UNLOCK(vp, 0, td);
1092 if (flags & (O_EXLOCK | O_SHLOCK)) {
1093 lf.l_whence = SEEK_SET;
1096 if (flags & O_EXLOCK)
1097 lf.l_type = F_WRLCK;
1099 lf.l_type = F_RDLCK;
1101 if ((flags & FNONBLOCK) == 0)
1103 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf,
1106 fp->f_flag |= FHASLOCK;
1108 if (flags & O_TRUNC) {
1109 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
1111 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
1114 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1116 error = mac_check_vnode_write(td->td_ucred, fp->f_cred, vp);
1119 error = VOP_SETATTR(vp, &vat, td->td_ucred, td);
1120 VOP_UNLOCK(vp, 0, td);
1121 vn_finished_write(mp);
1125 VFS_UNLOCK_GIANT(vfslocked);
1127 * Release our private reference, leaving the one associated with
1128 * the descriptor table intact.
1131 td->td_retval[0] = indx;
1134 VFS_UNLOCK_GIANT(vfslocked);
1135 fdclose(fdp, fp, indx, td);
1146 #ifndef _SYS_SYSPROTO_H_
1147 struct ocreat_args {
1155 register struct ocreat_args /* {
1161 return (kern_open(td, uap->path, UIO_USERSPACE,
1162 O_WRONLY | O_CREAT | O_TRUNC, uap->mode));
1164 #endif /* COMPAT_43 */
1167 * Create a special file.
1169 #ifndef _SYS_SYSPROTO_H_
1179 register struct mknod_args /* {
1186 return (kern_mknod(td, uap->path, UIO_USERSPACE, uap->mode, uap->dev));
1190 kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode,
1198 struct nameidata nd;
1201 AUDIT_ARG(mode, mode);
1202 AUDIT_ARG(dev, dev);
1203 switch (mode & S_IFMT) {
1209 error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
1216 NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
1218 if ((error = namei(&nd)) != 0)
1220 vfslocked = NDHASGIANT(&nd);
1223 NDFREE(&nd, NDF_ONLY_PNBUF);
1224 if (vp == nd.ni_dvp)
1229 VFS_UNLOCK_GIANT(vfslocked);
1233 FILEDESC_LOCK_FAST(td->td_proc->p_fd);
1234 vattr.va_mode = (mode & ALLPERMS) &
1235 ~td->td_proc->p_fd->fd_cmask;
1236 FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
1237 vattr.va_rdev = dev;
1240 switch (mode & S_IFMT) {
1241 case S_IFMT: /* used by badsect to flag bad sectors */
1242 vattr.va_type = VBAD;
1245 vattr.va_type = VCHR;
1248 vattr.va_type = VBLK;
1258 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1259 NDFREE(&nd, NDF_ONLY_PNBUF);
1261 VFS_UNLOCK_GIANT(vfslocked);
1262 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1267 if (error == 0 && !whiteout)
1268 error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp,
1269 &nd.ni_cnd, &vattr);
1272 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1274 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE);
1276 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp,
1277 &nd.ni_cnd, &vattr);
1282 NDFREE(&nd, NDF_ONLY_PNBUF);
1284 vn_finished_write(mp);
1285 VFS_UNLOCK_GIANT(vfslocked);
1290 * Create a named pipe.
1292 #ifndef _SYS_SYSPROTO_H_
1293 struct mkfifo_args {
1301 register struct mkfifo_args /* {
1307 return (kern_mkfifo(td, uap->path, UIO_USERSPACE, uap->mode));
1311 kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode)
1316 struct nameidata nd;
1321 NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
1323 if ((error = namei(&nd)) != 0)
1325 vfslocked = NDHASGIANT(&nd);
1326 if (nd.ni_vp != NULL) {
1327 NDFREE(&nd, NDF_ONLY_PNBUF);
1328 if (nd.ni_vp == nd.ni_dvp)
1333 VFS_UNLOCK_GIANT(vfslocked);
1336 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1337 NDFREE(&nd, NDF_ONLY_PNBUF);
1339 VFS_UNLOCK_GIANT(vfslocked);
1340 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1345 vattr.va_type = VFIFO;
1346 FILEDESC_LOCK_FAST(td->td_proc->p_fd);
1347 vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask;
1348 FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
1350 error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
1355 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1356 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
1363 vn_finished_write(mp);
1364 VFS_UNLOCK_GIANT(vfslocked);
1365 NDFREE(&nd, NDF_ONLY_PNBUF);
1370 * Make a hard file link.
1372 #ifndef _SYS_SYSPROTO_H_
1381 register struct link_args /* {
1388 error = kern_link(td, uap->path, uap->link, UIO_USERSPACE);
1392 SYSCTL_DECL(_security_bsd);
1394 static int hardlink_check_uid = 0;
1395 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_uid, CTLFLAG_RW,
1396 &hardlink_check_uid, 0,
1397 "Unprivileged processes cannot create hard links to files owned by other "
1399 static int hardlink_check_gid = 0;
1400 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_gid, CTLFLAG_RW,
1401 &hardlink_check_gid, 0,
1402 "Unprivileged processes cannot create hard links to files owned by other "
1406 can_hardlink(struct vnode *vp, struct thread *td, struct ucred *cred)
1411 if (suser_cred(cred, SUSER_ALLOWJAIL) == 0)
1414 if (!hardlink_check_uid && !hardlink_check_gid)
1417 error = VOP_GETATTR(vp, &va, cred, td);
1421 if (hardlink_check_uid) {
1422 if (cred->cr_uid != va.va_uid)
1426 if (hardlink_check_gid) {
1427 if (!groupmember(va.va_gid, cred))
1435 kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg)
1439 struct nameidata nd;
1445 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, segflg, path, td);
1446 if ((error = namei(&nd)) != 0)
1448 vfslocked = NDHASGIANT(&nd);
1449 NDFREE(&nd, NDF_ONLY_PNBUF);
1451 if (vp->v_type == VDIR) {
1453 VFS_UNLOCK_GIANT(vfslocked);
1454 return (EPERM); /* POSIX */
1456 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
1458 VFS_UNLOCK_GIANT(vfslocked);
1461 NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE2,
1463 if ((error = namei(&nd)) == 0) {
1464 lvfslocked = NDHASGIANT(&nd);
1465 if (nd.ni_vp != NULL) {
1466 if (nd.ni_dvp == nd.ni_vp)
1472 } else if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td))
1474 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1475 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
1476 error = can_hardlink(vp, td, td->td_ucred);
1479 error = mac_check_vnode_link(td->td_ucred,
1480 nd.ni_dvp, vp, &nd.ni_cnd);
1483 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
1484 VOP_UNLOCK(vp, 0, td);
1487 NDFREE(&nd, NDF_ONLY_PNBUF);
1488 VFS_UNLOCK_GIANT(lvfslocked);
1491 vn_finished_write(mp);
1492 VFS_UNLOCK_GIANT(vfslocked);
1497 * Make a symbolic link.
1499 #ifndef _SYS_SYSPROTO_H_
1500 struct symlink_args {
1508 register struct symlink_args /* {
1514 return (kern_symlink(td, uap->path, uap->link, UIO_USERSPACE));
1518 kern_symlink(struct thread *td, char *path, char *link, enum uio_seg segflg)
1524 struct nameidata nd;
1527 if (segflg == UIO_SYSSPACE) {
1530 syspath = uma_zalloc(namei_zone, M_WAITOK);
1531 if ((error = copyinstr(path, syspath, MAXPATHLEN, NULL)) != 0)
1536 NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
1538 if ((error = namei(&nd)) != 0)
1540 vfslocked = NDHASGIANT(&nd);
1542 NDFREE(&nd, NDF_ONLY_PNBUF);
1543 if (nd.ni_vp == nd.ni_dvp)
1548 VFS_UNLOCK_GIANT(vfslocked);
1552 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1553 NDFREE(&nd, NDF_ONLY_PNBUF);
1555 VFS_UNLOCK_GIANT(vfslocked);
1556 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1561 FILEDESC_LOCK_FAST(td->td_proc->p_fd);
1562 vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask;
1563 FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
1565 vattr.va_type = VLNK;
1566 error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
1571 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1572 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath);
1578 NDFREE(&nd, NDF_ONLY_PNBUF);
1580 vn_finished_write(mp);
1581 VFS_UNLOCK_GIANT(vfslocked);
1583 if (segflg != UIO_SYSSPACE)
1584 uma_zfree(namei_zone, syspath);
1589 * Delete a whiteout from the filesystem.
1594 register struct undelete_args /* {
1600 struct nameidata nd;
1605 NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | MPSAFE | AUDITVNODE1,
1606 UIO_USERSPACE, uap->path, td);
1610 vfslocked = NDHASGIANT(&nd);
1612 if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) {
1613 NDFREE(&nd, NDF_ONLY_PNBUF);
1614 if (nd.ni_vp == nd.ni_dvp)
1620 VFS_UNLOCK_GIANT(vfslocked);
1623 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1624 NDFREE(&nd, NDF_ONLY_PNBUF);
1626 VFS_UNLOCK_GIANT(vfslocked);
1627 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1631 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1632 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE);
1633 NDFREE(&nd, NDF_ONLY_PNBUF);
1635 vn_finished_write(mp);
1636 VFS_UNLOCK_GIANT(vfslocked);
1641 * Delete a name from the filesystem.
1643 #ifndef _SYS_SYSPROTO_H_
1644 struct unlink_args {
1651 struct unlink_args /* {
1657 error = kern_unlink(td, uap->path, UIO_USERSPACE);
1662 kern_unlink(struct thread *td, char *path, enum uio_seg pathseg)
1667 struct nameidata nd;
1672 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | AUDITVNODE1,
1674 if ((error = namei(&nd)) != 0)
1675 return (error == EINVAL ? EPERM : error);
1676 vfslocked = NDHASGIANT(&nd);
1678 if (vp->v_type == VDIR)
1679 error = EPERM; /* POSIX */
1682 * The root of a mounted filesystem cannot be deleted.
1684 * XXX: can this only be a VDIR case?
1686 if (vp->v_vflag & VV_ROOT)
1690 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1691 NDFREE(&nd, NDF_ONLY_PNBUF);
1693 if (vp == nd.ni_dvp)
1697 VFS_UNLOCK_GIANT(vfslocked);
1698 if ((error = vn_start_write(NULL, &mp,
1699 V_XSLEEP | PCATCH)) != 0)
1704 error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp,
1709 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1710 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd);
1714 vn_finished_write(mp);
1716 NDFREE(&nd, NDF_ONLY_PNBUF);
1718 if (vp == nd.ni_dvp)
1722 VFS_UNLOCK_GIANT(vfslocked);
1727 * Reposition read/write file offset.
1729 #ifndef _SYS_SYSPROTO_H_
1740 register struct lseek_args /* {
1747 struct ucred *cred = td->td_ucred;
1755 if ((error = fget(td, uap->fd, &fp)) != 0)
1757 if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) {
1762 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1763 noneg = (vp->v_type != VCHR);
1764 offset = uap->offset;
1765 switch (uap->whence) {
1768 (fp->f_offset < 0 ||
1769 (offset > 0 && fp->f_offset > OFF_MAX - offset))) {
1773 offset += fp->f_offset;
1776 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1777 error = VOP_GETATTR(vp, &vattr, cred, td);
1778 VOP_UNLOCK(vp, 0, td);
1782 (vattr.va_size > OFF_MAX ||
1783 (offset > 0 && vattr.va_size > OFF_MAX - offset))) {
1787 offset += vattr.va_size;
1794 if (error == 0 && noneg && offset < 0)
1798 fp->f_offset = offset;
1799 *(off_t *)(td->td_retval) = fp->f_offset;
1802 VFS_UNLOCK_GIANT(vfslocked);
1806 #if defined(COMPAT_43)
1808 * Reposition read/write file offset.
1810 #ifndef _SYS_SYSPROTO_H_
1811 struct olseek_args {
1820 register struct olseek_args /* {
1826 struct lseek_args /* {
1835 nuap.offset = uap->offset;
1836 nuap.whence = uap->whence;
1837 error = lseek(td, &nuap);
1840 #endif /* COMPAT_43 */
1843 * Check access permissions using passed credentials.
1846 vn_access(vp, user_flags, cred, td)
1854 /* Flags == 0 means only check for existence. */
1858 if (user_flags & R_OK)
1860 if (user_flags & W_OK)
1862 if (user_flags & X_OK)
1865 error = mac_check_vnode_access(cred, vp, flags);
1869 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
1870 error = VOP_ACCESS(vp, flags, cred, td);
1876 * Check access permissions using "real" credentials.
1878 #ifndef _SYS_SYSPROTO_H_
1879 struct access_args {
1887 register struct access_args /* {
1893 return (kern_access(td, uap->path, UIO_USERSPACE, uap->flags));
1897 kern_access(struct thread *td, char *path, enum uio_seg pathseg, int flags)
1899 struct ucred *cred, *tmpcred;
1900 register struct vnode *vp;
1901 struct nameidata nd;
1906 * Create and modify a temporary credential instead of one that
1907 * is potentially shared. This could also mess up socket
1908 * buffer accounting which can run in an interrupt context.
1910 cred = td->td_ucred;
1911 tmpcred = crdup(cred);
1912 tmpcred->cr_uid = cred->cr_ruid;
1913 tmpcred->cr_groups[0] = cred->cr_rgid;
1914 td->td_ucred = tmpcred;
1915 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
1917 if ((error = namei(&nd)) != 0)
1919 vfslocked = NDHASGIANT(&nd);
1922 error = vn_access(vp, flags, tmpcred, td);
1923 NDFREE(&nd, NDF_ONLY_PNBUF);
1925 VFS_UNLOCK_GIANT(vfslocked);
1927 td->td_ucred = cred;
1933 * Check access permissions using "effective" credentials.
1935 #ifndef _SYS_SYSPROTO_H_
1936 struct eaccess_args {
1944 register struct eaccess_args /* {
1950 return (kern_eaccess(td, uap->path, UIO_USERSPACE, uap->flags));
1954 kern_eaccess(struct thread *td, char *path, enum uio_seg pathseg, int flags)
1956 struct nameidata nd;
1961 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
1963 if ((error = namei(&nd)) != 0)
1966 vfslocked = NDHASGIANT(&nd);
1967 error = vn_access(vp, flags, td->td_ucred, td);
1968 NDFREE(&nd, NDF_ONLY_PNBUF);
1970 VFS_UNLOCK_GIANT(vfslocked);
1974 #if defined(COMPAT_43)
1976 * Get file status; this version follows links.
1978 #ifndef _SYS_SYSPROTO_H_
1987 register struct ostat_args /* {
1996 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
2000 error = copyout(&osb, uap->ub, sizeof (osb));
2005 * Get file status; this version does not follow links.
2007 #ifndef _SYS_SYSPROTO_H_
2008 struct olstat_args {
2016 register struct olstat_args /* {
2025 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
2029 error = copyout(&osb, uap->ub, sizeof (osb));
2034 * Convert from an old to a new stat structure.
2042 ost->st_dev = st->st_dev;
2043 ost->st_ino = st->st_ino;
2044 ost->st_mode = st->st_mode;
2045 ost->st_nlink = st->st_nlink;
2046 ost->st_uid = st->st_uid;
2047 ost->st_gid = st->st_gid;
2048 ost->st_rdev = st->st_rdev;
2049 if (st->st_size < (quad_t)1 << 32)
2050 ost->st_size = st->st_size;
2053 ost->st_atime = st->st_atime;
2054 ost->st_mtime = st->st_mtime;
2055 ost->st_ctime = st->st_ctime;
2056 ost->st_blksize = st->st_blksize;
2057 ost->st_blocks = st->st_blocks;
2058 ost->st_flags = st->st_flags;
2059 ost->st_gen = st->st_gen;
2061 #endif /* COMPAT_43 */
2064 * Get file status; this version follows links.
2066 #ifndef _SYS_SYSPROTO_H_
2075 register struct stat_args /* {
2083 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
2085 error = copyout(&sb, uap->ub, sizeof (sb));
2090 kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
2092 struct nameidata nd;
2094 int error, vfslocked;
2097 FOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE | AUDITVNODE1,
2099 if ((error = namei(&nd)) != 0)
2101 vfslocked = NDHASGIANT(&nd);
2102 error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td);
2103 NDFREE(&nd, NDF_ONLY_PNBUF);
2105 VFS_UNLOCK_GIANT(vfslocked);
2113 * Get file status; this version does not follow links.
2115 #ifndef _SYS_SYSPROTO_H_
2124 register struct lstat_args /* {
2132 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
2134 error = copyout(&sb, uap->ub, sizeof (sb));
2139 kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
2143 struct nameidata nd;
2144 int error, vfslocked;
2147 NOFOLLOW | LOCKLEAF | LOCKSHARED | MPSAFE | AUDITVNODE1,
2149 if ((error = namei(&nd)) != 0)
2151 vfslocked = NDHASGIANT(&nd);
2153 error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
2154 NDFREE(&nd, NDF_ONLY_PNBUF);
2156 VFS_UNLOCK_GIANT(vfslocked);
2164 * Implementation of the NetBSD [l]stat() functions.
2171 bzero(nsb, sizeof *nsb);
2172 nsb->st_dev = sb->st_dev;
2173 nsb->st_ino = sb->st_ino;
2174 nsb->st_mode = sb->st_mode;
2175 nsb->st_nlink = sb->st_nlink;
2176 nsb->st_uid = sb->st_uid;
2177 nsb->st_gid = sb->st_gid;
2178 nsb->st_rdev = sb->st_rdev;
2179 nsb->st_atimespec = sb->st_atimespec;
2180 nsb->st_mtimespec = sb->st_mtimespec;
2181 nsb->st_ctimespec = sb->st_ctimespec;
2182 nsb->st_size = sb->st_size;
2183 nsb->st_blocks = sb->st_blocks;
2184 nsb->st_blksize = sb->st_blksize;
2185 nsb->st_flags = sb->st_flags;
2186 nsb->st_gen = sb->st_gen;
2187 nsb->st_birthtimespec = sb->st_birthtimespec;
2190 #ifndef _SYS_SYSPROTO_H_
2199 register struct nstat_args /* {
2208 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
2211 cvtnstat(&sb, &nsb);
2212 error = copyout(&nsb, uap->ub, sizeof (nsb));
2217 * NetBSD lstat. Get file status; this version does not follow links.
2219 #ifndef _SYS_SYSPROTO_H_
2228 register struct nlstat_args /* {
2237 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
2240 cvtnstat(&sb, &nsb);
2241 error = copyout(&nsb, uap->ub, sizeof (nsb));
2246 * Get configurable pathname variables.
2248 #ifndef _SYS_SYSPROTO_H_
2249 struct pathconf_args {
2257 register struct pathconf_args /* {
2263 return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name));
2267 kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name)
2269 struct nameidata nd;
2270 int error, vfslocked;
2272 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
2274 if ((error = namei(&nd)) != 0)
2276 vfslocked = NDHASGIANT(&nd);
2277 NDFREE(&nd, NDF_ONLY_PNBUF);
2279 /* If asynchronous I/O is available, it works for all files. */
2280 if (name == _PC_ASYNC_IO)
2281 td->td_retval[0] = async_io_version;
2283 error = VOP_PATHCONF(nd.ni_vp, name, td->td_retval);
2285 VFS_UNLOCK_GIANT(vfslocked);
2290 * Return target name of a symbolic link.
2292 #ifndef _SYS_SYSPROTO_H_
2293 struct readlink_args {
2302 register struct readlink_args /* {
2309 return (kern_readlink(td, uap->path, UIO_USERSPACE, uap->buf,
2310 UIO_USERSPACE, uap->count));
2314 kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf,
2315 enum uio_seg bufseg, int count)
2317 register struct vnode *vp;
2321 struct nameidata nd;
2324 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
2326 if ((error = namei(&nd)) != 0)
2328 NDFREE(&nd, NDF_ONLY_PNBUF);
2329 vfslocked = NDHASGIANT(&nd);
2332 error = mac_check_vnode_readlink(td->td_ucred, vp);
2335 VFS_UNLOCK_GIANT(vfslocked);
2339 if (vp->v_type != VLNK)
2342 aiov.iov_base = buf;
2343 aiov.iov_len = count;
2344 auio.uio_iov = &aiov;
2345 auio.uio_iovcnt = 1;
2346 auio.uio_offset = 0;
2347 auio.uio_rw = UIO_READ;
2348 auio.uio_segflg = bufseg;
2350 auio.uio_resid = count;
2351 error = VOP_READLINK(vp, &auio, td->td_ucred);
2354 VFS_UNLOCK_GIANT(vfslocked);
2355 td->td_retval[0] = count - auio.uio_resid;
2360 * Common implementation code for chflags() and fchflags().
2363 setfflags(td, vp, flags)
2373 * Prevent non-root users from setting flags on devices. When
2374 * a device is reused, users can retain ownership of the device
2375 * if they are allowed to set flags and programs assume that
2376 * chown can't fail when done as root.
2378 if (vp->v_type == VCHR || vp->v_type == VBLK) {
2379 error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
2384 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2386 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2387 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2389 vattr.va_flags = flags;
2391 error = mac_check_vnode_setflags(td->td_ucred, vp, vattr.va_flags);
2394 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2395 VOP_UNLOCK(vp, 0, td);
2396 vn_finished_write(mp);
2401 * Change flags of a file given a path name.
2403 #ifndef _SYS_SYSPROTO_H_
2404 struct chflags_args {
2412 register struct chflags_args /* {
2418 struct nameidata nd;
2421 AUDIT_ARG(fflags, uap->flags);
2422 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE,
2424 if ((error = namei(&nd)) != 0)
2426 NDFREE(&nd, NDF_ONLY_PNBUF);
2427 vfslocked = NDHASGIANT(&nd);
2428 error = setfflags(td, nd.ni_vp, uap->flags);
2430 VFS_UNLOCK_GIANT(vfslocked);
2435 * Same as chflags() but doesn't follow symlinks.
2440 register struct lchflags_args /* {
2446 struct nameidata nd;
2449 AUDIT_ARG(fflags, uap->flags);
2450 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE,
2452 if ((error = namei(&nd)) != 0)
2454 vfslocked = NDHASGIANT(&nd);
2455 NDFREE(&nd, NDF_ONLY_PNBUF);
2456 error = setfflags(td, nd.ni_vp, uap->flags);
2458 VFS_UNLOCK_GIANT(vfslocked);
2463 * Change flags of a file given a file descriptor.
2465 #ifndef _SYS_SYSPROTO_H_
2466 struct fchflags_args {
2474 register struct fchflags_args /* {
2483 AUDIT_ARG(fd, uap->fd);
2484 AUDIT_ARG(fflags, uap->flags);
2485 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
2487 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2489 vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY, td);
2490 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1);
2491 VOP_UNLOCK(fp->f_vnode, 0, td);
2493 error = setfflags(td, fp->f_vnode, uap->flags);
2494 VFS_UNLOCK_GIANT(vfslocked);
2500 * Common implementation code for chmod(), lchmod() and fchmod().
2503 setfmode(td, vp, mode)
2512 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2514 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2515 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2517 vattr.va_mode = mode & ALLPERMS;
2519 error = mac_check_vnode_setmode(td->td_ucred, vp, vattr.va_mode);
2522 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2523 VOP_UNLOCK(vp, 0, td);
2524 vn_finished_write(mp);
2529 * Change mode of a file given path name.
2531 #ifndef _SYS_SYSPROTO_H_
2540 register struct chmod_args /* {
2546 return (kern_chmod(td, uap->path, UIO_USERSPACE, uap->mode));
2550 kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode)
2553 struct nameidata nd;
2556 AUDIT_ARG(mode, mode);
2557 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td);
2558 if ((error = namei(&nd)) != 0)
2560 vfslocked = NDHASGIANT(&nd);
2561 NDFREE(&nd, NDF_ONLY_PNBUF);
2562 error = setfmode(td, nd.ni_vp, mode);
2564 VFS_UNLOCK_GIANT(vfslocked);
2569 * Change mode of a file given path name (don't follow links.)
2571 #ifndef _SYS_SYSPROTO_H_
2572 struct lchmod_args {
2580 register struct lchmod_args /* {
2586 struct nameidata nd;
2589 AUDIT_ARG(mode, (mode_t)uap->mode);
2590 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, UIO_USERSPACE,
2592 if ((error = namei(&nd)) != 0)
2594 vfslocked = NDHASGIANT(&nd);
2595 NDFREE(&nd, NDF_ONLY_PNBUF);
2596 error = setfmode(td, nd.ni_vp, uap->mode);
2598 VFS_UNLOCK_GIANT(vfslocked);
2603 * Change mode of a file given a file descriptor.
2605 #ifndef _SYS_SYSPROTO_H_
2606 struct fchmod_args {
2614 register struct fchmod_args /* {
2623 AUDIT_ARG(fd, uap->fd);
2624 AUDIT_ARG(mode, uap->mode);
2625 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
2627 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2629 vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY, td);
2630 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1);
2631 VOP_UNLOCK(fp->f_vnode, 0, td);
2633 error = setfmode(td, fp->f_vnode, uap->mode);
2634 VFS_UNLOCK_GIANT(vfslocked);
2640 * Common implementation for chown(), lchown(), and fchown()
2643 setfown(td, vp, uid, gid)
2653 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2655 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2656 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2661 error = mac_check_vnode_setowner(td->td_ucred, vp, vattr.va_uid,
2665 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2666 VOP_UNLOCK(vp, 0, td);
2667 vn_finished_write(mp);
2672 * Set ownership given a path name.
2674 #ifndef _SYS_SYSPROTO_H_
2684 register struct chown_args /* {
2691 return (kern_chown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid));
2695 kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid,
2699 struct nameidata nd;
2702 AUDIT_ARG(owner, uid, gid);
2703 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td);
2704 if ((error = namei(&nd)) != 0)
2706 vfslocked = NDHASGIANT(&nd);
2707 NDFREE(&nd, NDF_ONLY_PNBUF);
2708 error = setfown(td, nd.ni_vp, uid, gid);
2710 VFS_UNLOCK_GIANT(vfslocked);
2715 * Set ownership given a path name, do not cross symlinks.
2717 #ifndef _SYS_SYSPROTO_H_
2718 struct lchown_args {
2727 register struct lchown_args /* {
2734 return (kern_lchown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid));
2738 kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid,
2742 struct nameidata nd;
2745 AUDIT_ARG(owner, uid, gid);
2746 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td);
2747 if ((error = namei(&nd)) != 0)
2749 vfslocked = NDHASGIANT(&nd);
2750 NDFREE(&nd, NDF_ONLY_PNBUF);
2751 error = setfown(td, nd.ni_vp, uid, gid);
2753 VFS_UNLOCK_GIANT(vfslocked);
2758 * Set ownership given a file descriptor.
2760 #ifndef _SYS_SYSPROTO_H_
2761 struct fchown_args {
2770 register struct fchown_args /* {
2780 AUDIT_ARG(fd, uap->fd);
2781 AUDIT_ARG(owner, uap->uid, uap->gid);
2782 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
2784 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2786 vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY, td);
2787 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1);
2788 VOP_UNLOCK(fp->f_vnode, 0, td);
2790 error = setfown(td, fp->f_vnode, uap->uid, uap->gid);
2791 VFS_UNLOCK_GIANT(vfslocked);
2797 * Common implementation code for utimes(), lutimes(), and futimes().
2800 getutimes(usrtvp, tvpseg, tsp)
2801 const struct timeval *usrtvp;
2802 enum uio_seg tvpseg;
2803 struct timespec *tsp;
2805 struct timeval tv[2];
2806 const struct timeval *tvp;
2809 if (usrtvp == NULL) {
2811 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]);
2814 if (tvpseg == UIO_SYSSPACE) {
2817 if ((error = copyin(usrtvp, tv, sizeof(tv))) != 0)
2822 if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000 ||
2823 tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
2825 TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]);
2826 TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]);
2832 * Common implementation code for utimes(), lutimes(), and futimes().
2835 setutimes(td, vp, ts, numtimes, nullflag)
2838 const struct timespec *ts;
2842 int error, setbirthtime;
2846 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2848 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2849 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2851 if (numtimes < 3 && VOP_GETATTR(vp, &vattr, td->td_ucred, td) == 0 &&
2852 timespeccmp(&ts[1], &vattr.va_birthtime, < ))
2855 vattr.va_atime = ts[0];
2856 vattr.va_mtime = ts[1];
2858 vattr.va_birthtime = ts[1];
2860 vattr.va_birthtime = ts[2];
2862 vattr.va_vaflags |= VA_UTIMES_NULL;
2864 error = mac_check_vnode_setutimes(td->td_ucred, vp, vattr.va_atime,
2868 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2869 VOP_UNLOCK(vp, 0, td);
2870 vn_finished_write(mp);
2875 * Set the access and modification times of a file.
2877 #ifndef _SYS_SYSPROTO_H_
2878 struct utimes_args {
2880 struct timeval *tptr;
2886 register struct utimes_args /* {
2888 struct timeval *tptr;
2892 return (kern_utimes(td, uap->path, UIO_USERSPACE, uap->tptr,
2897 kern_utimes(struct thread *td, char *path, enum uio_seg pathseg,
2898 struct timeval *tptr, enum uio_seg tptrseg)
2900 struct timespec ts[2];
2902 struct nameidata nd;
2905 if ((error = getutimes(tptr, tptrseg, ts)) != 0)
2907 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td);
2908 if ((error = namei(&nd)) != 0)
2910 vfslocked = NDHASGIANT(&nd);
2911 NDFREE(&nd, NDF_ONLY_PNBUF);
2912 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL);
2914 VFS_UNLOCK_GIANT(vfslocked);
2919 * Set the access and modification times of a file.
2921 #ifndef _SYS_SYSPROTO_H_
2922 struct lutimes_args {
2924 struct timeval *tptr;
2930 register struct lutimes_args /* {
2932 struct timeval *tptr;
2936 return (kern_lutimes(td, uap->path, UIO_USERSPACE, uap->tptr,
2941 kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg,
2942 struct timeval *tptr, enum uio_seg tptrseg)
2944 struct timespec ts[2];
2946 struct nameidata nd;
2949 if ((error = getutimes(tptr, tptrseg, ts)) != 0)
2951 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td);
2952 if ((error = namei(&nd)) != 0)
2954 vfslocked = NDHASGIANT(&nd);
2955 NDFREE(&nd, NDF_ONLY_PNBUF);
2956 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL);
2958 VFS_UNLOCK_GIANT(vfslocked);
2963 * Set the access and modification times of a file.
2965 #ifndef _SYS_SYSPROTO_H_
2966 struct futimes_args {
2968 struct timeval *tptr;
2974 register struct futimes_args /* {
2976 struct timeval *tptr;
2980 return (kern_futimes(td, uap->fd, uap->tptr, UIO_USERSPACE));
2984 kern_futimes(struct thread *td, int fd, struct timeval *tptr,
2985 enum uio_seg tptrseg)
2987 struct timespec ts[2];
2993 if ((error = getutimes(tptr, tptrseg, ts)) != 0)
2995 if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0)
2997 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2999 vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY, td);
3000 AUDIT_ARG(vnode, fp->f_vnode, ARG_VNODE1);
3001 VOP_UNLOCK(fp->f_vnode, 0, td);
3003 error = setutimes(td, fp->f_vnode, ts, 2, tptr == NULL);
3004 VFS_UNLOCK_GIANT(vfslocked);
3010 * Truncate a file given its path name.
3012 #ifndef _SYS_SYSPROTO_H_
3013 struct truncate_args {
3022 register struct truncate_args /* {
3029 return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length));
3033 kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length)
3039 struct nameidata nd;
3044 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td);
3045 if ((error = namei(&nd)) != 0)
3047 vfslocked = NDHASGIANT(&nd);
3049 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
3051 VFS_UNLOCK_GIANT(vfslocked);
3054 NDFREE(&nd, NDF_ONLY_PNBUF);
3055 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3056 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3057 if (vp->v_type == VDIR)
3060 else if ((error = mac_check_vnode_write(td->td_ucred, NOCRED, vp))) {
3063 else if ((error = vn_writechk(vp)) == 0 &&
3064 (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) {
3066 vattr.va_size = length;
3067 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
3070 vn_finished_write(mp);
3071 VFS_UNLOCK_GIANT(vfslocked);
3076 * Truncate a file given a file descriptor.
3078 #ifndef _SYS_SYSPROTO_H_
3079 struct ftruncate_args {
3088 register struct ftruncate_args /* {
3101 AUDIT_ARG(fd, uap->fd);
3102 if (uap->length < 0)
3104 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3106 if ((fp->f_flag & FWRITE) == 0) {
3111 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
3112 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
3114 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3115 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3116 AUDIT_ARG(vnode, vp, ARG_VNODE1);
3117 if (vp->v_type == VDIR)
3120 else if ((error = mac_check_vnode_write(td->td_ucred, fp->f_cred,
3124 else if ((error = vn_writechk(vp)) == 0) {
3126 vattr.va_size = uap->length;
3127 error = VOP_SETATTR(vp, &vattr, fp->f_cred, td);
3129 VOP_UNLOCK(vp, 0, td);
3130 vn_finished_write(mp);
3132 VFS_UNLOCK_GIANT(vfslocked);
3137 #if defined(COMPAT_43)
3139 * Truncate a file given its path name.
3141 #ifndef _SYS_SYSPROTO_H_
3142 struct otruncate_args {
3150 register struct otruncate_args /* {
3155 struct truncate_args /* {
3161 nuap.path = uap->path;
3162 nuap.length = uap->length;
3163 return (truncate(td, &nuap));
3167 * Truncate a file given a file descriptor.
3169 #ifndef _SYS_SYSPROTO_H_
3170 struct oftruncate_args {
3178 register struct oftruncate_args /* {
3183 struct ftruncate_args /* {
3190 nuap.length = uap->length;
3191 return (ftruncate(td, &nuap));
3193 #endif /* COMPAT_43 */
3196 * Sync an open file.
3198 #ifndef _SYS_SYSPROTO_H_
3206 struct fsync_args /* {
3216 AUDIT_ARG(fd, uap->fd);
3217 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3220 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
3221 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
3223 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3224 AUDIT_ARG(vnode, vp, ARG_VNODE1);
3225 if (vp->v_object != NULL) {
3226 VM_OBJECT_LOCK(vp->v_object);
3227 vm_object_page_clean(vp->v_object, 0, 0, 0);
3228 VM_OBJECT_UNLOCK(vp->v_object);
3230 error = VOP_FSYNC(vp, MNT_WAIT, td);
3232 VOP_UNLOCK(vp, 0, td);
3233 vn_finished_write(mp);
3235 VFS_UNLOCK_GIANT(vfslocked);
3241 * Rename files. Source and destination must either both be directories,
3242 * or both not be directories. If target is a directory, it must be empty.
3244 #ifndef _SYS_SYSPROTO_H_
3245 struct rename_args {
3253 register struct rename_args /* {
3259 return (kern_rename(td, uap->from, uap->to, UIO_USERSPACE));
3263 kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg)
3265 struct mount *mp = NULL;
3266 struct vnode *tvp, *fvp, *tdvp;
3267 struct nameidata fromnd, tond;
3274 NDINIT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE |
3275 AUDITVNODE1, pathseg, from, td);
3277 NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE |
3278 AUDITVNODE1, pathseg, from, td);
3280 if ((error = namei(&fromnd)) != 0)
3282 fvfslocked = NDHASGIANT(&fromnd);
3285 error = mac_check_vnode_rename_from(td->td_ucred, fromnd.ni_dvp,
3286 fromnd.ni_vp, &fromnd.ni_cnd);
3287 VOP_UNLOCK(fromnd.ni_dvp, 0, td);
3288 VOP_UNLOCK(fromnd.ni_vp, 0, td);
3292 error = vn_start_write(fvp, &mp, V_WAIT | PCATCH);
3294 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3295 vrele(fromnd.ni_dvp);
3299 NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART |
3300 MPSAFE | AUDITVNODE2, pathseg, to, td);
3301 if (fromnd.ni_vp->v_type == VDIR)
3302 tond.ni_cnd.cn_flags |= WILLBEDIR;
3303 if ((error = namei(&tond)) != 0) {
3304 /* Translate error code for rename("dir1", "dir2/."). */
3305 if (error == EISDIR && fvp->v_type == VDIR)
3307 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3308 vrele(fromnd.ni_dvp);
3310 vn_finished_write(mp);
3313 tvfslocked = NDHASGIANT(&tond);
3317 if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
3320 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
3328 * If the source is the same as the destination (that is, if they
3329 * are links to the same vnode), then there is nothing to do.
3335 error = mac_check_vnode_rename_to(td->td_ucred, tdvp,
3336 tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd);
3340 VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE);
3341 if (fromnd.ni_dvp != tdvp) {
3342 VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3345 VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE);
3347 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
3348 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
3349 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3350 NDFREE(&tond, NDF_ONLY_PNBUF);
3352 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3353 NDFREE(&tond, NDF_ONLY_PNBUF);
3360 vrele(fromnd.ni_dvp);
3363 vrele(tond.ni_startdir);
3364 vn_finished_write(mp);
3366 if (fromnd.ni_startdir)
3367 vrele(fromnd.ni_startdir);
3368 VFS_UNLOCK_GIANT(fvfslocked);
3369 VFS_UNLOCK_GIANT(tvfslocked);
3376 * Make a directory file.
3378 #ifndef _SYS_SYSPROTO_H_
3387 register struct mkdir_args /* {
3393 return (kern_mkdir(td, uap->path, UIO_USERSPACE, uap->mode));
3397 kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode)
3403 struct nameidata nd;
3406 AUDIT_ARG(mode, mode);
3409 NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1,
3411 nd.ni_cnd.cn_flags |= WILLBEDIR;
3412 if ((error = namei(&nd)) != 0)
3414 vfslocked = NDHASGIANT(&nd);
3417 NDFREE(&nd, NDF_ONLY_PNBUF);
3419 * XXX namei called with LOCKPARENT but not LOCKLEAF has
3420 * the strange behaviour of leaving the vnode unlocked
3421 * if the target is the same vnode as the parent.
3423 if (vp == nd.ni_dvp)
3428 VFS_UNLOCK_GIANT(vfslocked);
3431 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
3432 NDFREE(&nd, NDF_ONLY_PNBUF);
3434 VFS_UNLOCK_GIANT(vfslocked);
3435 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
3440 vattr.va_type = VDIR;
3441 FILEDESC_LOCK_FAST(td->td_proc->p_fd);
3442 vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask;
3443 FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
3445 error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
3450 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3451 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
3455 NDFREE(&nd, NDF_ONLY_PNBUF);
3459 vn_finished_write(mp);
3460 VFS_UNLOCK_GIANT(vfslocked);
3465 * Remove a directory file.
3467 #ifndef _SYS_SYSPROTO_H_
3475 struct rmdir_args /* {
3480 return (kern_rmdir(td, uap->path, UIO_USERSPACE));
3484 kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg)
3489 struct nameidata nd;
3494 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE | AUDITVNODE1,
3496 if ((error = namei(&nd)) != 0)
3498 vfslocked = NDHASGIANT(&nd);
3500 if (vp->v_type != VDIR) {
3505 * No rmdir "." please.
3507 if (nd.ni_dvp == vp) {
3512 * The root of a mounted filesystem cannot be deleted.
3514 if (vp->v_vflag & VV_ROOT) {
3519 error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp,
3524 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
3525 NDFREE(&nd, NDF_ONLY_PNBUF);
3527 if (nd.ni_dvp == vp)
3531 VFS_UNLOCK_GIANT(vfslocked);
3532 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
3536 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3537 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3538 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
3539 vn_finished_write(mp);
3541 NDFREE(&nd, NDF_ONLY_PNBUF);
3543 if (nd.ni_dvp == vp)
3547 VFS_UNLOCK_GIANT(vfslocked);
3553 * Read a block of directory entries in a filesystem independent format.
3555 #ifndef _SYS_SYSPROTO_H_
3556 struct ogetdirentries_args {
3564 ogetdirentries(td, uap)
3566 register struct ogetdirentries_args /* {
3575 struct uio auio, kuio;
3576 struct iovec aiov, kiov;
3577 struct dirent *dp, *edp;
3579 int error, eofflag, readcnt;
3582 /* XXX arbitrary sanity limit on `count'. */
3583 if (uap->count > 64 * 1024)
3585 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3587 if ((fp->f_flag & FREAD) == 0) {
3593 if (vp->v_type != VDIR) {
3597 aiov.iov_base = uap->buf;
3598 aiov.iov_len = uap->count;
3599 auio.uio_iov = &aiov;
3600 auio.uio_iovcnt = 1;
3601 auio.uio_rw = UIO_READ;
3602 auio.uio_segflg = UIO_USERSPACE;
3604 auio.uio_resid = uap->count;
3605 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3606 loff = auio.uio_offset = fp->f_offset;
3608 error = mac_check_vnode_readdir(td->td_ucred, vp);
3610 VOP_UNLOCK(vp, 0, td);
3615 # if (BYTE_ORDER != LITTLE_ENDIAN)
3616 if (vp->v_mount->mnt_maxsymlinklen <= 0) {
3617 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
3619 fp->f_offset = auio.uio_offset;
3624 kuio.uio_iov = &kiov;
3625 kuio.uio_segflg = UIO_SYSSPACE;
3626 kiov.iov_len = uap->count;
3627 MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK);
3628 kiov.iov_base = dirbuf;
3629 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag,
3631 fp->f_offset = kuio.uio_offset;
3633 readcnt = uap->count - kuio.uio_resid;
3634 edp = (struct dirent *)&dirbuf[readcnt];
3635 for (dp = (struct dirent *)dirbuf; dp < edp; ) {
3636 # if (BYTE_ORDER == LITTLE_ENDIAN)
3638 * The expected low byte of
3639 * dp->d_namlen is our dp->d_type.
3640 * The high MBZ byte of dp->d_namlen
3641 * is our dp->d_namlen.
3643 dp->d_type = dp->d_namlen;
3647 * The dp->d_type is the high byte
3648 * of the expected dp->d_namlen,
3649 * so must be zero'ed.
3653 if (dp->d_reclen > 0) {
3654 dp = (struct dirent *)
3655 ((char *)dp + dp->d_reclen);
3662 error = uiomove(dirbuf, readcnt, &auio);
3664 FREE(dirbuf, M_TEMP);
3666 VOP_UNLOCK(vp, 0, td);
3671 if (uap->count == auio.uio_resid) {
3672 if (union_dircheckp) {
3673 error = union_dircheckp(td, &vp, fp);
3682 * XXX We could delay dropping the lock above but
3683 * union_dircheckp complicates things.
3685 vn_lock(vp, LK_EXCLUSIVE|LK_RETRY, td);
3686 if ((vp->v_vflag & VV_ROOT) &&
3687 (vp->v_mount->mnt_flag & MNT_UNION)) {
3688 struct vnode *tvp = vp;
3689 vp = vp->v_mount->mnt_vnodecovered;
3697 VOP_UNLOCK(vp, 0, td);
3699 error = copyout(&loff, uap->basep, sizeof(long));
3701 td->td_retval[0] = uap->count - auio.uio_resid;
3704 #endif /* COMPAT_43 */
3707 * Read a block of directory entries in a filesystem independent format.
3709 #ifndef _SYS_SYSPROTO_H_
3710 struct getdirentries_args {
3718 getdirentries(td, uap)
3720 register struct getdirentries_args /* {
3735 AUDIT_ARG(fd, uap->fd);
3736 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3738 if ((fp->f_flag & FREAD) == 0) {
3744 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
3745 if (vp->v_type != VDIR) {
3749 aiov.iov_base = uap->buf;
3750 aiov.iov_len = uap->count;
3751 auio.uio_iov = &aiov;
3752 auio.uio_iovcnt = 1;
3753 auio.uio_rw = UIO_READ;
3754 auio.uio_segflg = UIO_USERSPACE;
3756 auio.uio_resid = uap->count;
3757 /* vn_lock(vp, LK_SHARED | LK_RETRY, td); */
3758 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3759 AUDIT_ARG(vnode, vp, ARG_VNODE1);
3760 loff = auio.uio_offset = fp->f_offset;
3762 error = mac_check_vnode_readdir(td->td_ucred, vp);
3765 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL,
3767 fp->f_offset = auio.uio_offset;
3768 VOP_UNLOCK(vp, 0, td);
3771 if (uap->count == auio.uio_resid) {
3772 if (union_dircheckp) {
3773 error = union_dircheckp(td, &vp, fp);
3775 VFS_UNLOCK_GIANT(vfslocked);
3782 * XXX We could delay dropping the lock above but
3783 * union_dircheckp complicates things.
3785 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3786 if ((vp->v_vflag & VV_ROOT) &&
3787 (vp->v_mount->mnt_flag & MNT_UNION)) {
3788 struct vnode *tvp = vp;
3789 vp = vp->v_mount->mnt_vnodecovered;
3795 VFS_UNLOCK_GIANT(vfslocked);
3798 VOP_UNLOCK(vp, 0, td);
3800 if (uap->basep != NULL) {
3801 error = copyout(&loff, uap->basep, sizeof(long));
3803 td->td_retval[0] = uap->count - auio.uio_resid;
3805 VFS_UNLOCK_GIANT(vfslocked);
3809 #ifndef _SYS_SYSPROTO_H_
3810 struct getdents_args {
3819 register struct getdents_args /* {
3825 struct getdirentries_args ap;
3828 ap.count = uap->count;
3830 return (getdirentries(td, &ap));
3834 * Set the mode mask for creation of filesystem nodes.
3838 #ifndef _SYS_SYSPROTO_H_
3846 struct umask_args /* {
3850 register struct filedesc *fdp;
3852 FILEDESC_LOCK_FAST(td->td_proc->p_fd);
3853 fdp = td->td_proc->p_fd;
3854 td->td_retval[0] = fdp->fd_cmask;
3855 fdp->fd_cmask = uap->newmask & ALLPERMS;
3856 FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
3861 * Void all references to file by ripping underlying filesystem
3864 #ifndef _SYS_SYSPROTO_H_
3865 struct revoke_args {
3872 register struct revoke_args /* {
3879 struct nameidata nd;
3882 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
3883 UIO_USERSPACE, uap->path, td);
3884 if ((error = namei(&nd)) != 0)
3886 vfslocked = NDHASGIANT(&nd);
3888 NDFREE(&nd, NDF_ONLY_PNBUF);
3889 if (vp->v_type != VCHR) {
3894 error = mac_check_vnode_revoke(td->td_ucred, vp);
3898 error = VOP_GETATTR(vp, &vattr, td->td_ucred, td);
3901 if (td->td_ucred->cr_uid != vattr.va_uid) {
3902 error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
3907 VOP_REVOKE(vp, REVOKEALL);
3910 VFS_UNLOCK_GIANT(vfslocked);
3915 * Convert a user file descriptor to a kernel file entry.
3916 * A reference on the file entry is held upon returning.
3919 getvnode(fdp, fd, fpp)
3920 struct filedesc *fdp;
3932 if ((u_int)fd >= fdp->fd_nfiles ||
3933 (fp = fdp->fd_ofiles[fd]) == NULL)
3935 else if (fp->f_vnode == NULL) {
3942 FILEDESC_UNLOCK(fdp);
3949 * Get (NFS) file handle
3951 #ifndef _SYS_SYSPROTO_H_
3952 struct lgetfh_args {
3960 register struct lgetfh_args *uap;
3962 struct nameidata nd;
3964 register struct vnode *vp;
3971 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
3972 UIO_USERSPACE, uap->fname, td);
3976 vfslocked = NDHASGIANT(&nd);
3977 NDFREE(&nd, NDF_ONLY_PNBUF);
3979 bzero(&fh, sizeof(fh));
3980 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
3981 error = VFS_VPTOFH(vp, &fh.fh_fid);
3983 VFS_UNLOCK_GIANT(vfslocked);
3986 error = copyout(&fh, uap->fhp, sizeof (fh));
3990 #ifndef _SYS_SYSPROTO_H_
3999 register struct getfh_args *uap;
4001 struct nameidata nd;
4003 register struct vnode *vp;
4010 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
4011 UIO_USERSPACE, uap->fname, td);
4015 vfslocked = NDHASGIANT(&nd);
4016 NDFREE(&nd, NDF_ONLY_PNBUF);
4018 bzero(&fh, sizeof(fh));
4019 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
4020 error = VFS_VPTOFH(vp, &fh.fh_fid);
4022 VFS_UNLOCK_GIANT(vfslocked);
4025 error = copyout(&fh, uap->fhp, sizeof (fh));
4030 * syscall for the rpc.lockd to use to translate a NFS file handle into
4031 * an open descriptor.
4033 * warning: do not remove the suser() call or this becomes one giant
4038 #ifndef _SYS_SYSPROTO_H_
4039 struct fhopen_args {
4040 const struct fhandle *u_fhp;
4047 struct fhopen_args /* {
4048 const struct fhandle *u_fhp;
4052 struct proc *p = td->td_proc;
4057 struct vattr *vap = &vat;
4060 register struct filedesc *fdp = p->p_fd;
4061 int fmode, mode, error, type;
4068 fmode = FFLAGS(uap->flags);
4069 /* why not allow a non-read/write open for our lockd? */
4070 if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT))
4072 error = copyin(uap->u_fhp, &fhp, sizeof(fhp));
4075 /* find the mount point */
4077 mp = vfs_getvfs(&fhp.fh_fsid);
4082 /* now give me my vnode, it gets returned to me locked */
4083 error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp);
4087 * from now on we have to make sure not
4088 * to forget about the vnode
4089 * any error that causes an abort must vput(vp)
4090 * just set error = err and 'goto bad;'.
4096 if (vp->v_type == VLNK) {
4100 if (vp->v_type == VSOCK) {
4105 if (fmode & (FWRITE | O_TRUNC)) {
4106 if (vp->v_type == VDIR) {
4110 error = vn_writechk(vp);
4117 if (fmode & O_APPEND)
4120 error = mac_check_vnode_open(td->td_ucred, vp, mode);
4125 error = VOP_ACCESS(vp, mode, td->td_ucred, td);
4129 if (fmode & O_TRUNC) {
4130 VOP_UNLOCK(vp, 0, td); /* XXX */
4131 if ((error = vn_start_write(NULL, &mp, V_WAIT | PCATCH)) != 0) {
4135 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4136 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); /* XXX */
4139 * We don't yet have fp->f_cred, so use td->td_ucred, which
4142 error = mac_check_vnode_write(td->td_ucred, td->td_ucred, vp);
4147 error = VOP_SETATTR(vp, vap, td->td_ucred, td);
4151 vn_finished_write(mp);
4155 error = VOP_OPEN(vp, fmode, td->td_ucred, td, -1);
4163 * end of vn_open code
4166 if ((error = falloc(td, &nfp, &indx)) != 0) {
4171 /* An extra reference on `nfp' has been held for us by falloc(). */
4176 nfp->f_flag = fmode & FMASK;
4177 nfp->f_ops = &vnops;
4178 nfp->f_type = DTYPE_VNODE;
4179 if (fmode & (O_EXLOCK | O_SHLOCK)) {
4180 lf.l_whence = SEEK_SET;
4183 if (fmode & O_EXLOCK)
4184 lf.l_type = F_WRLCK;
4186 lf.l_type = F_RDLCK;
4188 if ((fmode & FNONBLOCK) == 0)
4190 VOP_UNLOCK(vp, 0, td);
4191 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf,
4194 * The lock request failed. Normally close the
4195 * descriptor but handle the case where someone might
4196 * have dup()d or close()d it when we weren't looking.
4198 fdclose(fdp, fp, indx, td);
4201 * release our private reference
4206 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4207 fp->f_flag |= FHASLOCK;
4210 VOP_UNLOCK(vp, 0, td);
4213 td->td_retval[0] = indx;
4224 * Stat an (NFS) file handle.
4228 #ifndef _SYS_SYSPROTO_H_
4229 struct fhstat_args {
4230 struct fhandle *u_fhp;
4237 register struct fhstat_args /* {
4238 struct fhandle *u_fhp;
4251 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
4255 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) {
4259 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) {
4263 error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
4268 error = copyout(&sb, uap->sb, sizeof(sb));
4273 * Implement fstatfs() for (NFS) file handles.
4277 #ifndef _SYS_SYSPROTO_H_
4278 struct fhstatfs_args {
4279 struct fhandle *u_fhp;
4286 struct fhstatfs_args /* {
4287 struct fhandle *u_fhp;
4295 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
4298 error = kern_fhstatfs(td, fh, &sf);
4301 return (copyout(&sf, uap->buf, sizeof(sf)));
4305 kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf)
4316 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) {
4320 error = VFS_FHTOVP(mp, &fh.fh_fid, &vp);
4331 error = prison_canseemount(td->td_ucred, mp);
4337 error = mac_check_mount_stat(td->td_ucred, mp);
4345 * Set these in case the underlying filesystem fails to do so.
4348 sp->f_version = STATFS_VERSION;
4349 sp->f_namemax = NAME_MAX;
4350 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
4351 error = VFS_STATFS(mp, sp, td);
4361 * Syscall to push extended attribute configuration information into the
4362 * VFS. Accepts a path, which it converts to a mountpoint, as well as
4363 * a command (int cmd), and attribute name and misc data. For now, the
4364 * attribute name is left in userspace for consumption by the VFS_op.
4365 * It will probably be changed to be copied into sysspace by the
4366 * syscall in the future, once issues with various consumers of the
4367 * attribute code have raised their hands.
4369 * Currently this is used only by UFS Extended Attributes.
4374 struct extattrctl_args /* {
4377 const char *filename;
4379 const char *attrname;
4382 struct vnode *filename_vp;
4383 struct nameidata nd;
4384 struct mount *mp, *mp_writable;
4385 char attrname[EXTATTR_MAXNAMELEN];
4386 int vfslocked, fnvfslocked, error;
4389 * uap->attrname is not always defined. We check again later when we
4390 * invoke the VFS call so as to pass in NULL there if needed.
4392 if (uap->attrname != NULL) {
4393 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN,
4399 vfslocked = fnvfslocked = 0;
4401 * uap->filename is not always defined. If it is, grab a vnode lock,
4402 * which VFS_EXTATTRCTL() will later release.
4405 if (uap->filename != NULL) {
4406 NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | LOCKLEAF |
4407 AUDITVNODE2, UIO_USERSPACE, uap->filename, td);
4411 fnvfslocked = NDHASGIANT(&nd);
4412 filename_vp = nd.ni_vp;
4413 NDFREE(&nd, NDF_NO_VP_RELE | NDF_NO_VP_UNLOCK);
4416 /* uap->path is always defined. */
4417 NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | AUDITVNODE1, UIO_USERSPACE,
4421 if (filename_vp != NULL)
4425 vfslocked = NDHASGIANT(&nd);
4426 mp = nd.ni_vp->v_mount;
4427 error = vn_start_write(nd.ni_vp, &mp_writable, V_WAIT | PCATCH);
4430 if (filename_vp != NULL)
4435 error = VFS_EXTATTRCTL(mp, uap->cmd, filename_vp, uap->attrnamespace,
4436 uap->attrname != NULL ? attrname : NULL, td);
4438 vn_finished_write(mp_writable);
4440 * VFS_EXTATTRCTL will have unlocked, but not de-ref'd,
4441 * filename_vp, so vrele it if it is defined.
4443 if (filename_vp != NULL)
4446 VFS_UNLOCK_GIANT(fnvfslocked);
4447 VFS_UNLOCK_GIANT(vfslocked);
4452 * Set a named extended attribute on a file or directory
4454 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4455 * kernelspace string pointer "attrname", userspace buffer
4456 * pointer "data", buffer length "nbytes", thread "td".
4457 * Returns: 0 on success, an error number otherwise
4459 * References: vp must be a valid reference for the duration of the call
4462 extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4463 void *data, size_t nbytes, struct thread *td)
4471 VFS_ASSERT_GIANT(vp->v_mount);
4472 error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
4475 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4476 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4478 aiov.iov_base = data;
4479 aiov.iov_len = nbytes;
4480 auio.uio_iov = &aiov;
4481 auio.uio_iovcnt = 1;
4482 auio.uio_offset = 0;
4483 if (nbytes > INT_MAX) {
4487 auio.uio_resid = nbytes;
4488 auio.uio_rw = UIO_WRITE;
4489 auio.uio_segflg = UIO_USERSPACE;
4494 error = mac_check_vnode_setextattr(td->td_ucred, vp, attrnamespace,
4500 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio,
4502 cnt -= auio.uio_resid;
4503 td->td_retval[0] = cnt;
4506 VOP_UNLOCK(vp, 0, td);
4507 vn_finished_write(mp);
4512 extattr_set_fd(td, uap)
4514 struct extattr_set_fd_args /* {
4517 const char *attrname;
4523 char attrname[EXTATTR_MAXNAMELEN];
4524 int vfslocked, error;
4526 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4530 error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
4534 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
4535 error = extattr_set_vp(fp->f_vnode, uap->attrnamespace,
4536 attrname, uap->data, uap->nbytes, td);
4538 VFS_UNLOCK_GIANT(vfslocked);
4544 extattr_set_file(td, uap)
4546 struct extattr_set_file_args /* {
4549 const char *attrname;
4554 struct nameidata nd;
4555 char attrname[EXTATTR_MAXNAMELEN];
4556 int vfslocked, error;
4558 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4562 NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | AUDITVNODE1, UIO_USERSPACE,
4567 NDFREE(&nd, NDF_ONLY_PNBUF);
4569 vfslocked = NDHASGIANT(&nd);
4570 error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname,
4571 uap->data, uap->nbytes, td);
4574 VFS_UNLOCK_GIANT(vfslocked);
4579 extattr_set_link(td, uap)
4581 struct extattr_set_link_args /* {
4584 const char *attrname;
4589 struct nameidata nd;
4590 char attrname[EXTATTR_MAXNAMELEN];
4591 int vfslocked, error;
4593 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4597 NDINIT(&nd, LOOKUP, MPSAFE | NOFOLLOW | AUDITVNODE1, UIO_USERSPACE,
4602 NDFREE(&nd, NDF_ONLY_PNBUF);
4604 vfslocked = NDHASGIANT(&nd);
4605 error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname,
4606 uap->data, uap->nbytes, td);
4609 VFS_UNLOCK_GIANT(vfslocked);
4614 * Get a named extended attribute on a file or directory
4616 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4617 * kernelspace string pointer "attrname", userspace buffer
4618 * pointer "data", buffer length "nbytes", thread "td".
4619 * Returns: 0 on success, an error number otherwise
4621 * References: vp must be a valid reference for the duration of the call
4624 extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4625 void *data, size_t nbytes, struct thread *td)
4627 struct uio auio, *auiop;
4630 size_t size, *sizep;
4633 VFS_ASSERT_GIANT(vp->v_mount);
4634 VOP_LEASE(vp, td, td->td_ucred, LEASE_READ);
4635 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4638 * Slightly unusual semantics: if the user provides a NULL data
4639 * pointer, they don't want to receive the data, just the
4640 * maximum read length.
4646 aiov.iov_base = data;
4647 aiov.iov_len = nbytes;
4648 auio.uio_iov = &aiov;
4649 auio.uio_iovcnt = 1;
4650 auio.uio_offset = 0;
4651 if (nbytes > INT_MAX) {
4655 auio.uio_resid = nbytes;
4656 auio.uio_rw = UIO_READ;
4657 auio.uio_segflg = UIO_USERSPACE;
4665 error = mac_check_vnode_getextattr(td->td_ucred, vp, attrnamespace,
4671 error = VOP_GETEXTATTR(vp, attrnamespace, attrname, auiop, sizep,
4674 if (auiop != NULL) {
4675 cnt -= auio.uio_resid;
4676 td->td_retval[0] = cnt;
4678 td->td_retval[0] = size;
4681 VOP_UNLOCK(vp, 0, td);
4686 extattr_get_fd(td, uap)
4688 struct extattr_get_fd_args /* {
4691 const char *attrname;
4697 char attrname[EXTATTR_MAXNAMELEN];
4698 int vfslocked, error;
4700 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4704 error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
4708 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
4709 error = extattr_get_vp(fp->f_vnode, uap->attrnamespace,
4710 attrname, uap->data, uap->nbytes, td);
4713 VFS_UNLOCK_GIANT(vfslocked);
4718 extattr_get_file(td, uap)
4720 struct extattr_get_file_args /* {
4723 const char *attrname;
4728 struct nameidata nd;
4729 char attrname[EXTATTR_MAXNAMELEN];
4730 int vfslocked, error;
4732 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4736 NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | AUDITVNODE1, UIO_USERSPACE,
4741 NDFREE(&nd, NDF_ONLY_PNBUF);
4743 vfslocked = NDHASGIANT(&nd);
4744 error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname,
4745 uap->data, uap->nbytes, td);
4748 VFS_UNLOCK_GIANT(vfslocked);
4753 extattr_get_link(td, uap)
4755 struct extattr_get_link_args /* {
4758 const char *attrname;
4763 struct nameidata nd;
4764 char attrname[EXTATTR_MAXNAMELEN];
4765 int vfslocked, error;
4767 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4771 NDINIT(&nd, LOOKUP, MPSAFE | NOFOLLOW | AUDITVNODE1, UIO_USERSPACE,
4776 NDFREE(&nd, NDF_ONLY_PNBUF);
4778 vfslocked = NDHASGIANT(&nd);
4779 error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname,
4780 uap->data, uap->nbytes, td);
4783 VFS_UNLOCK_GIANT(vfslocked);
4788 * extattr_delete_vp(): Delete a named extended attribute on a file or
4791 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4792 * kernelspace string pointer "attrname", proc "p"
4793 * Returns: 0 on success, an error number otherwise
4795 * References: vp must be a valid reference for the duration of the call
4798 extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4804 VFS_ASSERT_GIANT(vp->v_mount);
4805 error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
4808 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4809 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4812 error = mac_check_vnode_deleteextattr(td->td_ucred, vp, attrnamespace,
4818 error = VOP_DELETEEXTATTR(vp, attrnamespace, attrname, td->td_ucred,
4820 if (error == EOPNOTSUPP)
4821 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL,
4826 VOP_UNLOCK(vp, 0, td);
4827 vn_finished_write(mp);
4832 extattr_delete_fd(td, uap)
4834 struct extattr_delete_fd_args /* {
4837 const char *attrname;
4841 char attrname[EXTATTR_MAXNAMELEN];
4842 int vfslocked, error;
4844 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4848 error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
4852 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
4853 error = extattr_delete_vp(fp->f_vnode, uap->attrnamespace,
4856 VFS_UNLOCK_GIANT(vfslocked);
4861 extattr_delete_file(td, uap)
4863 struct extattr_delete_file_args /* {
4866 const char *attrname;
4869 struct nameidata nd;
4870 char attrname[EXTATTR_MAXNAMELEN];
4871 int vfslocked, error;
4873 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4877 NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | AUDITVNODE1, UIO_USERSPACE,
4882 NDFREE(&nd, NDF_ONLY_PNBUF);
4884 vfslocked = NDHASGIANT(&nd);
4885 error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td);
4887 VFS_UNLOCK_GIANT(vfslocked);
4892 extattr_delete_link(td, uap)
4894 struct extattr_delete_link_args /* {
4897 const char *attrname;
4900 struct nameidata nd;
4901 char attrname[EXTATTR_MAXNAMELEN];
4902 int vfslocked, error;
4904 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4908 NDINIT(&nd, LOOKUP, MPSAFE | NOFOLLOW | AUDITVNODE1, UIO_USERSPACE,
4913 NDFREE(&nd, NDF_ONLY_PNBUF);
4915 vfslocked = NDHASGIANT(&nd);
4916 error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td);
4918 VFS_UNLOCK_GIANT(vfslocked);
4923 * Retrieve a list of extended attributes on a file or directory.
4925 * Arguments: unlocked vnode "vp", attribute namespace 'attrnamespace",
4926 * userspace buffer pointer "data", buffer length "nbytes",
4928 * Returns: 0 on success, an error number otherwise
4930 * References: vp must be a valid reference for the duration of the call
4933 extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
4934 size_t nbytes, struct thread *td)
4936 struct uio auio, *auiop;
4937 size_t size, *sizep;
4942 VFS_ASSERT_GIANT(vp->v_mount);
4943 VOP_LEASE(vp, td, td->td_ucred, LEASE_READ);
4944 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4950 aiov.iov_base = data;
4951 aiov.iov_len = nbytes;
4952 auio.uio_iov = &aiov;
4953 auio.uio_iovcnt = 1;
4954 auio.uio_offset = 0;
4955 if (nbytes > INT_MAX) {
4959 auio.uio_resid = nbytes;
4960 auio.uio_rw = UIO_READ;
4961 auio.uio_segflg = UIO_USERSPACE;
4969 error = mac_check_vnode_listextattr(td->td_ucred, vp, attrnamespace);
4974 error = VOP_LISTEXTATTR(vp, attrnamespace, auiop, sizep,
4977 if (auiop != NULL) {
4978 cnt -= auio.uio_resid;
4979 td->td_retval[0] = cnt;
4981 td->td_retval[0] = size;
4984 VOP_UNLOCK(vp, 0, td);
4990 extattr_list_fd(td, uap)
4992 struct extattr_list_fd_args /* {
5000 int vfslocked, error;
5002 error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
5006 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
5007 error = extattr_list_vp(fp->f_vnode, uap->attrnamespace, uap->data,
5011 VFS_UNLOCK_GIANT(vfslocked);
5016 extattr_list_file(td, uap)
5018 struct extattr_list_file_args /* {
5025 struct nameidata nd;
5026 int vfslocked, error;
5028 NDINIT(&nd, LOOKUP, MPSAFE | FOLLOW | AUDITVNODE1, UIO_USERSPACE,
5033 NDFREE(&nd, NDF_ONLY_PNBUF);
5035 vfslocked = NDHASGIANT(&nd);
5036 error = extattr_list_vp(nd.ni_vp, uap->attrnamespace, uap->data,
5040 VFS_UNLOCK_GIANT(vfslocked);
5045 extattr_list_link(td, uap)
5047 struct extattr_list_link_args /* {
5054 struct nameidata nd;
5055 int vfslocked, error;
5057 NDINIT(&nd, LOOKUP, MPSAFE | NOFOLLOW | AUDITVNODE1, UIO_USERSPACE,
5062 NDFREE(&nd, NDF_ONLY_PNBUF);
5064 vfslocked = NDHASGIANT(&nd);
5065 error = extattr_list_vp(nd.ni_vp, uap->attrnamespace, uap->data,
5069 VFS_UNLOCK_GIANT(vfslocked);