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>
74 #include <vm/vm_object.h>
75 #include <vm/vm_page.h>
78 static int chroot_refuse_vdir_fds(struct filedesc *fdp);
79 static int getutimes(const struct timeval *, enum uio_seg, struct timespec *);
80 static int setfown(struct thread *td, struct vnode *, uid_t, gid_t);
81 static int setfmode(struct thread *td, struct vnode *, int);
82 static int setfflags(struct thread *td, struct vnode *, int);
83 static int setutimes(struct thread *td, struct vnode *,
84 const struct timespec *, int, int);
85 static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred,
88 static int extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
89 size_t nbytes, struct thread *td);
91 int (*union_dircheckp)(struct thread *td, struct vnode **, struct file *);
94 * The module initialization routine for POSIX asynchronous I/O will
95 * set this to the version of AIO that it implements. (Zero means
96 * that it is not implemented.) This value is used here by pathconf()
97 * and in kern_descrip.c by fpathconf().
102 * Sync each mounted filesystem.
104 #ifndef _SYS_SYSPROTO_H_
111 static int syncprt = 0;
112 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, "");
119 struct sync_args *uap;
121 struct mount *mp, *nmp;
125 mtx_lock(&mountlist_mtx);
126 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
127 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
128 nmp = TAILQ_NEXT(mp, mnt_list);
131 if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
132 vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
133 asyncflag = mp->mnt_flag & MNT_ASYNC;
134 mp->mnt_flag &= ~MNT_ASYNC;
135 vfs_msync(mp, MNT_NOWAIT);
136 VFS_SYNC(mp, MNT_NOWAIT, td);
137 mp->mnt_flag |= asyncflag;
138 vn_finished_write(mp);
140 mtx_lock(&mountlist_mtx);
141 nmp = TAILQ_NEXT(mp, mnt_list);
144 mtx_unlock(&mountlist_mtx);
147 * XXX don't call vfs_bufstats() yet because that routine
148 * was not imported in the Lite2 merge.
153 #endif /* DIAGNOSTIC */
159 /* XXX PRISON: could be per prison flag */
160 static int prison_quotas;
162 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, "");
166 * Change filesystem quotas.
170 #ifndef _SYS_SYSPROTO_H_
171 struct quotactl_args {
181 register struct quotactl_args /* {
188 struct mount *mp, *vmp;
192 if (jailed(td->td_ucred) && !prison_quotas)
195 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
196 if ((error = namei(&nd)) != 0) {
200 NDFREE(&nd, NDF_ONLY_PNBUF);
201 error = vn_start_write(nd.ni_vp, &vmp, V_WAIT | PCATCH);
202 mp = nd.ni_vp->v_mount;
208 error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg, td);
209 vn_finished_write(vmp);
215 * Get filesystem statistics.
217 #ifndef _SYS_SYSPROTO_H_
226 register struct statfs_args /* {
234 error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
236 error = copyout(&sf, uap->buf, sizeof(sf));
241 kern_statfs(struct thread *td, char *path, enum uio_seg pathseg,
245 struct statfs *sp, sb;
250 NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td);
256 mp = nd.ni_vp->v_mount;
258 NDFREE(&nd, NDF_ONLY_PNBUF);
261 error = mac_check_mount_stat(td->td_ucred, mp);
268 * Set these in case the underlying filesystem fails to do so.
270 sp->f_version = STATFS_VERSION;
271 sp->f_namemax = NAME_MAX;
272 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
273 error = VFS_STATFS(mp, sp, td);
278 bcopy(sp, &sb, sizeof(sb));
279 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
287 * Get filesystem statistics.
289 #ifndef _SYS_SYSPROTO_H_
290 struct fstatfs_args {
298 register struct fstatfs_args /* {
306 error = kern_fstatfs(td, uap->fd, &sf);
308 error = copyout(&sf, uap->buf, sizeof(sf));
313 kern_fstatfs(struct thread *td, int fd, struct statfs *buf)
317 struct statfs *sp, sb;
320 error = getvnode(td->td_proc->p_fd, fd, &fp);
324 mp = fp->f_vnode->v_mount;
331 error = mac_check_mount_stat(td->td_ucred, mp);
339 * Set these in case the underlying filesystem fails to do so.
341 sp->f_version = STATFS_VERSION;
342 sp->f_namemax = NAME_MAX;
343 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
344 error = VFS_STATFS(mp, sp, td);
349 bcopy(sp, &sb, sizeof(sb));
350 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
358 * Get statistics on all filesystems.
360 #ifndef _SYS_SYSPROTO_H_
361 struct getfsstat_args {
370 register struct getfsstat_args /* {
377 return (kern_getfsstat(td, uap->buf, uap->bufsize, UIO_USERSPACE,
382 kern_getfsstat(struct thread *td, struct statfs *buf, size_t bufsize,
383 enum uio_seg bufseg, int flags)
385 struct mount *mp, *nmp;
386 struct statfs *sfsp, *sp, sb;
387 size_t count, maxcount;
390 maxcount = bufsize / sizeof(struct statfs);
394 mtx_lock(&mountlist_mtx);
395 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
396 if (!prison_check_mount(td->td_ucred, mp)) {
397 nmp = TAILQ_NEXT(mp, mnt_list);
401 if (mac_check_mount_stat(td->td_ucred, mp) != 0) {
402 nmp = TAILQ_NEXT(mp, mnt_list);
406 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
407 nmp = TAILQ_NEXT(mp, mnt_list);
410 if (sfsp && count < maxcount) {
413 * Set these in case the underlying filesystem
416 sp->f_version = STATFS_VERSION;
417 sp->f_namemax = NAME_MAX;
418 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
420 * If MNT_NOWAIT or MNT_LAZY is specified, do not
421 * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
422 * overrides MNT_WAIT.
424 if (((flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
425 (flags & MNT_WAIT)) &&
426 (error = VFS_STATFS(mp, sp, td))) {
427 mtx_lock(&mountlist_mtx);
428 nmp = TAILQ_NEXT(mp, mnt_list);
433 bcopy(sp, &sb, sizeof(sb));
434 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
437 if (bufseg == UIO_USERSPACE) {
438 error = copyout(sp, sfsp, sizeof(*sp));
445 bcopy(sp, sfsp, sizeof(*sp));
449 mtx_lock(&mountlist_mtx);
450 nmp = TAILQ_NEXT(mp, mnt_list);
453 mtx_unlock(&mountlist_mtx);
455 if (sfsp && count > maxcount)
456 td->td_retval[0] = maxcount;
458 td->td_retval[0] = count;
462 #ifdef COMPAT_FREEBSD4
464 * Get old format filesystem statistics.
466 static void cvtstatfs(struct statfs *, struct ostatfs *);
468 #ifndef _SYS_SYSPROTO_H_
469 struct freebsd4_statfs_args {
475 freebsd4_statfs(td, uap)
477 struct freebsd4_statfs_args /* {
486 error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
489 cvtstatfs(&sf, &osb);
490 return (copyout(&osb, uap->buf, sizeof(osb)));
494 * Get filesystem statistics.
496 #ifndef _SYS_SYSPROTO_H_
497 struct freebsd4_fstatfs_args {
503 freebsd4_fstatfs(td, uap)
505 struct freebsd4_fstatfs_args /* {
514 error = kern_fstatfs(td, uap->fd, &sf);
517 cvtstatfs(&sf, &osb);
518 return (copyout(&osb, uap->buf, sizeof(osb)));
522 * Get statistics on all filesystems.
524 #ifndef _SYS_SYSPROTO_H_
525 struct freebsd4_getfsstat_args {
532 freebsd4_getfsstat(td, uap)
534 register struct freebsd4_getfsstat_args /* {
540 struct statfs *buf, *sp;
545 count = uap->bufsize / sizeof(struct ostatfs);
546 size = count * sizeof(struct statfs);
548 buf = malloc(size, M_TEMP, M_WAITOK);
551 error = kern_getfsstat(td, buf, size, UIO_SYSSPACE, uap->flags);
553 count = td->td_retval[0];
555 while (count > 0 && error == 0) {
557 error = copyout(&osb, uap->buf, sizeof(osb));
568 * Implement fstatfs() for (NFS) file handles.
570 #ifndef _SYS_SYSPROTO_H_
571 struct freebsd4_fhstatfs_args {
572 struct fhandle *u_fhp;
577 freebsd4_fhstatfs(td, uap)
579 struct freebsd4_fhstatfs_args /* {
580 struct fhandle *u_fhp;
589 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
592 error = kern_fhstatfs(td, fh, &sf);
595 cvtstatfs(&sf, &osb);
596 return (copyout(&osb, uap->buf, sizeof(osb)));
600 * Convert a new format statfs structure to an old format statfs structure.
608 bzero(osp, sizeof(*osp));
609 osp->f_bsize = MIN(nsp->f_bsize, LONG_MAX);
610 osp->f_iosize = MIN(nsp->f_iosize, LONG_MAX);
611 osp->f_blocks = MIN(nsp->f_blocks, LONG_MAX);
612 osp->f_bfree = MIN(nsp->f_bfree, LONG_MAX);
613 osp->f_bavail = MIN(nsp->f_bavail, LONG_MAX);
614 osp->f_files = MIN(nsp->f_files, LONG_MAX);
615 osp->f_ffree = MIN(nsp->f_ffree, LONG_MAX);
616 osp->f_owner = nsp->f_owner;
617 osp->f_type = nsp->f_type;
618 osp->f_flags = nsp->f_flags;
619 osp->f_syncwrites = MIN(nsp->f_syncwrites, LONG_MAX);
620 osp->f_asyncwrites = MIN(nsp->f_asyncwrites, LONG_MAX);
621 osp->f_syncreads = MIN(nsp->f_syncreads, LONG_MAX);
622 osp->f_asyncreads = MIN(nsp->f_asyncreads, LONG_MAX);
623 bcopy(nsp->f_fstypename, osp->f_fstypename,
624 MIN(MFSNAMELEN, OMNAMELEN));
625 bcopy(nsp->f_mntonname, osp->f_mntonname,
626 MIN(MFSNAMELEN, OMNAMELEN));
627 bcopy(nsp->f_mntfromname, osp->f_mntfromname,
628 MIN(MFSNAMELEN, OMNAMELEN));
629 osp->f_fsid = nsp->f_fsid;
631 #endif /* COMPAT_FREEBSD4 */
634 * Change current working directory to a given file descriptor.
636 #ifndef _SYS_SYSPROTO_H_
644 struct fchdir_args /* {
648 register struct filedesc *fdp = td->td_proc->p_fd;
649 struct vnode *vp, *tdp, *vpold;
655 if ((error = getvnode(fdp, uap->fd, &fp)) != 0)
658 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
661 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
662 if (vp->v_type != VDIR)
665 else if ((error = mac_check_vnode_chdir(td->td_ucred, vp)) != 0) {
669 error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td);
670 while (!error && (mp = vp->v_mountedhere) != NULL) {
672 if (vfs_busy(mp, 0, 0, td))
674 tvfslocked = VFS_LOCK_GIANT(mp);
675 error = VFS_ROOT(mp, LK_EXCLUSIVE, &tdp, td);
678 VFS_UNLOCK_GIANT(tvfslocked);
682 VFS_UNLOCK_GIANT(vfslocked);
684 vfslocked = tvfslocked;
688 VFS_UNLOCK_GIANT(vfslocked);
691 VOP_UNLOCK(vp, 0, td);
692 FILEDESC_LOCK_FAST(fdp);
693 vpold = fdp->fd_cdir;
695 FILEDESC_UNLOCK_FAST(fdp);
697 VFS_UNLOCK_GIANT(vfslocked);
702 * Change current working directory (``.'').
704 #ifndef _SYS_SYSPROTO_H_
712 struct chdir_args /* {
717 return (kern_chdir(td, uap->path, UIO_USERSPACE));
721 kern_chdir(struct thread *td, char *path, enum uio_seg pathseg)
723 register struct filedesc *fdp = td->td_proc->p_fd;
729 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE, pathseg, path, td);
730 if ((error = namei(&nd)) != 0)
732 vfslocked = NDHASGIANT(&nd);
733 if ((error = change_dir(nd.ni_vp, td)) != 0) {
735 VFS_UNLOCK_GIANT(vfslocked);
736 NDFREE(&nd, NDF_ONLY_PNBUF);
739 VOP_UNLOCK(nd.ni_vp, 0, td);
740 NDFREE(&nd, NDF_ONLY_PNBUF);
741 FILEDESC_LOCK_FAST(fdp);
743 fdp->fd_cdir = nd.ni_vp;
744 FILEDESC_UNLOCK_FAST(fdp);
746 VFS_UNLOCK_GIANT(vfslocked);
751 * Helper function for raised chroot(2) security function: Refuse if
752 * any filedescriptors are open directories.
755 chroot_refuse_vdir_fds(fdp)
756 struct filedesc *fdp;
762 FILEDESC_LOCK_ASSERT(fdp, MA_OWNED);
763 for (fd = 0; fd < fdp->fd_nfiles ; fd++) {
764 fp = fget_locked(fdp, fd);
767 if (fp->f_type == DTYPE_VNODE) {
769 if (vp->v_type == VDIR)
777 * This sysctl determines if we will allow a process to chroot(2) if it
778 * has a directory open:
779 * 0: disallowed for all processes.
780 * 1: allowed for processes that were not already chroot(2)'ed.
781 * 2: allowed for all processes.
784 static int chroot_allow_open_directories = 1;
786 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW,
787 &chroot_allow_open_directories, 0, "");
790 * Change notion of root (``/'') directory.
792 #ifndef _SYS_SYSPROTO_H_
800 struct chroot_args /* {
808 error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
811 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE,
812 UIO_USERSPACE, uap->path, td);
816 vfslocked = NDHASGIANT(&nd);
817 if ((error = change_dir(nd.ni_vp, td)) != 0)
820 if ((error = mac_check_vnode_chroot(td->td_ucred, nd.ni_vp)))
823 VOP_UNLOCK(nd.ni_vp, 0, td);
824 error = change_root(nd.ni_vp, td);
826 VFS_UNLOCK_GIANT(vfslocked);
827 NDFREE(&nd, NDF_ONLY_PNBUF);
831 VFS_UNLOCK_GIANT(vfslocked);
833 NDFREE(&nd, NDF_ONLY_PNBUF);
838 * Common routine for chroot and chdir. Callers must provide a locked vnode
848 ASSERT_VOP_LOCKED(vp, "change_dir(): vp not locked");
849 if (vp->v_type != VDIR)
852 error = mac_check_vnode_chdir(td->td_ucred, vp);
856 error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td);
861 * Common routine for kern_chroot() and jail_attach(). The caller is
862 * responsible for invoking suser() and mac_check_chroot() to authorize this
870 struct filedesc *fdp;
874 VFS_ASSERT_GIANT(vp->v_mount);
875 fdp = td->td_proc->p_fd;
877 if (chroot_allow_open_directories == 0 ||
878 (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) {
879 error = chroot_refuse_vdir_fds(fdp);
881 FILEDESC_UNLOCK(fdp);
885 oldvp = fdp->fd_rdir;
892 FILEDESC_UNLOCK(fdp);
898 * Check permissions, allocate an open file structure,
899 * and call the device open routine if any.
903 #ifndef _SYS_SYSPROTO_H_
913 register struct open_args /* {
921 error = kern_open(td, uap->path, UIO_USERSPACE, uap->flags, uap->mode);
922 if (mtx_owned(&Giant))
923 printf("open: %s: %d\n", uap->path, error);
928 kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags,
931 struct proc *p = td->td_proc;
932 struct filedesc *fdp = p->p_fd;
939 int type, indx, error;
944 if ((flags & O_ACCMODE) == O_ACCMODE)
946 flags = FFLAGS(flags);
947 error = falloc(td, &nfp, &indx);
950 /* An extra reference on `nfp' has been held for us by falloc(). */
952 cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
953 NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td);
954 td->td_dupfd = -1; /* XXX check for fdopen */
955 error = vn_open(&nd, &flags, cmode, indx);
958 * If the vn_open replaced the method vector, something
959 * wonderous happened deep below and we just pass it up
960 * pretending we know what we do.
962 if (error == ENXIO && fp->f_ops != &badfileops) {
964 td->td_retval[0] = indx;
969 * release our own reference
974 * handle special fdopen() case. bleh. dupfdopen() is
975 * responsible for dropping the old contents of ofiles[indx]
978 if ((error == ENODEV || error == ENXIO) &&
979 td->td_dupfd >= 0 && /* XXX from fdopen */
981 dupfdopen(td, fdp, indx, td->td_dupfd, flags, error)) == 0) {
982 td->td_retval[0] = indx;
986 * Clean up the descriptor, but only if another thread hadn't
987 * replaced or closed it.
989 fdclose(fdp, fp, indx, td);
991 if (error == ERESTART)
996 vfslocked = NDHASGIANT(&nd);
997 NDFREE(&nd, NDF_ONLY_PNBUF);
1001 * There should be 2 references on the file, one from the descriptor
1002 * table, and one for us.
1004 * Handle the case where someone closed the file (via its file
1005 * descriptor) while we were blocked. The end result should look
1006 * like opening the file succeeded but it was immediately closed.
1007 * We call vn_close() manually because we haven't yet hooked up
1008 * the various 'struct file' fields.
1012 if (fp->f_count == 1) {
1014 KASSERT(fdp->fd_ofiles[indx] != fp,
1015 ("Open file descriptor lost all refs"));
1017 FILEDESC_UNLOCK(fdp);
1018 VOP_UNLOCK(vp, 0, td);
1019 vn_close(vp, flags & FMASK, fp->f_cred, td);
1020 VFS_UNLOCK_GIANT(vfslocked);
1022 td->td_retval[0] = indx;
1026 if (fp->f_data == NULL)
1028 fp->f_flag = flags & FMASK;
1029 if (fp->f_ops == &badfileops)
1032 fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE);
1034 FILEDESC_UNLOCK(fdp);
1036 VOP_UNLOCK(vp, 0, td);
1037 if (flags & (O_EXLOCK | O_SHLOCK)) {
1038 lf.l_whence = SEEK_SET;
1041 if (flags & O_EXLOCK)
1042 lf.l_type = F_WRLCK;
1044 lf.l_type = F_RDLCK;
1046 if ((flags & FNONBLOCK) == 0)
1048 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf,
1051 fp->f_flag |= FHASLOCK;
1053 if (flags & O_TRUNC) {
1054 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
1056 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
1059 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1061 error = mac_check_vnode_write(td->td_ucred, fp->f_cred, vp);
1064 error = VOP_SETATTR(vp, &vat, td->td_ucred, td);
1065 VOP_UNLOCK(vp, 0, td);
1066 vn_finished_write(mp);
1070 VFS_UNLOCK_GIANT(vfslocked);
1072 * Release our private reference, leaving the one associated with
1073 * the descriptor table intact.
1076 td->td_retval[0] = indx;
1079 VFS_UNLOCK_GIANT(vfslocked);
1080 fdclose(fdp, fp, indx, td);
1091 #ifndef _SYS_SYSPROTO_H_
1092 struct ocreat_args {
1100 register struct ocreat_args /* {
1106 return (kern_open(td, uap->path, UIO_USERSPACE,
1107 O_WRONLY | O_CREAT | O_TRUNC, uap->mode));
1109 #endif /* COMPAT_43 */
1112 * Create a special file.
1114 #ifndef _SYS_SYSPROTO_H_
1124 register struct mknod_args /* {
1131 return (kern_mknod(td, uap->path, UIO_USERSPACE, uap->mode, uap->dev));
1135 kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode,
1143 struct nameidata nd;
1146 switch (mode & S_IFMT) {
1152 error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
1159 NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE, pathseg, path, td);
1160 if ((error = namei(&nd)) != 0)
1162 vfslocked = NDHASGIANT(&nd);
1165 NDFREE(&nd, NDF_ONLY_PNBUF);
1167 if (vp == nd.ni_dvp)
1171 VFS_UNLOCK_GIANT(vfslocked);
1175 FILEDESC_LOCK_FAST(td->td_proc->p_fd);
1176 vattr.va_mode = (mode & ALLPERMS) &
1177 ~td->td_proc->p_fd->fd_cmask;
1178 FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
1179 vattr.va_rdev = dev;
1182 switch (mode & S_IFMT) {
1183 case S_IFMT: /* used by badsect to flag bad sectors */
1184 vattr.va_type = VBAD;
1187 vattr.va_type = VCHR;
1190 vattr.va_type = VBLK;
1200 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1201 NDFREE(&nd, NDF_ONLY_PNBUF);
1203 VFS_UNLOCK_GIANT(vfslocked);
1204 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1209 if (error == 0 && !whiteout)
1210 error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp,
1211 &nd.ni_cnd, &vattr);
1214 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1216 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE);
1218 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp,
1219 &nd.ni_cnd, &vattr);
1224 NDFREE(&nd, NDF_ONLY_PNBUF);
1226 vn_finished_write(mp);
1227 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod");
1228 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod");
1229 VFS_UNLOCK_GIANT(vfslocked);
1234 * Create a named pipe.
1236 #ifndef _SYS_SYSPROTO_H_
1237 struct mkfifo_args {
1245 register struct mkfifo_args /* {
1251 return (kern_mkfifo(td, uap->path, UIO_USERSPACE, uap->mode));
1255 kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode)
1260 struct nameidata nd;
1265 NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE, pathseg, path, td);
1266 if ((error = namei(&nd)) != 0)
1268 vfslocked = NDHASGIANT(&nd);
1269 if (nd.ni_vp != NULL) {
1270 NDFREE(&nd, NDF_ONLY_PNBUF);
1272 if (nd.ni_vp == nd.ni_dvp)
1276 VFS_UNLOCK_GIANT(vfslocked);
1279 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1280 NDFREE(&nd, NDF_ONLY_PNBUF);
1282 VFS_UNLOCK_GIANT(vfslocked);
1283 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1288 vattr.va_type = VFIFO;
1289 FILEDESC_LOCK_FAST(td->td_proc->p_fd);
1290 vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask;
1291 FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
1293 error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
1298 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1299 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
1306 vn_finished_write(mp);
1307 VFS_UNLOCK_GIANT(vfslocked);
1308 NDFREE(&nd, NDF_ONLY_PNBUF);
1313 * Make a hard file link.
1315 #ifndef _SYS_SYSPROTO_H_
1324 register struct link_args /* {
1331 error = kern_link(td, uap->path, uap->link, UIO_USERSPACE);
1335 SYSCTL_DECL(_security_bsd);
1337 static int hardlink_check_uid = 0;
1338 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_uid, CTLFLAG_RW,
1339 &hardlink_check_uid, 0,
1340 "Unprivileged processes cannot create hard links to files owned by other "
1342 static int hardlink_check_gid = 0;
1343 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_gid, CTLFLAG_RW,
1344 &hardlink_check_gid, 0,
1345 "Unprivileged processes cannot create hard links to files owned by other "
1349 can_hardlink(struct vnode *vp, struct thread *td, struct ucred *cred)
1354 if (suser_cred(cred, SUSER_ALLOWJAIL) == 0)
1357 if (!hardlink_check_uid && !hardlink_check_gid)
1360 error = VOP_GETATTR(vp, &va, cred, td);
1364 if (hardlink_check_uid) {
1365 if (cred->cr_uid != va.va_uid)
1369 if (hardlink_check_gid) {
1370 if (!groupmember(va.va_gid, cred))
1378 kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg)
1382 struct nameidata nd;
1388 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, segflg, path, td);
1389 if ((error = namei(&nd)) != 0)
1391 vfslocked = NDHASGIANT(&nd);
1392 NDFREE(&nd, NDF_ONLY_PNBUF);
1394 if (vp->v_type == VDIR) {
1396 VFS_UNLOCK_GIANT(vfslocked);
1397 return (EPERM); /* POSIX */
1399 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
1401 VFS_UNLOCK_GIANT(vfslocked);
1404 NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME, segflg, link, td);
1405 if ((error = namei(&nd)) == 0) {
1406 lvfslocked = NDHASGIANT(&nd);
1407 if (nd.ni_vp != NULL) {
1409 if (nd.ni_dvp == nd.ni_vp)
1414 } else if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td))
1416 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1417 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
1418 error = can_hardlink(vp, td, td->td_ucred);
1421 error = mac_check_vnode_link(td->td_ucred,
1422 nd.ni_dvp, vp, &nd.ni_cnd);
1425 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
1426 VOP_UNLOCK(vp, 0, td);
1429 NDFREE(&nd, NDF_ONLY_PNBUF);
1430 VFS_UNLOCK_GIANT(lvfslocked);
1433 vn_finished_write(mp);
1434 VFS_UNLOCK_GIANT(vfslocked);
1435 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link");
1436 ASSERT_VOP_UNLOCKED(nd.ni_vp, "link");
1441 * Make a symbolic link.
1443 #ifndef _SYS_SYSPROTO_H_
1444 struct symlink_args {
1452 register struct symlink_args /* {
1458 return (kern_symlink(td, uap->path, uap->link, UIO_USERSPACE));
1462 kern_symlink(struct thread *td, char *path, char *link, enum uio_seg segflg)
1468 struct nameidata nd;
1471 if (segflg == UIO_SYSSPACE) {
1474 syspath = uma_zalloc(namei_zone, M_WAITOK);
1475 if ((error = copyinstr(path, syspath, MAXPATHLEN, NULL)) != 0)
1480 NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE,
1482 if ((error = namei(&nd)) != 0)
1484 vfslocked = NDHASGIANT(&nd);
1486 NDFREE(&nd, NDF_ONLY_PNBUF);
1488 if (nd.ni_vp == nd.ni_dvp)
1492 VFS_UNLOCK_GIANT(vfslocked);
1496 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1497 NDFREE(&nd, NDF_ONLY_PNBUF);
1499 VFS_UNLOCK_GIANT(vfslocked);
1500 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1505 FILEDESC_LOCK_FAST(td->td_proc->p_fd);
1506 vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask;
1507 FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
1509 vattr.va_type = VLNK;
1510 error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
1515 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1516 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath);
1522 NDFREE(&nd, NDF_ONLY_PNBUF);
1524 vn_finished_write(mp);
1525 VFS_UNLOCK_GIANT(vfslocked);
1526 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink");
1527 ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink");
1529 if (segflg != UIO_SYSSPACE)
1530 uma_zfree(namei_zone, syspath);
1535 * Delete a whiteout from the filesystem.
1540 register struct undelete_args /* {
1546 struct nameidata nd;
1551 NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | MPSAFE, UIO_USERSPACE,
1556 vfslocked = NDHASGIANT(&nd);
1558 if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) {
1559 NDFREE(&nd, NDF_ONLY_PNBUF);
1562 if (nd.ni_vp == nd.ni_dvp)
1566 VFS_UNLOCK_GIANT(vfslocked);
1569 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1570 NDFREE(&nd, NDF_ONLY_PNBUF);
1572 VFS_UNLOCK_GIANT(vfslocked);
1573 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1577 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1578 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE);
1579 NDFREE(&nd, NDF_ONLY_PNBUF);
1581 vn_finished_write(mp);
1582 VFS_UNLOCK_GIANT(vfslocked);
1583 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "undelete");
1584 ASSERT_VOP_UNLOCKED(nd.ni_vp, "undelete");
1589 * Delete a name from the filesystem.
1591 #ifndef _SYS_SYSPROTO_H_
1592 struct unlink_args {
1599 struct unlink_args /* {
1605 error = kern_unlink(td, uap->path, UIO_USERSPACE);
1610 kern_unlink(struct thread *td, char *path, enum uio_seg pathseg)
1615 struct nameidata nd;
1620 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE, pathseg, path, td);
1621 if ((error = namei(&nd)) != 0)
1623 vfslocked = NDHASGIANT(&nd);
1625 if (vp->v_type == VDIR)
1626 error = EPERM; /* POSIX */
1629 * The root of a mounted filesystem cannot be deleted.
1631 * XXX: can this only be a VDIR case?
1633 if (vp->v_vflag & VV_ROOT)
1637 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1638 NDFREE(&nd, NDF_ONLY_PNBUF);
1639 if (vp == nd.ni_dvp)
1644 VFS_UNLOCK_GIANT(vfslocked);
1645 if ((error = vn_start_write(NULL, &mp,
1646 V_XSLEEP | PCATCH)) != 0)
1651 error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp,
1656 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1657 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd);
1661 vn_finished_write(mp);
1663 NDFREE(&nd, NDF_ONLY_PNBUF);
1664 if (vp == nd.ni_dvp)
1669 VFS_UNLOCK_GIANT(vfslocked);
1670 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink");
1671 ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink");
1676 * Reposition read/write file offset.
1678 #ifndef _SYS_SYSPROTO_H_
1689 register struct lseek_args /* {
1696 struct ucred *cred = td->td_ucred;
1704 if ((error = fget(td, uap->fd, &fp)) != 0)
1706 if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) {
1711 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1712 noneg = (vp->v_type != VCHR);
1713 offset = uap->offset;
1714 switch (uap->whence) {
1717 (fp->f_offset < 0 ||
1718 (offset > 0 && fp->f_offset > OFF_MAX - offset))) {
1722 offset += fp->f_offset;
1725 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1726 error = VOP_GETATTR(vp, &vattr, cred, td);
1727 VOP_UNLOCK(vp, 0, td);
1731 (vattr.va_size > OFF_MAX ||
1732 (offset > 0 && vattr.va_size > OFF_MAX - offset))) {
1736 offset += vattr.va_size;
1743 if (error == 0 && noneg && offset < 0)
1747 fp->f_offset = offset;
1748 *(off_t *)(td->td_retval) = fp->f_offset;
1751 VFS_UNLOCK_GIANT(vfslocked);
1755 #if defined(COMPAT_43)
1757 * Reposition read/write file offset.
1759 #ifndef _SYS_SYSPROTO_H_
1760 struct olseek_args {
1769 register struct olseek_args /* {
1775 struct lseek_args /* {
1784 nuap.offset = uap->offset;
1785 nuap.whence = uap->whence;
1786 error = lseek(td, &nuap);
1789 #endif /* COMPAT_43 */
1792 * Check access permissions using passed credentials.
1795 vn_access(vp, user_flags, cred, td)
1803 /* Flags == 0 means only check for existence. */
1807 if (user_flags & R_OK)
1809 if (user_flags & W_OK)
1811 if (user_flags & X_OK)
1814 error = mac_check_vnode_access(cred, vp, flags);
1818 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
1819 error = VOP_ACCESS(vp, flags, cred, td);
1825 * Check access permissions using "real" credentials.
1827 #ifndef _SYS_SYSPROTO_H_
1828 struct access_args {
1836 register struct access_args /* {
1842 return (kern_access(td, uap->path, UIO_USERSPACE, uap->flags));
1846 kern_access(struct thread *td, char *path, enum uio_seg pathseg, int flags)
1848 struct ucred *cred, *tmpcred;
1849 register struct vnode *vp;
1850 struct nameidata nd;
1855 * Create and modify a temporary credential instead of one that
1856 * is potentially shared. This could also mess up socket
1857 * buffer accounting which can run in an interrupt context.
1859 cred = td->td_ucred;
1860 tmpcred = crdup(cred);
1861 tmpcred->cr_uid = cred->cr_ruid;
1862 tmpcred->cr_groups[0] = cred->cr_rgid;
1863 td->td_ucred = tmpcred;
1864 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE, pathseg, path, td);
1865 if ((error = namei(&nd)) != 0)
1867 vfslocked = NDHASGIANT(&nd);
1870 error = vn_access(vp, flags, tmpcred, td);
1871 NDFREE(&nd, NDF_ONLY_PNBUF);
1873 VFS_UNLOCK_GIANT(vfslocked);
1875 td->td_ucred = cred;
1881 * Check access permissions using "effective" credentials.
1883 #ifndef _SYS_SYSPROTO_H_
1884 struct eaccess_args {
1892 register struct eaccess_args /* {
1897 struct nameidata nd;
1902 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE, UIO_USERSPACE,
1904 if ((error = namei(&nd)) != 0)
1907 vfslocked = NDHASGIANT(&nd);
1908 error = vn_access(vp, uap->flags, td->td_ucred, td);
1909 NDFREE(&nd, NDF_ONLY_PNBUF);
1911 VFS_UNLOCK_GIANT(vfslocked);
1915 #if defined(COMPAT_43)
1917 * Get file status; this version follows links.
1919 #ifndef _SYS_SYSPROTO_H_
1928 register struct ostat_args /* {
1937 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
1941 error = copyout(&osb, uap->ub, sizeof (osb));
1946 * Get file status; this version does not follow links.
1948 #ifndef _SYS_SYSPROTO_H_
1949 struct olstat_args {
1957 register struct olstat_args /* {
1966 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
1970 error = copyout(&osb, uap->ub, sizeof (osb));
1975 * Convert from an old to a new stat structure.
1983 ost->st_dev = st->st_dev;
1984 ost->st_ino = st->st_ino;
1985 ost->st_mode = st->st_mode;
1986 ost->st_nlink = st->st_nlink;
1987 ost->st_uid = st->st_uid;
1988 ost->st_gid = st->st_gid;
1989 ost->st_rdev = st->st_rdev;
1990 if (st->st_size < (quad_t)1 << 32)
1991 ost->st_size = st->st_size;
1994 ost->st_atime = st->st_atime;
1995 ost->st_mtime = st->st_mtime;
1996 ost->st_ctime = st->st_ctime;
1997 ost->st_blksize = st->st_blksize;
1998 ost->st_blocks = st->st_blocks;
1999 ost->st_flags = st->st_flags;
2000 ost->st_gen = st->st_gen;
2002 #endif /* COMPAT_43 */
2005 * Get file status; this version follows links.
2007 #ifndef _SYS_SYSPROTO_H_
2016 register struct stat_args /* {
2024 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
2026 error = copyout(&sb, uap->ub, sizeof (sb));
2031 kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
2033 struct nameidata nd;
2035 int error, vfslocked;
2037 NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE,
2039 if ((error = namei(&nd)) != 0)
2041 vfslocked = NDHASGIANT(&nd);
2042 error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td);
2043 NDFREE(&nd, NDF_ONLY_PNBUF);
2045 VFS_UNLOCK_GIANT(vfslocked);
2053 * Get file status; this version does not follow links.
2055 #ifndef _SYS_SYSPROTO_H_
2064 register struct lstat_args /* {
2072 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
2074 error = copyout(&sb, uap->ub, sizeof (sb));
2079 kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
2083 struct nameidata nd;
2084 int error, vfslocked;
2086 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKSHARED | MPSAFE,
2088 if ((error = namei(&nd)) != 0)
2090 vfslocked = NDHASGIANT(&nd);
2092 error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
2093 NDFREE(&nd, NDF_ONLY_PNBUF);
2095 VFS_UNLOCK_GIANT(vfslocked);
2103 * Implementation of the NetBSD [l]stat() functions.
2110 bzero(nsb, sizeof *nsb);
2111 nsb->st_dev = sb->st_dev;
2112 nsb->st_ino = sb->st_ino;
2113 nsb->st_mode = sb->st_mode;
2114 nsb->st_nlink = sb->st_nlink;
2115 nsb->st_uid = sb->st_uid;
2116 nsb->st_gid = sb->st_gid;
2117 nsb->st_rdev = sb->st_rdev;
2118 nsb->st_atimespec = sb->st_atimespec;
2119 nsb->st_mtimespec = sb->st_mtimespec;
2120 nsb->st_ctimespec = sb->st_ctimespec;
2121 nsb->st_size = sb->st_size;
2122 nsb->st_blocks = sb->st_blocks;
2123 nsb->st_blksize = sb->st_blksize;
2124 nsb->st_flags = sb->st_flags;
2125 nsb->st_gen = sb->st_gen;
2126 nsb->st_birthtimespec = sb->st_birthtimespec;
2129 #ifndef _SYS_SYSPROTO_H_
2138 register struct nstat_args /* {
2147 error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
2150 cvtnstat(&sb, &nsb);
2151 error = copyout(&nsb, uap->ub, sizeof (nsb));
2156 * NetBSD lstat. Get file status; this version does not follow links.
2158 #ifndef _SYS_SYSPROTO_H_
2167 register struct nlstat_args /* {
2176 error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
2179 cvtnstat(&sb, &nsb);
2180 error = copyout(&nsb, uap->ub, sizeof (nsb));
2185 * Get configurable pathname variables.
2187 #ifndef _SYS_SYSPROTO_H_
2188 struct pathconf_args {
2196 register struct pathconf_args /* {
2202 return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name));
2206 kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name)
2208 struct nameidata nd;
2209 int error, vfslocked;
2211 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE, pathseg, path, td);
2212 if ((error = namei(&nd)) != 0)
2214 vfslocked = NDHASGIANT(&nd);
2215 NDFREE(&nd, NDF_ONLY_PNBUF);
2217 /* If asynchronous I/O is available, it works for all files. */
2218 if (name == _PC_ASYNC_IO)
2219 td->td_retval[0] = async_io_version;
2221 error = VOP_PATHCONF(nd.ni_vp, name, td->td_retval);
2223 VFS_UNLOCK_GIANT(vfslocked);
2228 * Return target name of a symbolic link.
2230 #ifndef _SYS_SYSPROTO_H_
2231 struct readlink_args {
2240 register struct readlink_args /* {
2247 return (kern_readlink(td, uap->path, UIO_USERSPACE, uap->buf,
2248 UIO_USERSPACE, uap->count));
2252 kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf,
2253 enum uio_seg bufseg, int count)
2255 register struct vnode *vp;
2259 struct nameidata nd;
2262 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE, pathseg, path, td);
2263 if ((error = namei(&nd)) != 0)
2265 NDFREE(&nd, NDF_ONLY_PNBUF);
2266 vfslocked = NDHASGIANT(&nd);
2269 error = mac_check_vnode_readlink(td->td_ucred, vp);
2272 VFS_UNLOCK_GIANT(vfslocked);
2276 if (vp->v_type != VLNK)
2279 aiov.iov_base = buf;
2280 aiov.iov_len = count;
2281 auio.uio_iov = &aiov;
2282 auio.uio_iovcnt = 1;
2283 auio.uio_offset = 0;
2284 auio.uio_rw = UIO_READ;
2285 auio.uio_segflg = bufseg;
2287 auio.uio_resid = count;
2288 error = VOP_READLINK(vp, &auio, td->td_ucred);
2291 VFS_UNLOCK_GIANT(vfslocked);
2292 td->td_retval[0] = count - auio.uio_resid;
2297 * Common implementation code for chflags() and fchflags().
2300 setfflags(td, vp, flags)
2310 * Prevent non-root users from setting flags on devices. When
2311 * a device is reused, users can retain ownership of the device
2312 * if they are allowed to set flags and programs assume that
2313 * chown can't fail when done as root.
2315 if (vp->v_type == VCHR || vp->v_type == VBLK) {
2316 error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
2321 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2323 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2324 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2326 vattr.va_flags = flags;
2328 error = mac_check_vnode_setflags(td->td_ucred, vp, vattr.va_flags);
2331 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2332 VOP_UNLOCK(vp, 0, td);
2333 vn_finished_write(mp);
2338 * Change flags of a file given a path name.
2340 #ifndef _SYS_SYSPROTO_H_
2341 struct chflags_args {
2349 register struct chflags_args /* {
2355 struct nameidata nd;
2358 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_USERSPACE, uap->path, td);
2359 if ((error = namei(&nd)) != 0)
2361 NDFREE(&nd, NDF_ONLY_PNBUF);
2362 vfslocked = NDHASGIANT(&nd);
2363 error = setfflags(td, nd.ni_vp, uap->flags);
2365 VFS_UNLOCK_GIANT(vfslocked);
2370 * Same as chflags() but doesn't follow symlinks.
2375 register struct lchflags_args /* {
2381 struct nameidata nd;
2384 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_USERSPACE, uap->path, td);
2385 if ((error = namei(&nd)) != 0)
2387 vfslocked = NDHASGIANT(&nd);
2388 NDFREE(&nd, NDF_ONLY_PNBUF);
2389 error = setfflags(td, nd.ni_vp, uap->flags);
2391 VFS_UNLOCK_GIANT(vfslocked);
2396 * Change flags of a file given a file descriptor.
2398 #ifndef _SYS_SYSPROTO_H_
2399 struct fchflags_args {
2407 register struct fchflags_args /* {
2416 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
2418 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2419 error = setfflags(td, fp->f_vnode, uap->flags);
2421 VFS_UNLOCK_GIANT(vfslocked);
2426 * Common implementation code for chmod(), lchmod() and fchmod().
2429 setfmode(td, vp, mode)
2438 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2440 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2441 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2443 vattr.va_mode = mode & ALLPERMS;
2445 error = mac_check_vnode_setmode(td->td_ucred, vp, vattr.va_mode);
2448 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2449 VOP_UNLOCK(vp, 0, td);
2450 vn_finished_write(mp);
2455 * Change mode of a file given path name.
2457 #ifndef _SYS_SYSPROTO_H_
2466 register struct chmod_args /* {
2472 return (kern_chmod(td, uap->path, UIO_USERSPACE, uap->mode));
2476 kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode)
2479 struct nameidata nd;
2482 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, pathseg, path, td);
2483 if ((error = namei(&nd)) != 0)
2485 vfslocked = NDHASGIANT(&nd);
2486 NDFREE(&nd, NDF_ONLY_PNBUF);
2487 error = setfmode(td, nd.ni_vp, mode);
2489 VFS_UNLOCK_GIANT(vfslocked);
2494 * Change mode of a file given path name (don't follow links.)
2496 #ifndef _SYS_SYSPROTO_H_
2497 struct lchmod_args {
2505 register struct lchmod_args /* {
2511 struct nameidata nd;
2514 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_USERSPACE, uap->path, td);
2515 if ((error = namei(&nd)) != 0)
2517 vfslocked = NDHASGIANT(&nd);
2518 NDFREE(&nd, NDF_ONLY_PNBUF);
2519 error = setfmode(td, nd.ni_vp, uap->mode);
2521 VFS_UNLOCK_GIANT(vfslocked);
2526 * Change mode of a file given a file descriptor.
2528 #ifndef _SYS_SYSPROTO_H_
2529 struct fchmod_args {
2537 register struct fchmod_args /* {
2546 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
2548 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2549 error = setfmode(td, fp->f_vnode, uap->mode);
2551 VFS_UNLOCK_GIANT(vfslocked);
2556 * Common implementation for chown(), lchown(), and fchown()
2559 setfown(td, vp, uid, gid)
2569 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2571 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2572 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2577 error = mac_check_vnode_setowner(td->td_ucred, vp, vattr.va_uid,
2581 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2582 VOP_UNLOCK(vp, 0, td);
2583 vn_finished_write(mp);
2588 * Set ownership given a path name.
2590 #ifndef _SYS_SYSPROTO_H_
2600 register struct chown_args /* {
2607 return (kern_chown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid));
2611 kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid,
2615 struct nameidata nd;
2618 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, pathseg, path, td);
2619 if ((error = namei(&nd)) != 0)
2621 vfslocked = NDHASGIANT(&nd);
2622 NDFREE(&nd, NDF_ONLY_PNBUF);
2623 error = setfown(td, nd.ni_vp, uid, gid);
2625 VFS_UNLOCK_GIANT(vfslocked);
2630 * Set ownership given a path name, do not cross symlinks.
2632 #ifndef _SYS_SYSPROTO_H_
2633 struct lchown_args {
2642 register struct lchown_args /* {
2649 return (kern_lchown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid));
2653 kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid,
2657 struct nameidata nd;
2660 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, pathseg, path, td);
2661 if ((error = namei(&nd)) != 0)
2663 vfslocked = NDHASGIANT(&nd);
2664 NDFREE(&nd, NDF_ONLY_PNBUF);
2665 error = setfown(td, nd.ni_vp, uid, gid);
2667 VFS_UNLOCK_GIANT(vfslocked);
2672 * Set ownership given a file descriptor.
2674 #ifndef _SYS_SYSPROTO_H_
2675 struct fchown_args {
2684 register struct fchown_args /* {
2694 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
2696 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2697 error = setfown(td, fp->f_vnode, uap->uid, uap->gid);
2699 VFS_UNLOCK_GIANT(vfslocked);
2704 * Common implementation code for utimes(), lutimes(), and futimes().
2707 getutimes(usrtvp, tvpseg, tsp)
2708 const struct timeval *usrtvp;
2709 enum uio_seg tvpseg;
2710 struct timespec *tsp;
2712 struct timeval tv[2];
2713 const struct timeval *tvp;
2716 if (usrtvp == NULL) {
2718 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]);
2721 if (tvpseg == UIO_SYSSPACE) {
2724 if ((error = copyin(usrtvp, tv, sizeof(tv))) != 0)
2729 TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]);
2730 TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]);
2736 * Common implementation code for utimes(), lutimes(), and futimes().
2739 setutimes(td, vp, ts, numtimes, nullflag)
2742 const struct timespec *ts;
2746 int error, setbirthtime;
2750 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2752 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2753 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2755 if (numtimes < 3 && VOP_GETATTR(vp, &vattr, td->td_ucred, td) == 0 &&
2756 timespeccmp(&ts[1], &vattr.va_birthtime, < ))
2759 vattr.va_atime = ts[0];
2760 vattr.va_mtime = ts[1];
2762 vattr.va_birthtime = ts[1];
2764 vattr.va_birthtime = ts[2];
2766 vattr.va_vaflags |= VA_UTIMES_NULL;
2768 error = mac_check_vnode_setutimes(td->td_ucred, vp, vattr.va_atime,
2772 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2773 VOP_UNLOCK(vp, 0, td);
2774 vn_finished_write(mp);
2779 * Set the access and modification times of a file.
2781 #ifndef _SYS_SYSPROTO_H_
2782 struct utimes_args {
2784 struct timeval *tptr;
2790 register struct utimes_args /* {
2792 struct timeval *tptr;
2796 return (kern_utimes(td, uap->path, UIO_USERSPACE, uap->tptr,
2801 kern_utimes(struct thread *td, char *path, enum uio_seg pathseg,
2802 struct timeval *tptr, enum uio_seg tptrseg)
2804 struct timespec ts[2];
2806 struct nameidata nd;
2809 if ((error = getutimes(tptr, tptrseg, ts)) != 0)
2811 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, pathseg, path, td);
2812 if ((error = namei(&nd)) != 0)
2814 vfslocked = NDHASGIANT(&nd);
2815 NDFREE(&nd, NDF_ONLY_PNBUF);
2816 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL);
2818 VFS_UNLOCK_GIANT(vfslocked);
2823 * Set the access and modification times of a file.
2825 #ifndef _SYS_SYSPROTO_H_
2826 struct lutimes_args {
2828 struct timeval *tptr;
2834 register struct lutimes_args /* {
2836 struct timeval *tptr;
2840 return (kern_lutimes(td, uap->path, UIO_USERSPACE, uap->tptr,
2845 kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg,
2846 struct timeval *tptr, enum uio_seg tptrseg)
2848 struct timespec ts[2];
2850 struct nameidata nd;
2853 if ((error = getutimes(tptr, tptrseg, ts)) != 0)
2855 NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, pathseg, path, td);
2856 if ((error = namei(&nd)) != 0)
2858 vfslocked = NDHASGIANT(&nd);
2859 NDFREE(&nd, NDF_ONLY_PNBUF);
2860 error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL);
2862 VFS_UNLOCK_GIANT(vfslocked);
2867 * Set the access and modification times of a file.
2869 #ifndef _SYS_SYSPROTO_H_
2870 struct futimes_args {
2872 struct timeval *tptr;
2878 register struct futimes_args /* {
2880 struct timeval *tptr;
2884 return (kern_futimes(td, uap->fd, uap->tptr, UIO_USERSPACE));
2888 kern_futimes(struct thread *td, int fd, struct timeval *tptr,
2889 enum uio_seg tptrseg)
2891 struct timespec ts[2];
2896 if ((error = getutimes(tptr, tptrseg, ts)) != 0)
2898 if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0)
2900 vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2901 error = setutimes(td, fp->f_vnode, ts, 2, tptr == NULL);
2903 VFS_UNLOCK_GIANT(vfslocked);
2908 * Truncate a file given its path name.
2910 #ifndef _SYS_SYSPROTO_H_
2911 struct truncate_args {
2920 register struct truncate_args /* {
2927 return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length));
2931 kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length)
2937 struct nameidata nd;
2942 NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, pathseg, path, td);
2943 if ((error = namei(&nd)) != 0)
2945 vfslocked = NDHASGIANT(&nd);
2947 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
2949 VFS_UNLOCK_GIANT(vfslocked);
2952 NDFREE(&nd, NDF_ONLY_PNBUF);
2953 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2954 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2955 if (vp->v_type == VDIR)
2958 else if ((error = mac_check_vnode_write(td->td_ucred, NOCRED, vp))) {
2961 else if ((error = vn_writechk(vp)) == 0 &&
2962 (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) {
2964 vattr.va_size = length;
2965 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2968 vn_finished_write(mp);
2969 VFS_UNLOCK_GIANT(vfslocked);
2974 * Truncate a file given a file descriptor.
2976 #ifndef _SYS_SYSPROTO_H_
2977 struct ftruncate_args {
2986 register struct ftruncate_args /* {
2999 if (uap->length < 0)
3001 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3003 if ((fp->f_flag & FWRITE) == 0) {
3008 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
3009 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
3011 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3012 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3013 if (vp->v_type == VDIR)
3016 else if ((error = mac_check_vnode_write(td->td_ucred, fp->f_cred,
3020 else if ((error = vn_writechk(vp)) == 0) {
3022 vattr.va_size = uap->length;
3023 error = VOP_SETATTR(vp, &vattr, fp->f_cred, td);
3025 VOP_UNLOCK(vp, 0, td);
3026 vn_finished_write(mp);
3028 VFS_UNLOCK_GIANT(vfslocked);
3033 #if defined(COMPAT_43)
3035 * Truncate a file given its path name.
3037 #ifndef _SYS_SYSPROTO_H_
3038 struct otruncate_args {
3046 register struct otruncate_args /* {
3051 struct truncate_args /* {
3057 nuap.path = uap->path;
3058 nuap.length = uap->length;
3059 return (truncate(td, &nuap));
3063 * Truncate a file given a file descriptor.
3065 #ifndef _SYS_SYSPROTO_H_
3066 struct oftruncate_args {
3074 register struct oftruncate_args /* {
3079 struct ftruncate_args /* {
3086 nuap.length = uap->length;
3087 return (ftruncate(td, &nuap));
3089 #endif /* COMPAT_43 */
3092 * Sync an open file.
3094 #ifndef _SYS_SYSPROTO_H_
3102 struct fsync_args /* {
3112 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3115 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
3116 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
3118 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3119 if (vp->v_object != NULL) {
3120 VM_OBJECT_LOCK(vp->v_object);
3121 vm_object_page_clean(vp->v_object, 0, 0, 0);
3122 VM_OBJECT_UNLOCK(vp->v_object);
3124 error = VOP_FSYNC(vp, MNT_WAIT, td);
3126 VOP_UNLOCK(vp, 0, td);
3127 vn_finished_write(mp);
3129 VFS_UNLOCK_GIANT(vfslocked);
3135 * Rename files. Source and destination must either both be directories,
3136 * or both not be directories. If target is a directory, it must be empty.
3138 #ifndef _SYS_SYSPROTO_H_
3139 struct rename_args {
3147 register struct rename_args /* {
3153 return (kern_rename(td, uap->from, uap->to, UIO_USERSPACE));
3157 kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg)
3159 struct mount *mp = NULL;
3160 struct vnode *tvp, *fvp, *tdvp;
3161 struct nameidata fromnd, tond;
3168 NDINIT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE,
3171 NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE,
3174 if ((error = namei(&fromnd)) != 0)
3176 fvfslocked = NDHASGIANT(&fromnd);
3179 error = mac_check_vnode_rename_from(td->td_ucred, fromnd.ni_dvp,
3180 fromnd.ni_vp, &fromnd.ni_cnd);
3181 VOP_UNLOCK(fromnd.ni_dvp, 0, td);
3182 VOP_UNLOCK(fromnd.ni_vp, 0, td);
3186 error = vn_start_write(fvp, &mp, V_WAIT | PCATCH);
3188 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3189 vrele(fromnd.ni_dvp);
3193 NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART |
3194 MPSAFE, pathseg, to, td);
3195 if (fromnd.ni_vp->v_type == VDIR)
3196 tond.ni_cnd.cn_flags |= WILLBEDIR;
3197 if ((error = namei(&tond)) != 0) {
3198 /* Translate error code for rename("dir1", "dir2/."). */
3199 if (error == EISDIR && fvp->v_type == VDIR)
3201 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3202 vrele(fromnd.ni_dvp);
3206 tvfslocked = NDHASGIANT(&tond);
3210 if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
3213 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
3221 * If the source is the same as the destination (that is, if they
3222 * are links to the same vnode), then there is nothing to do.
3228 error = mac_check_vnode_rename_to(td->td_ucred, tdvp,
3229 tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd);
3233 VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE);
3234 if (fromnd.ni_dvp != tdvp) {
3235 VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3238 VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE);
3240 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
3241 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
3242 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3243 NDFREE(&tond, NDF_ONLY_PNBUF);
3245 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3246 NDFREE(&tond, NDF_ONLY_PNBUF);
3253 vrele(fromnd.ni_dvp);
3256 vrele(tond.ni_startdir);
3257 ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename");
3258 ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename");
3259 ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename");
3260 ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename");
3262 vn_finished_write(mp);
3263 if (fromnd.ni_startdir)
3264 vrele(fromnd.ni_startdir);
3265 VFS_UNLOCK_GIANT(fvfslocked);
3266 VFS_UNLOCK_GIANT(tvfslocked);
3273 * Make a directory file.
3275 #ifndef _SYS_SYSPROTO_H_
3284 register struct mkdir_args /* {
3290 return (kern_mkdir(td, uap->path, UIO_USERSPACE, uap->mode));
3294 kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode)
3300 struct nameidata nd;
3305 NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE, segflg, path, td);
3306 nd.ni_cnd.cn_flags |= WILLBEDIR;
3307 if ((error = namei(&nd)) != 0)
3309 vfslocked = NDHASGIANT(&nd);
3312 NDFREE(&nd, NDF_ONLY_PNBUF);
3315 * XXX namei called with LOCKPARENT but not LOCKLEAF has
3316 * the strange behaviour of leaving the vnode unlocked
3317 * if the target is the same vnode as the parent.
3319 if (vp == nd.ni_dvp)
3323 VFS_UNLOCK_GIANT(vfslocked);
3326 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
3327 NDFREE(&nd, NDF_ONLY_PNBUF);
3329 VFS_UNLOCK_GIANT(vfslocked);
3330 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
3335 vattr.va_type = VDIR;
3336 FILEDESC_LOCK_FAST(td->td_proc->p_fd);
3337 vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask;
3338 FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
3340 error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
3345 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3346 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
3350 NDFREE(&nd, NDF_ONLY_PNBUF);
3354 vn_finished_write(mp);
3355 VFS_UNLOCK_GIANT(vfslocked);
3356 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir");
3357 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir");
3362 * Remove a directory file.
3364 #ifndef _SYS_SYSPROTO_H_
3372 struct rmdir_args /* {
3377 return (kern_rmdir(td, uap->path, UIO_USERSPACE));
3381 kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg)
3386 struct nameidata nd;
3391 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE, pathseg, path, td);
3392 if ((error = namei(&nd)) != 0)
3394 vfslocked = NDHASGIANT(&nd);
3396 if (vp->v_type != VDIR) {
3401 * No rmdir "." please.
3403 if (nd.ni_dvp == vp) {
3408 * The root of a mounted filesystem cannot be deleted.
3410 if (vp->v_vflag & VV_ROOT) {
3415 error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp,
3420 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
3421 NDFREE(&nd, NDF_ONLY_PNBUF);
3422 if (nd.ni_dvp == vp)
3427 VFS_UNLOCK_GIANT(vfslocked);
3428 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
3432 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3433 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3434 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
3435 vn_finished_write(mp);
3437 NDFREE(&nd, NDF_ONLY_PNBUF);
3438 if (nd.ni_dvp == vp)
3443 VFS_UNLOCK_GIANT(vfslocked);
3444 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir");
3445 ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir");
3451 * Read a block of directory entries in a filesystem independent format.
3453 #ifndef _SYS_SYSPROTO_H_
3454 struct ogetdirentries_args {
3462 ogetdirentries(td, uap)
3464 register struct ogetdirentries_args /* {
3473 struct uio auio, kuio;
3474 struct iovec aiov, kiov;
3475 struct dirent *dp, *edp;
3477 int error, eofflag, readcnt;
3480 /* XXX arbitrary sanity limit on `count'. */
3481 if (uap->count > 64 * 1024)
3483 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3485 if ((fp->f_flag & FREAD) == 0) {
3491 if (vp->v_type != VDIR) {
3495 aiov.iov_base = uap->buf;
3496 aiov.iov_len = uap->count;
3497 auio.uio_iov = &aiov;
3498 auio.uio_iovcnt = 1;
3499 auio.uio_rw = UIO_READ;
3500 auio.uio_segflg = UIO_USERSPACE;
3502 auio.uio_resid = uap->count;
3503 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3504 loff = auio.uio_offset = fp->f_offset;
3506 error = mac_check_vnode_readdir(td->td_ucred, vp);
3508 VOP_UNLOCK(vp, 0, td);
3513 # if (BYTE_ORDER != LITTLE_ENDIAN)
3514 if (vp->v_mount->mnt_maxsymlinklen <= 0) {
3515 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
3517 fp->f_offset = auio.uio_offset;
3522 kuio.uio_iov = &kiov;
3523 kuio.uio_segflg = UIO_SYSSPACE;
3524 kiov.iov_len = uap->count;
3525 MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK);
3526 kiov.iov_base = dirbuf;
3527 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag,
3529 fp->f_offset = kuio.uio_offset;
3531 readcnt = uap->count - kuio.uio_resid;
3532 edp = (struct dirent *)&dirbuf[readcnt];
3533 for (dp = (struct dirent *)dirbuf; dp < edp; ) {
3534 # if (BYTE_ORDER == LITTLE_ENDIAN)
3536 * The expected low byte of
3537 * dp->d_namlen is our dp->d_type.
3538 * The high MBZ byte of dp->d_namlen
3539 * is our dp->d_namlen.
3541 dp->d_type = dp->d_namlen;
3545 * The dp->d_type is the high byte
3546 * of the expected dp->d_namlen,
3547 * so must be zero'ed.
3551 if (dp->d_reclen > 0) {
3552 dp = (struct dirent *)
3553 ((char *)dp + dp->d_reclen);
3560 error = uiomove(dirbuf, readcnt, &auio);
3562 FREE(dirbuf, M_TEMP);
3564 VOP_UNLOCK(vp, 0, td);
3569 if (uap->count == auio.uio_resid) {
3570 if (union_dircheckp) {
3571 error = union_dircheckp(td, &vp, fp);
3580 * XXX We could delay dropping the lock above but
3581 * union_dircheckp complicates things.
3583 vn_lock(vp, LK_EXCLUSIVE|LK_RETRY, td);
3584 if ((vp->v_vflag & VV_ROOT) &&
3585 (vp->v_mount->mnt_flag & MNT_UNION)) {
3586 struct vnode *tvp = vp;
3587 vp = vp->v_mount->mnt_vnodecovered;
3595 VOP_UNLOCK(vp, 0, td);
3597 error = copyout(&loff, uap->basep, sizeof(long));
3599 td->td_retval[0] = uap->count - auio.uio_resid;
3602 #endif /* COMPAT_43 */
3605 * Read a block of directory entries in a filesystem independent format.
3607 #ifndef _SYS_SYSPROTO_H_
3608 struct getdirentries_args {
3616 getdirentries(td, uap)
3618 register struct getdirentries_args /* {
3633 if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3635 if ((fp->f_flag & FREAD) == 0) {
3641 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
3642 if (vp->v_type != VDIR) {
3646 aiov.iov_base = uap->buf;
3647 aiov.iov_len = uap->count;
3648 auio.uio_iov = &aiov;
3649 auio.uio_iovcnt = 1;
3650 auio.uio_rw = UIO_READ;
3651 auio.uio_segflg = UIO_USERSPACE;
3653 auio.uio_resid = uap->count;
3654 /* vn_lock(vp, LK_SHARED | LK_RETRY, td); */
3655 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3656 loff = auio.uio_offset = fp->f_offset;
3658 error = mac_check_vnode_readdir(td->td_ucred, vp);
3661 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL,
3663 fp->f_offset = auio.uio_offset;
3664 VOP_UNLOCK(vp, 0, td);
3667 if (uap->count == auio.uio_resid) {
3668 if (union_dircheckp) {
3669 error = union_dircheckp(td, &vp, fp);
3671 VFS_UNLOCK_GIANT(vfslocked);
3678 * XXX We could delay dropping the lock above but
3679 * union_dircheckp complicates things.
3681 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3682 if ((vp->v_vflag & VV_ROOT) &&
3683 (vp->v_mount->mnt_flag & MNT_UNION)) {
3684 struct vnode *tvp = vp;
3685 vp = vp->v_mount->mnt_vnodecovered;
3691 VFS_UNLOCK_GIANT(vfslocked);
3694 VOP_UNLOCK(vp, 0, td);
3696 if (uap->basep != NULL) {
3697 error = copyout(&loff, uap->basep, sizeof(long));
3699 td->td_retval[0] = uap->count - auio.uio_resid;
3701 VFS_UNLOCK_GIANT(vfslocked);
3705 #ifndef _SYS_SYSPROTO_H_
3706 struct getdents_args {
3715 register struct getdents_args /* {
3721 struct getdirentries_args ap;
3724 ap.count = uap->count;
3726 return (getdirentries(td, &ap));
3730 * Set the mode mask for creation of filesystem nodes.
3734 #ifndef _SYS_SYSPROTO_H_
3742 struct umask_args /* {
3746 register struct filedesc *fdp;
3748 FILEDESC_LOCK_FAST(td->td_proc->p_fd);
3749 fdp = td->td_proc->p_fd;
3750 td->td_retval[0] = fdp->fd_cmask;
3751 fdp->fd_cmask = uap->newmask & ALLPERMS;
3752 FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
3757 * Void all references to file by ripping underlying filesystem
3760 #ifndef _SYS_SYSPROTO_H_
3761 struct revoke_args {
3768 register struct revoke_args /* {
3775 struct nameidata nd;
3778 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE, UIO_USERSPACE,
3780 if ((error = namei(&nd)) != 0)
3782 vfslocked = NDHASGIANT(&nd);
3784 NDFREE(&nd, NDF_ONLY_PNBUF);
3785 if (vp->v_type != VCHR) {
3790 error = mac_check_vnode_revoke(td->td_ucred, vp);
3794 error = VOP_GETATTR(vp, &vattr, td->td_ucred, td);
3797 if (td->td_ucred->cr_uid != vattr.va_uid) {
3798 error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
3803 VOP_REVOKE(vp, REVOKEALL);
3806 VFS_UNLOCK_GIANT(vfslocked);
3811 * Convert a user file descriptor to a kernel file entry.
3812 * A reference on the file entry is held upon returning.
3815 getvnode(fdp, fd, fpp)
3816 struct filedesc *fdp;
3828 if ((u_int)fd >= fdp->fd_nfiles ||
3829 (fp = fdp->fd_ofiles[fd]) == NULL)
3831 else if (fp->f_vnode == NULL) {
3838 FILEDESC_UNLOCK(fdp);
3845 * Get (NFS) file handle
3847 #ifndef _SYS_SYSPROTO_H_
3848 struct lgetfh_args {
3856 register struct lgetfh_args *uap;
3858 struct nameidata nd;
3860 register struct vnode *vp;
3867 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE,
3868 UIO_USERSPACE, uap->fname, td);
3872 vfslocked = NDHASGIANT(&nd);
3873 NDFREE(&nd, NDF_ONLY_PNBUF);
3875 bzero(&fh, sizeof(fh));
3876 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
3877 error = VFS_VPTOFH(vp, &fh.fh_fid);
3879 VFS_UNLOCK_GIANT(vfslocked);
3882 error = copyout(&fh, uap->fhp, sizeof (fh));
3886 #ifndef _SYS_SYSPROTO_H_
3895 register struct getfh_args *uap;
3897 struct nameidata nd;
3899 register struct vnode *vp;
3906 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE,
3907 UIO_USERSPACE, uap->fname, td);
3911 vfslocked = NDHASGIANT(&nd);
3912 NDFREE(&nd, NDF_ONLY_PNBUF);
3914 bzero(&fh, sizeof(fh));
3915 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
3916 error = VFS_VPTOFH(vp, &fh.fh_fid);
3918 VFS_UNLOCK_GIANT(vfslocked);
3921 error = copyout(&fh, uap->fhp, sizeof (fh));
3926 * syscall for the rpc.lockd to use to translate a NFS file handle into
3927 * an open descriptor.
3929 * warning: do not remove the suser() call or this becomes one giant
3934 #ifndef _SYS_SYSPROTO_H_
3935 struct fhopen_args {
3936 const struct fhandle *u_fhp;
3943 struct fhopen_args /* {
3944 const struct fhandle *u_fhp;
3948 struct proc *p = td->td_proc;
3953 struct vattr *vap = &vat;
3956 register struct filedesc *fdp = p->p_fd;
3957 int fmode, mode, error, type;
3964 fmode = FFLAGS(uap->flags);
3965 /* why not allow a non-read/write open for our lockd? */
3966 if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT))
3968 error = copyin(uap->u_fhp, &fhp, sizeof(fhp));
3971 /* find the mount point */
3973 mp = vfs_getvfs(&fhp.fh_fsid);
3978 /* now give me my vnode, it gets returned to me locked */
3979 error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp);
3983 * from now on we have to make sure not
3984 * to forget about the vnode
3985 * any error that causes an abort must vput(vp)
3986 * just set error = err and 'goto bad;'.
3992 if (vp->v_type == VLNK) {
3996 if (vp->v_type == VSOCK) {
4001 if (fmode & (FWRITE | O_TRUNC)) {
4002 if (vp->v_type == VDIR) {
4006 error = vn_writechk(vp);
4013 if (fmode & O_APPEND)
4016 error = mac_check_vnode_open(td->td_ucred, vp, mode);
4021 error = VOP_ACCESS(vp, mode, td->td_ucred, td);
4025 if (fmode & O_TRUNC) {
4026 VOP_UNLOCK(vp, 0, td); /* XXX */
4027 if ((error = vn_start_write(NULL, &mp, V_WAIT | PCATCH)) != 0) {
4031 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4032 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); /* XXX */
4035 * We don't yet have fp->f_cred, so use td->td_ucred, which
4038 error = mac_check_vnode_write(td->td_ucred, td->td_ucred, vp);
4043 error = VOP_SETATTR(vp, vap, td->td_ucred, td);
4047 vn_finished_write(mp);
4051 error = VOP_OPEN(vp, fmode, td->td_ucred, td, -1);
4059 * end of vn_open code
4062 if ((error = falloc(td, &nfp, &indx)) != 0) {
4067 /* An extra reference on `nfp' has been held for us by falloc(). */
4072 nfp->f_flag = fmode & FMASK;
4073 nfp->f_ops = &vnops;
4074 nfp->f_type = DTYPE_VNODE;
4075 if (fmode & (O_EXLOCK | O_SHLOCK)) {
4076 lf.l_whence = SEEK_SET;
4079 if (fmode & O_EXLOCK)
4080 lf.l_type = F_WRLCK;
4082 lf.l_type = F_RDLCK;
4084 if ((fmode & FNONBLOCK) == 0)
4086 VOP_UNLOCK(vp, 0, td);
4087 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf,
4090 * The lock request failed. Normally close the
4091 * descriptor but handle the case where someone might
4092 * have dup()d or close()d it when we weren't looking.
4094 fdclose(fdp, fp, indx, td);
4097 * release our private reference
4102 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4103 fp->f_flag |= FHASLOCK;
4106 VOP_UNLOCK(vp, 0, td);
4109 td->td_retval[0] = indx;
4120 * Stat an (NFS) file handle.
4124 #ifndef _SYS_SYSPROTO_H_
4125 struct fhstat_args {
4126 struct fhandle *u_fhp;
4133 register struct fhstat_args /* {
4134 struct fhandle *u_fhp;
4147 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
4151 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) {
4155 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) {
4159 error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
4164 error = copyout(&sb, uap->sb, sizeof(sb));
4169 * Implement fstatfs() for (NFS) file handles.
4173 #ifndef _SYS_SYSPROTO_H_
4174 struct fhstatfs_args {
4175 struct fhandle *u_fhp;
4182 struct fhstatfs_args /* {
4183 struct fhandle *u_fhp;
4191 error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
4194 error = kern_fhstatfs(td, fh, &sf);
4197 return (copyout(&sf, uap->buf, sizeof(sf)));
4201 kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf)
4212 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) {
4216 error = VFS_FHTOVP(mp, &fh.fh_fid, &vp);
4225 error = mac_check_mount_stat(td->td_ucred, mp);
4232 * Set these in case the underlying filesystem fails to do so.
4234 sp->f_version = STATFS_VERSION;
4235 sp->f_namemax = NAME_MAX;
4236 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
4237 error = VFS_STATFS(mp, sp, td);
4246 * Syscall to push extended attribute configuration information into the
4247 * VFS. Accepts a path, which it converts to a mountpoint, as well as
4248 * a command (int cmd), and attribute name and misc data. For now, the
4249 * attribute name is left in userspace for consumption by the VFS_op.
4250 * It will probably be changed to be copied into sysspace by the
4251 * syscall in the future, once issues with various consumers of the
4252 * attribute code have raised their hands.
4254 * Currently this is used only by UFS Extended Attributes.
4259 struct extattrctl_args /* {
4262 const char *filename;
4264 const char *attrname;
4267 struct vnode *filename_vp;
4268 struct nameidata nd;
4269 struct mount *mp, *mp_writable;
4270 char attrname[EXTATTR_MAXNAMELEN];
4274 * uap->attrname is not always defined. We check again later when we
4275 * invoke the VFS call so as to pass in NULL there if needed.
4277 if (uap->attrname != NULL) {
4278 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN,
4285 * uap->filename is not always defined. If it is, grab a vnode lock,
4286 * which VFS_EXTATTRCTL() will later release.
4289 if (uap->filename != NULL) {
4290 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
4295 filename_vp = nd.ni_vp;
4296 NDFREE(&nd, NDF_NO_VP_RELE | NDF_NO_VP_UNLOCK);
4299 /* uap->path is always defined. */
4300 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
4303 if (filename_vp != NULL)
4307 mp = nd.ni_vp->v_mount;
4308 error = vn_start_write(nd.ni_vp, &mp_writable, V_WAIT | PCATCH);
4311 if (filename_vp != NULL)
4316 error = VFS_EXTATTRCTL(mp, uap->cmd, filename_vp, uap->attrnamespace,
4317 uap->attrname != NULL ? attrname : NULL, td);
4319 vn_finished_write(mp_writable);
4321 * VFS_EXTATTRCTL will have unlocked, but not de-ref'd,
4322 * filename_vp, so vrele it if it is defined.
4324 if (filename_vp != NULL)
4330 * Set a named extended attribute on a file or directory
4332 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4333 * kernelspace string pointer "attrname", userspace buffer
4334 * pointer "data", buffer length "nbytes", thread "td".
4335 * Returns: 0 on success, an error number otherwise
4337 * References: vp must be a valid reference for the duration of the call
4340 extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4341 void *data, size_t nbytes, struct thread *td)
4349 error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
4352 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4353 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4355 aiov.iov_base = data;
4356 aiov.iov_len = nbytes;
4357 auio.uio_iov = &aiov;
4358 auio.uio_iovcnt = 1;
4359 auio.uio_offset = 0;
4360 if (nbytes > INT_MAX) {
4364 auio.uio_resid = nbytes;
4365 auio.uio_rw = UIO_WRITE;
4366 auio.uio_segflg = UIO_USERSPACE;
4371 error = mac_check_vnode_setextattr(td->td_ucred, vp, attrnamespace,
4377 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio,
4379 cnt -= auio.uio_resid;
4380 td->td_retval[0] = cnt;
4383 VOP_UNLOCK(vp, 0, td);
4384 vn_finished_write(mp);
4389 extattr_set_fd(td, uap)
4391 struct extattr_set_fd_args /* {
4394 const char *attrname;
4400 char attrname[EXTATTR_MAXNAMELEN];
4403 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4407 error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
4411 error = extattr_set_vp(fp->f_vnode, uap->attrnamespace,
4412 attrname, uap->data, uap->nbytes, td);
4419 extattr_set_file(td, uap)
4421 struct extattr_set_file_args /* {
4424 const char *attrname;
4429 struct nameidata nd;
4430 char attrname[EXTATTR_MAXNAMELEN];
4433 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4437 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
4441 NDFREE(&nd, NDF_ONLY_PNBUF);
4443 error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname,
4444 uap->data, uap->nbytes, td);
4451 extattr_set_link(td, uap)
4453 struct extattr_set_link_args /* {
4456 const char *attrname;
4461 struct nameidata nd;
4462 char attrname[EXTATTR_MAXNAMELEN];
4465 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4469 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
4473 NDFREE(&nd, NDF_ONLY_PNBUF);
4475 error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname,
4476 uap->data, uap->nbytes, td);
4483 * Get a named extended attribute on a file or directory
4485 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4486 * kernelspace string pointer "attrname", userspace buffer
4487 * pointer "data", buffer length "nbytes", thread "td".
4488 * Returns: 0 on success, an error number otherwise
4490 * References: vp must be a valid reference for the duration of the call
4493 extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4494 void *data, size_t nbytes, struct thread *td)
4496 struct uio auio, *auiop;
4499 size_t size, *sizep;
4502 VOP_LEASE(vp, td, td->td_ucred, LEASE_READ);
4503 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4506 * Slightly unusual semantics: if the user provides a NULL data
4507 * pointer, they don't want to receive the data, just the
4508 * maximum read length.
4514 aiov.iov_base = data;
4515 aiov.iov_len = nbytes;
4516 auio.uio_iov = &aiov;
4517 auio.uio_iovcnt = 1;
4518 auio.uio_offset = 0;
4519 if (nbytes > INT_MAX) {
4523 auio.uio_resid = nbytes;
4524 auio.uio_rw = UIO_READ;
4525 auio.uio_segflg = UIO_USERSPACE;
4533 error = mac_check_vnode_getextattr(td->td_ucred, vp, attrnamespace,
4539 error = VOP_GETEXTATTR(vp, attrnamespace, attrname, auiop, sizep,
4542 if (auiop != NULL) {
4543 cnt -= auio.uio_resid;
4544 td->td_retval[0] = cnt;
4546 td->td_retval[0] = size;
4549 VOP_UNLOCK(vp, 0, td);
4554 extattr_get_fd(td, uap)
4556 struct extattr_get_fd_args /* {
4559 const char *attrname;
4565 char attrname[EXTATTR_MAXNAMELEN];
4568 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4572 error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
4576 error = extattr_get_vp(fp->f_vnode, uap->attrnamespace,
4577 attrname, uap->data, uap->nbytes, td);
4584 extattr_get_file(td, uap)
4586 struct extattr_get_file_args /* {
4589 const char *attrname;
4594 struct nameidata nd;
4595 char attrname[EXTATTR_MAXNAMELEN];
4598 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4602 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
4606 NDFREE(&nd, NDF_ONLY_PNBUF);
4608 error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname,
4609 uap->data, uap->nbytes, td);
4616 extattr_get_link(td, uap)
4618 struct extattr_get_link_args /* {
4621 const char *attrname;
4626 struct nameidata nd;
4627 char attrname[EXTATTR_MAXNAMELEN];
4630 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4634 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
4638 NDFREE(&nd, NDF_ONLY_PNBUF);
4640 error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname,
4641 uap->data, uap->nbytes, td);
4648 * extattr_delete_vp(): Delete a named extended attribute on a file or
4651 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4652 * kernelspace string pointer "attrname", proc "p"
4653 * Returns: 0 on success, an error number otherwise
4655 * References: vp must be a valid reference for the duration of the call
4658 extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4664 error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
4667 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4668 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4671 error = mac_check_vnode_deleteextattr(td->td_ucred, vp, attrnamespace,
4677 error = VOP_DELETEEXTATTR(vp, attrnamespace, attrname, td->td_ucred,
4679 if (error == EOPNOTSUPP)
4680 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL,
4685 VOP_UNLOCK(vp, 0, td);
4686 vn_finished_write(mp);
4691 extattr_delete_fd(td, uap)
4693 struct extattr_delete_fd_args /* {
4696 const char *attrname;
4701 char attrname[EXTATTR_MAXNAMELEN];
4704 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4708 error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
4713 error = extattr_delete_vp(vp, uap->attrnamespace, attrname, td);
4719 extattr_delete_file(td, uap)
4721 struct extattr_delete_file_args /* {
4724 const char *attrname;
4727 struct nameidata nd;
4728 char attrname[EXTATTR_MAXNAMELEN];
4731 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4735 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
4739 NDFREE(&nd, NDF_ONLY_PNBUF);
4741 error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td);
4747 extattr_delete_link(td, uap)
4749 struct extattr_delete_link_args /* {
4752 const char *attrname;
4755 struct nameidata nd;
4756 char attrname[EXTATTR_MAXNAMELEN];
4759 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4763 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
4767 NDFREE(&nd, NDF_ONLY_PNBUF);
4769 error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td);
4775 * Retrieve a list of extended attributes on a file or directory.
4777 * Arguments: unlocked vnode "vp", attribute namespace 'attrnamespace",
4778 * userspace buffer pointer "data", buffer length "nbytes",
4780 * Returns: 0 on success, an error number otherwise
4782 * References: vp must be a valid reference for the duration of the call
4785 extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
4786 size_t nbytes, struct thread *td)
4788 struct uio auio, *auiop;
4789 size_t size, *sizep;
4794 VOP_LEASE(vp, td, td->td_ucred, LEASE_READ);
4795 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4801 aiov.iov_base = data;
4802 aiov.iov_len = nbytes;
4803 auio.uio_iov = &aiov;
4804 auio.uio_iovcnt = 1;
4805 auio.uio_offset = 0;
4806 if (nbytes > INT_MAX) {
4810 auio.uio_resid = nbytes;
4811 auio.uio_rw = UIO_READ;
4812 auio.uio_segflg = UIO_USERSPACE;
4820 error = mac_check_vnode_listextattr(td->td_ucred, vp, attrnamespace);
4825 error = VOP_LISTEXTATTR(vp, attrnamespace, auiop, sizep,
4828 if (auiop != NULL) {
4829 cnt -= auio.uio_resid;
4830 td->td_retval[0] = cnt;
4832 td->td_retval[0] = size;
4835 VOP_UNLOCK(vp, 0, td);
4841 extattr_list_fd(td, uap)
4843 struct extattr_list_fd_args /* {
4853 error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
4857 error = extattr_list_vp(fp->f_vnode, uap->attrnamespace, uap->data,
4865 extattr_list_file(td, uap)
4867 struct extattr_list_file_args /* {
4874 struct nameidata nd;
4877 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
4881 NDFREE(&nd, NDF_ONLY_PNBUF);
4883 error = extattr_list_vp(nd.ni_vp, uap->attrnamespace, uap->data,
4891 extattr_list_link(td, uap)
4893 struct extattr_list_link_args /* {
4900 struct nameidata nd;
4903 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
4907 NDFREE(&nd, NDF_ONLY_PNBUF);
4909 error = extattr_list_vp(nd.ni_vp, uap->attrnamespace, uap->data,