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 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
42 /* For 4.3 integer FS ID compatibility */
43 #include "opt_compat.h"
46 #include <sys/param.h>
47 #include <sys/systm.h>
50 #include <sys/sysent.h>
51 #include <sys/malloc.h>
52 #include <sys/mount.h>
53 #include <sys/mutex.h>
54 #include <sys/sysproto.h>
55 #include <sys/namei.h>
56 #include <sys/filedesc.h>
57 #include <sys/kernel.h>
58 #include <sys/fcntl.h>
60 #include <sys/linker.h>
63 #include <sys/unistd.h>
64 #include <sys/vnode.h>
66 #include <sys/dirent.h>
67 #include <sys/extattr.h>
69 #include <sys/sysctl.h>
71 #include <machine/limits.h>
72 #include <machine/stdarg.h>
75 #include <vm/vm_object.h>
76 #include <vm/vm_page.h>
79 static int change_dir(struct nameidata *ndp, struct thread *td);
80 static void checkdirs(struct vnode *olddp, struct vnode *newdp);
81 static int chroot_refuse_vdir_fds(struct filedesc *fdp);
82 static int getutimes(const struct timeval *, struct timespec *);
83 static int setfown(struct thread *td, struct vnode *, uid_t, gid_t);
84 static int setfmode(struct thread *td, struct vnode *, int);
85 static int setfflags(struct thread *td, struct vnode *, int);
86 static int setutimes(struct thread *td, struct vnode *,
87 const struct timespec *, int);
88 static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred,
90 static void vfs_freeopts(struct vfsoptlist *opt);
91 static int vfs_nmount(struct thread *td, int, struct uio *);
93 static int usermount = 0; /* if 1, non-root can mount fs. */
95 int (*union_dircheckp)(struct thread *td, struct vnode **, struct file *);
97 SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, "");
100 * Virtual File System System Calls
103 #ifndef _SYS_SYSPROTO_H_
114 struct nmount_args /* {
115 syscallarg(struct iovec *) iovp;
116 syscallarg(unsigned int) iovcnt;
117 syscallarg(int) flags;
121 struct iovec *iov, *needfree;
122 struct iovec aiov[UIO_SMALLIOV];
124 u_int iovlen, iovcnt;
126 iovcnt = SCARG(uap, iovcnt);
127 iovlen = iovcnt * sizeof (struct iovec);
129 * Check that we have an even number of iovec's
130 * and that we have at least two options.
132 if ((iovcnt & 1) || (iovcnt < 4) || (iovcnt > UIO_MAXIOV))
135 if (iovcnt > UIO_SMALLIOV) {
136 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
143 auio.uio_iovcnt = iovcnt;
144 auio.uio_rw = UIO_WRITE;
145 auio.uio_segflg = UIO_USERSPACE;
149 if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen)))
151 for (i = 0; i < iovcnt; i++) {
152 if (iov->iov_len > INT_MAX - auio.uio_resid) {
156 auio.uio_resid += iov->iov_len;
159 error = vfs_nmount(td, SCARG(uap, flags), &auio);
161 if (needfree != NULL)
162 free(needfree, M_TEMP);
167 * Release all resources related to the
171 vfs_freeopts(struct vfsoptlist *opt)
173 free(opt->opt, M_MOUNT);
174 free(opt->optbuf, M_MOUNT);
179 kernel_mount(iovp, iovcnt, flags)
189 * Check that we have an even number of iovec's
190 * and that we have at least two options.
192 if ((iovcnt & 1) || (iovcnt < 4))
196 auio.uio_iovcnt = iovcnt;
197 auio.uio_rw = UIO_WRITE;
198 auio.uio_segflg = UIO_SYSSPACE;
203 for (i = 0; i < iovcnt; i++) {
204 if (iov->iov_len > INT_MAX - auio.uio_resid) {
207 auio.uio_resid += iov->iov_len;
211 error = vfs_nmount(curthread, flags, &auio);
216 kernel_vmount(int flags, ...)
221 unsigned int iovcnt, iovlen, len;
229 for (iovcnt = 0; (cp = va_arg(ap, const char *)) != NULL; iovcnt++)
230 len += strlen(cp) + 1;
233 if (iovcnt < 4 || iovcnt & 1)
236 iovlen = iovcnt * sizeof (struct iovec);
237 MALLOC(iovp, struct iovec *, iovlen, M_MOUNT, M_WAITOK);
238 MALLOC(buf, char *, len, M_MOUNT, M_WAITOK);
241 for (i = 0; i < iovcnt; i++) {
242 cp = va_arg(ap, const char *);
243 copystr(cp, pos, len - (pos - buf), &n);
244 iovp[i].iov_base = pos;
251 auio.uio_iovcnt = iovcnt;
252 auio.uio_rw = UIO_WRITE;
253 auio.uio_segflg = UIO_SYSSPACE;
256 auio.uio_resid = len;
258 error = vfs_nmount(curthread, flags, &auio);
265 * vfs_nmount(): actually attempt a filesystem mount.
268 vfs_nmount(td, fsflags, fsoptions)
270 int fsflags; /* Flags common to all filesystems. */
271 struct uio *fsoptions; /* Options local to the filesystem. */
276 struct vfsconf *vfsp;
278 struct vfsoptlist *optlist;
280 char *buf, *fstype, *fspath;
281 int error, flag = 0, kern_flag = 0, i, len, optcnt;
282 int offset, iovcnt, fstypelen, fspathlen;
287 * Allocate memory to hold the vfsopt structures.
289 iovcnt = fsoptions->uio_iovcnt;
290 optcnt = iovcnt >> 1;
291 opt = malloc(sizeof (struct vfsopt) * optcnt,
292 M_MOUNT, M_WAITOK | M_ZERO);
295 * Count the size of the buffer for options,
296 * allocate it, and fill in the vfsopt structures.
298 cur = fsoptions->uio_iov;
299 len = fsoptions->uio_resid;
300 buf = malloc(len, M_TEMP, M_WAITOK | M_ZERO);
302 optlist = malloc(sizeof (struct vfsoptlist), M_MOUNT, M_WAITOK);
304 optlist->optbuf = buf;
305 optlist->optcnt = optcnt;
308 cur = fsoptions->uio_iov;
310 opt[i].name = buf + offset;
311 /* Ensure the name of an option is a string. */
312 if (opt[i].name[cur->iov_len - 1] != '\0') {
316 offset += cur->iov_len;
318 opt[i].len = cur->iov_len;
320 * Prevent consumers from trying to
321 * read the value of a 0 length option
322 * by setting it to NULL.
327 opt[i].value = buf + offset;
328 offset += cur->iov_len;
332 if ((error = uiomove(buf, len, fsoptions)) != 0)
336 * We need these two options before the others,
337 * and they are mandatory for any filesystem.
338 * Ensure they are NULL terminated as well.
341 error = vfs_getopt(optlist, "fstype", (void **)&fstype, &fstypelen);
342 if (error || fstype[fstypelen - 1] != '\0') {
347 error = vfs_getopt(optlist, "fspath", (void **)&fspath, &fspathlen);
348 if (error || fspath[fspathlen - 1] != '\0') {
354 * Be ultra-paranoid about making sure the type and fspath
355 * variables will fit in our mp buffers, including the
358 if (fstypelen >= MFSNAMELEN - 1 || fspathlen >= MNAMELEN - 1) {
359 error = ENAMETOOLONG;
363 if (usermount == 0) {
369 * Do not allow NFS export by non-root users.
371 if (fsflags & MNT_EXPORTED) {
377 * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users.
380 fsflags |= MNT_NOSUID | MNT_NODEV;
382 * Get vnode to be covered
384 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath, td);
385 if ((error = namei(&nd)) != 0)
387 NDFREE(&nd, NDF_ONLY_PNBUF);
389 if (fsflags & MNT_UPDATE) {
390 if ((vp->v_flag & VROOT) == 0) {
397 kern_flag = mp->mnt_kern_flag;
399 * We only allow the filesystem to be reloaded if it
400 * is currently mounted read-only.
402 if ((fsflags & MNT_RELOAD) &&
403 ((mp->mnt_flag & MNT_RDONLY) == 0)) {
405 error = EOPNOTSUPP; /* Needs translation */
409 * Only root, or the user that did the original mount is
410 * permitted to update it.
412 if (mp->mnt_stat.f_owner != td->td_ucred->cr_uid) {
419 if (vfs_busy(mp, LK_NOWAIT, 0, td)) {
424 mtx_lock(&vp->v_interlock);
425 if ((vp->v_flag & VMOUNT) != 0 || vp->v_mountedhere != NULL) {
426 mtx_unlock(&vp->v_interlock);
432 vp->v_flag |= VMOUNT;
433 mtx_unlock(&vp->v_interlock);
434 mp->mnt_flag |= fsflags &
435 (MNT_RELOAD | MNT_FORCE | MNT_UPDATE | MNT_SNAPSHOT);
436 VOP_UNLOCK(vp, 0, td);
437 mp->mnt_optnew = optlist;
441 * If the user is not root, ensure that they own the directory
442 * onto which we are attempting to mount.
444 error = VOP_GETATTR(vp, &va, td->td_ucred, td);
449 if (va.va_uid != td->td_ucred->cr_uid) {
456 if ((error = vinvalbuf(vp, V_SAVE, td->td_ucred, td, 0, 0)) != 0) {
460 if (vp->v_type != VDIR) {
465 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
466 if (!strcmp(vfsp->vfc_name, fstype))
469 /* Only load modules for root (very important!). */
475 error = securelevel_gt(td->td_ucred, 0);
480 error = linker_load_file(fstype, &lf);
481 if (error || lf == NULL) {
488 /* Look up again to see if the VFS was loaded. */
489 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
490 if (!strcmp(vfsp->vfc_name, fstype))
494 linker_file_unload(lf);
500 mtx_lock(&vp->v_interlock);
501 if ((vp->v_flag & VMOUNT) != 0 ||
502 vp->v_mountedhere != NULL) {
503 mtx_unlock(&vp->v_interlock);
508 vp->v_flag |= VMOUNT;
509 mtx_unlock(&vp->v_interlock);
512 * Allocate and initialize the filesystem.
514 mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK | M_ZERO);
515 TAILQ_INIT(&mp->mnt_nvnodelist);
516 TAILQ_INIT(&mp->mnt_reservedvnlist);
517 lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE);
518 (void)vfs_busy(mp, LK_NOWAIT, 0, td);
519 mp->mnt_op = vfsp->vfc_vfsops;
521 vfsp->vfc_refcount++;
522 mp->mnt_stat.f_type = vfsp->vfc_typenum;
523 mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
524 strncpy(mp->mnt_stat.f_fstypename, fstype, MFSNAMELEN);
525 mp->mnt_vnodecovered = vp;
526 mp->mnt_stat.f_owner = td->td_ucred->cr_uid;
527 strncpy(mp->mnt_stat.f_mntonname, fspath, MNAMELEN);
528 mp->mnt_iosize_max = DFLTPHYS;
529 VOP_UNLOCK(vp, 0, td);
531 mp->mnt_opt = optlist;
534 * Check if the fs implements the new VFS_NMOUNT()
535 * function, since the new system call was used.
537 if (mp->mnt_op->vfs_mount != NULL) {
538 printf("%s doesn't support the new mount syscall\n",
539 mp->mnt_vfc->vfc_name);
540 mtx_lock(&vp->v_interlock);
541 vp->v_flag &= ~VMOUNT;
542 mtx_unlock(&vp->v_interlock);
543 if (mp->mnt_flag & MNT_UPDATE)
546 mp->mnt_vfc->vfc_refcount--;
548 free((caddr_t)mp, M_MOUNT);
556 * Set the mount level flags.
558 if (fsflags & MNT_RDONLY)
559 mp->mnt_flag |= MNT_RDONLY;
560 else if (mp->mnt_flag & MNT_RDONLY)
561 mp->mnt_kern_flag |= MNTK_WANTRDWR;
562 mp->mnt_flag &=~ MNT_UPDATEMASK;
563 mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE);
565 * Mount the filesystem.
566 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
567 * get. No freeing of cn_pnbuf.
569 error = VFS_NMOUNT(mp, &nd, td);
570 if (mp->mnt_flag & MNT_UPDATE) {
571 if (mp->mnt_kern_flag & MNTK_WANTRDWR)
572 mp->mnt_flag &= ~MNT_RDONLY;
574 (MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_SNAPSHOT);
575 mp->mnt_kern_flag &=~ MNTK_WANTRDWR;
578 mp->mnt_kern_flag = kern_flag;
579 vfs_freeopts(mp->mnt_optnew);
581 vfs_freeopts(mp->mnt_opt);
582 mp->mnt_opt = mp->mnt_optnew;
584 if ((mp->mnt_flag & MNT_RDONLY) == 0) {
585 if (mp->mnt_syncer == NULL)
586 error = vfs_allocate_syncvnode(mp);
588 if (mp->mnt_syncer != NULL)
589 vrele(mp->mnt_syncer);
590 mp->mnt_syncer = NULL;
593 mtx_lock(&vp->v_interlock);
594 vp->v_flag &= ~VMOUNT;
595 mtx_unlock(&vp->v_interlock);
599 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
601 * Put the new filesystem on the mount list after root.
607 mtx_lock(&vp->v_interlock);
608 vp->v_flag &= ~VMOUNT;
609 vp->v_mountedhere = mp;
610 mtx_unlock(&vp->v_interlock);
611 mtx_lock(&mountlist_mtx);
612 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
613 mtx_unlock(&mountlist_mtx);
614 if (VFS_ROOT(mp, &newdp))
615 panic("mount: lost mount");
616 checkdirs(vp, newdp);
618 VOP_UNLOCK(vp, 0, td);
619 if ((mp->mnt_flag & MNT_RDONLY) == 0)
620 error = vfs_allocate_syncvnode(mp);
622 if ((error = VFS_START(mp, 0, td)) != 0) {
627 mtx_lock(&vp->v_interlock);
628 vp->v_flag &= ~VMOUNT;
629 mtx_unlock(&vp->v_interlock);
630 mp->mnt_vfc->vfc_refcount--;
632 free((caddr_t)mp, M_MOUNT);
638 vfs_freeopts(optlist);
645 #ifndef _SYS_SYSPROTO_H_
657 struct mount_args /* {
658 syscallarg(char *) type;
659 syscallarg(char *) path;
660 syscallarg(int) flags;
661 syscallarg(caddr_t) data;
668 fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK);
669 fspath = malloc(MNAMELEN, M_TEMP, M_WAITOK);
672 * vfs_mount() actually takes a kernel string for `type' and
673 * `path' now, so extract them.
675 error = copyinstr(SCARG(uap, type), fstype, MFSNAMELEN, NULL);
678 error = copyinstr(SCARG(uap, path), fspath, MNAMELEN, NULL);
681 error = vfs_mount(td, fstype, fspath, SCARG(uap, flags),
684 free(fstype, M_TEMP);
685 free(fspath, M_TEMP);
690 * vfs_mount(): actually attempt a filesystem mount.
692 * This routine is designed to be a "generic" entry point for routines
693 * that wish to mount a filesystem. All parameters except `fsdata' are
694 * pointers into kernel space. `fsdata' is currently still a pointer
698 vfs_mount(td, fstype, fspath, fsflags, fsdata)
708 struct vfsconf *vfsp;
709 int error, flag = 0, kern_flag = 0;
714 * Be ultra-paranoid about making sure the type and fspath
715 * variables will fit in our mp buffers, including the
718 if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN)
719 return (ENAMETOOLONG);
721 if (usermount == 0) {
727 * Do not allow NFS export by non-root users.
729 if (fsflags & MNT_EXPORTED) {
735 * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users.
738 fsflags |= MNT_NOSUID | MNT_NODEV;
740 * Get vnode to be covered
742 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath, td);
743 if ((error = namei(&nd)) != 0)
745 NDFREE(&nd, NDF_ONLY_PNBUF);
747 if (fsflags & MNT_UPDATE) {
748 if ((vp->v_flag & VROOT) == 0) {
754 kern_flag = mp->mnt_kern_flag;
756 * We only allow the filesystem to be reloaded if it
757 * is currently mounted read-only.
759 if ((fsflags & MNT_RELOAD) &&
760 ((mp->mnt_flag & MNT_RDONLY) == 0)) {
762 return (EOPNOTSUPP); /* Needs translation */
765 * Only root, or the user that did the original mount is
766 * permitted to update it.
768 if (mp->mnt_stat.f_owner != td->td_ucred->cr_uid) {
775 if (vfs_busy(mp, LK_NOWAIT, 0, td)) {
779 mtx_lock(&vp->v_interlock);
780 if ((vp->v_flag & VMOUNT) != 0 || vp->v_mountedhere != NULL) {
781 mtx_unlock(&vp->v_interlock);
786 vp->v_flag |= VMOUNT;
787 mtx_unlock(&vp->v_interlock);
788 mp->mnt_flag |= fsflags &
789 (MNT_RELOAD | MNT_FORCE | MNT_UPDATE | MNT_SNAPSHOT);
790 VOP_UNLOCK(vp, 0, td);
794 * If the user is not root, ensure that they own the directory
795 * onto which we are attempting to mount.
797 error = VOP_GETATTR(vp, &va, td->td_ucred, td);
802 if (va.va_uid != td->td_ucred->cr_uid) {
809 if ((error = vinvalbuf(vp, V_SAVE, td->td_ucred, td, 0, 0)) != 0) {
813 if (vp->v_type != VDIR) {
817 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
818 if (!strcmp(vfsp->vfc_name, fstype))
821 /* Only load modules for root (very important!). */
827 error = securelevel_gt(td->td_ucred, 0);
832 error = linker_load_file(fstype, &lf);
833 if (error || lf == NULL) {
840 /* Look up again to see if the VFS was loaded. */
841 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
842 if (!strcmp(vfsp->vfc_name, fstype))
846 linker_file_unload(lf);
851 mtx_lock(&vp->v_interlock);
852 if ((vp->v_flag & VMOUNT) != 0 ||
853 vp->v_mountedhere != NULL) {
854 mtx_unlock(&vp->v_interlock);
858 vp->v_flag |= VMOUNT;
859 mtx_unlock(&vp->v_interlock);
862 * Allocate and initialize the filesystem.
864 mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK | M_ZERO);
865 TAILQ_INIT(&mp->mnt_nvnodelist);
866 TAILQ_INIT(&mp->mnt_reservedvnlist);
867 lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE);
868 (void)vfs_busy(mp, LK_NOWAIT, 0, td);
869 mp->mnt_op = vfsp->vfc_vfsops;
871 vfsp->vfc_refcount++;
872 mp->mnt_stat.f_type = vfsp->vfc_typenum;
873 mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
874 strncpy(mp->mnt_stat.f_fstypename, fstype, MFSNAMELEN);
875 mp->mnt_vnodecovered = vp;
876 mp->mnt_stat.f_owner = td->td_ucred->cr_uid;
877 strncpy(mp->mnt_stat.f_mntonname, fspath, MNAMELEN);
878 mp->mnt_iosize_max = DFLTPHYS;
879 VOP_UNLOCK(vp, 0, td);
882 * Check if the fs implements the old VFS_MOUNT()
883 * function, since the old system call was used.
885 if (mp->mnt_op->vfs_mount == NULL) {
886 printf("%s doesn't support the old mount syscall\n",
887 mp->mnt_vfc->vfc_name);
888 mtx_lock(&vp->v_interlock);
889 vp->v_flag &= ~VMOUNT;
890 mtx_unlock(&vp->v_interlock);
891 if (mp->mnt_flag & MNT_UPDATE)
894 mp->mnt_vfc->vfc_refcount--;
896 free((caddr_t)mp, M_MOUNT);
903 * Set the mount level flags.
905 if (fsflags & MNT_RDONLY)
906 mp->mnt_flag |= MNT_RDONLY;
907 else if (mp->mnt_flag & MNT_RDONLY)
908 mp->mnt_kern_flag |= MNTK_WANTRDWR;
909 mp->mnt_flag &=~ MNT_UPDATEMASK;
910 mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE);
912 * Mount the filesystem.
913 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
914 * get. No freeing of cn_pnbuf.
916 error = VFS_MOUNT(mp, fspath, fsdata, &nd, td);
917 if (mp->mnt_flag & MNT_UPDATE) {
918 if (mp->mnt_kern_flag & MNTK_WANTRDWR)
919 mp->mnt_flag &= ~MNT_RDONLY;
921 (MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_SNAPSHOT);
922 mp->mnt_kern_flag &=~ MNTK_WANTRDWR;
925 mp->mnt_kern_flag = kern_flag;
927 if ((mp->mnt_flag & MNT_RDONLY) == 0) {
928 if (mp->mnt_syncer == NULL)
929 error = vfs_allocate_syncvnode(mp);
931 if (mp->mnt_syncer != NULL)
932 vrele(mp->mnt_syncer);
933 mp->mnt_syncer = NULL;
936 mtx_lock(&vp->v_interlock);
937 vp->v_flag &= ~VMOUNT;
938 mtx_unlock(&vp->v_interlock);
942 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
944 * Put the new filesystem on the mount list after root.
950 mtx_lock(&vp->v_interlock);
951 vp->v_flag &= ~VMOUNT;
952 vp->v_mountedhere = mp;
953 mtx_unlock(&vp->v_interlock);
954 mtx_lock(&mountlist_mtx);
955 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
956 mtx_unlock(&mountlist_mtx);
957 if (VFS_ROOT(mp, &newdp))
958 panic("mount: lost mount");
959 checkdirs(vp, newdp);
961 VOP_UNLOCK(vp, 0, td);
962 if ((mp->mnt_flag & MNT_RDONLY) == 0)
963 error = vfs_allocate_syncvnode(mp);
965 if ((error = VFS_START(mp, 0, td)) != 0)
968 mtx_lock(&vp->v_interlock);
969 vp->v_flag &= ~VMOUNT;
970 mtx_unlock(&vp->v_interlock);
971 mp->mnt_vfc->vfc_refcount--;
973 free((caddr_t)mp, M_MOUNT);
980 * Scan all active processes to see if any of them have a current
981 * or root directory of `olddp'. If so, replace them with the new
985 checkdirs(olddp, newdp)
986 struct vnode *olddp, *newdp;
988 struct filedesc *fdp;
992 if (olddp->v_usecount == 1)
994 sx_slock(&allproc_lock);
995 LIST_FOREACH(p, &allproc, p_list) {
1004 if (fdp->fd_cdir == olddp) {
1006 fdp->fd_cdir = newdp;
1009 if (fdp->fd_rdir == olddp) {
1011 fdp->fd_rdir = newdp;
1014 FILEDESC_UNLOCK(fdp);
1019 sx_sunlock(&allproc_lock);
1020 if (rootvnode == olddp) {
1028 * Unmount a file system.
1030 * Note: unmount takes a path to the vnode mounted on as argument,
1031 * not special file (as before).
1033 #ifndef _SYS_SYSPROTO_H_
1034 struct unmount_args {
1043 register struct unmount_args /* {
1044 syscallarg(char *) path;
1045 syscallarg(int) flags;
1048 register struct vnode *vp;
1051 struct nameidata nd;
1053 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
1054 SCARG(uap, path), td);
1055 if ((error = namei(&nd)) != 0)
1058 NDFREE(&nd, NDF_ONLY_PNBUF);
1062 * Only root, or the user that did the original mount is
1063 * permitted to unmount this filesystem.
1065 if (mp->mnt_stat.f_owner != td->td_ucred->cr_uid) {
1074 * Don't allow unmounting the root file system.
1076 if (mp->mnt_flag & MNT_ROOTFS) {
1082 * Must be the root of the filesystem
1084 if ((vp->v_flag & VROOT) == 0) {
1089 return (dounmount(mp, SCARG(uap, flags), td));
1093 * Do the actual file system unmount.
1096 dounmount(mp, flags, td)
1101 struct vnode *coveredvp, *fsrootvp;
1105 mtx_lock(&mountlist_mtx);
1106 mp->mnt_kern_flag |= MNTK_UNMOUNT;
1107 error = lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK |
1108 ((flags & MNT_FORCE) ? 0 : LK_NOWAIT), &mountlist_mtx, td);
1110 mp->mnt_kern_flag &= ~MNTK_UNMOUNT;
1111 if (mp->mnt_kern_flag & MNTK_MWAIT)
1112 wakeup((caddr_t)mp);
1115 vn_start_write(NULL, &mp, V_WAIT);
1117 if (mp->mnt_flag & MNT_EXPUBLIC)
1118 vfs_setpublicfs(NULL, NULL, NULL);
1120 vfs_msync(mp, MNT_WAIT);
1121 async_flag = mp->mnt_flag & MNT_ASYNC;
1122 mp->mnt_flag &=~ MNT_ASYNC;
1123 cache_purgevfs(mp); /* remove cache entries for this file sys */
1124 if (mp->mnt_syncer != NULL)
1125 vrele(mp->mnt_syncer);
1126 /* Move process cdir/rdir refs on fs root to underlying vnode. */
1127 if (VFS_ROOT(mp, &fsrootvp) == 0) {
1128 if (mp->mnt_vnodecovered != NULL)
1129 checkdirs(fsrootvp, mp->mnt_vnodecovered);
1130 if (fsrootvp == rootvnode) {
1136 if (((mp->mnt_flag & MNT_RDONLY) ||
1137 (error = VFS_SYNC(mp, MNT_WAIT, td->td_ucred, td)) == 0) ||
1138 (flags & MNT_FORCE)) {
1139 error = VFS_UNMOUNT(mp, flags, td);
1141 vn_finished_write(mp);
1143 /* Undo cdir/rdir and rootvnode changes made above. */
1144 if (VFS_ROOT(mp, &fsrootvp) == 0) {
1145 if (mp->mnt_vnodecovered != NULL)
1146 checkdirs(mp->mnt_vnodecovered, fsrootvp);
1147 if (rootvnode == NULL) {
1148 rootvnode = fsrootvp;
1153 if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL)
1154 (void) vfs_allocate_syncvnode(mp);
1155 mtx_lock(&mountlist_mtx);
1156 mp->mnt_kern_flag &= ~MNTK_UNMOUNT;
1157 mp->mnt_flag |= async_flag;
1158 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK,
1159 &mountlist_mtx, td);
1160 if (mp->mnt_kern_flag & MNTK_MWAIT)
1161 wakeup((caddr_t)mp);
1164 mtx_lock(&mountlist_mtx);
1165 TAILQ_REMOVE(&mountlist, mp, mnt_list);
1166 if ((coveredvp = mp->mnt_vnodecovered) != NULL)
1167 coveredvp->v_mountedhere = NULL;
1168 mp->mnt_vfc->vfc_refcount--;
1169 if (!TAILQ_EMPTY(&mp->mnt_nvnodelist))
1170 panic("unmount: dangling vnode");
1171 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_mtx, td);
1172 lockdestroy(&mp->mnt_lock);
1173 if (coveredvp != NULL)
1175 if (mp->mnt_kern_flag & MNTK_MWAIT)
1176 wakeup((caddr_t)mp);
1177 if (mp->mnt_op->vfs_mount == NULL)
1178 vfs_freeopts(mp->mnt_opt);
1179 free((caddr_t)mp, M_MOUNT);
1184 * Sync each mounted filesystem.
1186 #ifndef _SYS_SYSPROTO_H_
1193 static int syncprt = 0;
1194 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, "");
1201 struct sync_args *uap;
1203 struct mount *mp, *nmp;
1206 mtx_lock(&mountlist_mtx);
1207 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
1208 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
1209 nmp = TAILQ_NEXT(mp, mnt_list);
1212 if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
1213 vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
1214 asyncflag = mp->mnt_flag & MNT_ASYNC;
1215 mp->mnt_flag &= ~MNT_ASYNC;
1216 vfs_msync(mp, MNT_NOWAIT);
1217 VFS_SYNC(mp, MNT_NOWAIT,
1218 ((td != NULL) ? td->td_ucred : NOCRED), td);
1219 mp->mnt_flag |= asyncflag;
1220 vn_finished_write(mp);
1222 mtx_lock(&mountlist_mtx);
1223 nmp = TAILQ_NEXT(mp, mnt_list);
1226 mtx_unlock(&mountlist_mtx);
1229 * XXX don't call vfs_bufstats() yet because that routine
1230 * was not imported in the Lite2 merge.
1235 #endif /* DIAGNOSTIC */
1240 /* XXX PRISON: could be per prison flag */
1241 static int prison_quotas;
1243 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, "");
1247 * Change filesystem quotas.
1249 #ifndef _SYS_SYSPROTO_H_
1250 struct quotactl_args {
1261 register struct quotactl_args /* {
1262 syscallarg(char *) path;
1263 syscallarg(int) cmd;
1264 syscallarg(int) uid;
1265 syscallarg(caddr_t) arg;
1270 struct nameidata nd;
1272 if (jailed(td->td_ucred) && !prison_quotas)
1274 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
1275 if ((error = namei(&nd)) != 0)
1277 NDFREE(&nd, NDF_ONLY_PNBUF);
1278 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
1282 error = VFS_QUOTACTL(mp, SCARG(uap, cmd), SCARG(uap, uid),
1283 SCARG(uap, arg), td);
1284 vn_finished_write(mp);
1289 * Get filesystem statistics.
1291 #ifndef _SYS_SYSPROTO_H_
1292 struct statfs_args {
1301 register struct statfs_args /* {
1302 syscallarg(char *) path;
1303 syscallarg(struct statfs *) buf;
1306 register struct mount *mp;
1307 register struct statfs *sp;
1309 struct nameidata nd;
1312 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
1313 if ((error = namei(&nd)) != 0)
1315 mp = nd.ni_vp->v_mount;
1317 NDFREE(&nd, NDF_ONLY_PNBUF);
1319 error = VFS_STATFS(mp, sp, td);
1322 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
1324 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
1325 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
1328 return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp)));
1332 * Get filesystem statistics.
1334 #ifndef _SYS_SYSPROTO_H_
1335 struct fstatfs_args {
1344 register struct fstatfs_args /* {
1346 syscallarg(struct statfs *) buf;
1351 register struct statfs *sp;
1355 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
1357 mp = ((struct vnode *)fp->f_data)->v_mount;
1362 error = VFS_STATFS(mp, sp, td);
1365 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
1367 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
1368 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
1371 return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp)));
1375 * Get statistics on all filesystems.
1377 #ifndef _SYS_SYSPROTO_H_
1378 struct getfsstat_args {
1387 register struct getfsstat_args /* {
1388 syscallarg(struct statfs *) buf;
1389 syscallarg(long) bufsize;
1390 syscallarg(int) flags;
1393 register struct mount *mp, *nmp;
1394 register struct statfs *sp;
1396 long count, maxcount, error;
1398 maxcount = SCARG(uap, bufsize) / sizeof(struct statfs);
1399 sfsp = (caddr_t)SCARG(uap, buf);
1401 mtx_lock(&mountlist_mtx);
1402 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
1403 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
1404 nmp = TAILQ_NEXT(mp, mnt_list);
1407 if (sfsp && count < maxcount) {
1410 * If MNT_NOWAIT or MNT_LAZY is specified, do not
1411 * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
1412 * overrides MNT_WAIT.
1414 if (((SCARG(uap, flags) & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
1415 (SCARG(uap, flags) & MNT_WAIT)) &&
1416 (error = VFS_STATFS(mp, sp, td))) {
1417 mtx_lock(&mountlist_mtx);
1418 nmp = TAILQ_NEXT(mp, mnt_list);
1422 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
1423 error = copyout((caddr_t)sp, sfsp, sizeof(*sp));
1428 sfsp += sizeof(*sp);
1431 mtx_lock(&mountlist_mtx);
1432 nmp = TAILQ_NEXT(mp, mnt_list);
1435 mtx_unlock(&mountlist_mtx);
1436 if (sfsp && count > maxcount)
1437 td->td_retval[0] = maxcount;
1439 td->td_retval[0] = count;
1444 * Change current working directory to a given file descriptor.
1446 #ifndef _SYS_SYSPROTO_H_
1447 struct fchdir_args {
1455 struct fchdir_args /* {
1459 register struct filedesc *fdp = td->td_proc->p_fd;
1460 struct vnode *vp, *tdp, *vpold;
1465 if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0)
1467 vp = (struct vnode *)fp->f_data;
1470 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1471 if (vp->v_type != VDIR)
1474 error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td);
1475 while (!error && (mp = vp->v_mountedhere) != NULL) {
1476 if (vfs_busy(mp, 0, 0, td))
1478 error = VFS_ROOT(mp, &tdp);
1489 VOP_UNLOCK(vp, 0, td);
1491 vpold = fdp->fd_cdir;
1493 FILEDESC_UNLOCK(fdp);
1499 * Change current working directory (``.'').
1501 #ifndef _SYS_SYSPROTO_H_
1510 struct chdir_args /* {
1511 syscallarg(char *) path;
1514 register struct filedesc *fdp = td->td_proc->p_fd;
1516 struct nameidata nd;
1519 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
1520 SCARG(uap, path), td);
1521 if ((error = change_dir(&nd, td)) != 0)
1523 NDFREE(&nd, NDF_ONLY_PNBUF);
1526 fdp->fd_cdir = nd.ni_vp;
1527 FILEDESC_UNLOCK(fdp);
1533 * Helper function for raised chroot(2) security function: Refuse if
1534 * any filedescriptors are open directories.
1537 chroot_refuse_vdir_fds(fdp)
1538 struct filedesc *fdp;
1545 for (fd = 0; fd < fdp->fd_nfiles ; fd++) {
1546 fp = fget_locked(fdp, fd);
1549 if (fp->f_type == DTYPE_VNODE) {
1550 vp = (struct vnode *)fp->f_data;
1551 if (vp->v_type == VDIR) {
1552 FILEDESC_UNLOCK(fdp);
1557 FILEDESC_UNLOCK(fdp);
1562 * This sysctl determines if we will allow a process to chroot(2) if it
1563 * has a directory open:
1564 * 0: disallowed for all processes.
1565 * 1: allowed for processes that were not already chroot(2)'ed.
1566 * 2: allowed for all processes.
1569 static int chroot_allow_open_directories = 1;
1571 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW,
1572 &chroot_allow_open_directories, 0, "");
1575 * Change notion of root (``/'') directory.
1577 #ifndef _SYS_SYSPROTO_H_
1578 struct chroot_args {
1586 struct chroot_args /* {
1587 syscallarg(char *) path;
1590 register struct filedesc *fdp = td->td_proc->p_fd;
1592 struct nameidata nd;
1595 error = suser_cred(td->td_ucred, PRISON_ROOT);
1599 if (chroot_allow_open_directories == 0 ||
1600 (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) {
1601 FILEDESC_UNLOCK(fdp);
1602 error = chroot_refuse_vdir_fds(fdp);
1604 FILEDESC_UNLOCK(fdp);
1607 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
1608 SCARG(uap, path), td);
1609 if ((error = change_dir(&nd, td)) != 0)
1611 NDFREE(&nd, NDF_ONLY_PNBUF);
1614 fdp->fd_rdir = nd.ni_vp;
1615 if (!fdp->fd_jdir) {
1616 fdp->fd_jdir = nd.ni_vp;
1619 FILEDESC_UNLOCK(fdp);
1625 * Common routine for chroot and chdir.
1629 register struct nameidata *ndp;
1639 if (vp->v_type != VDIR)
1642 error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td);
1646 VOP_UNLOCK(vp, 0, td);
1651 * Check permissions, allocate an open file structure,
1652 * and call the device open routine if any.
1654 #ifndef _SYS_SYSPROTO_H_
1664 register struct open_args /* {
1665 syscallarg(char *) path;
1666 syscallarg(int) flags;
1667 syscallarg(int) mode;
1670 struct proc *p = td->td_proc;
1671 struct filedesc *fdp = p->p_fd;
1676 int cmode, flags, oflags;
1678 int type, indx, error;
1680 struct nameidata nd;
1682 oflags = SCARG(uap, flags);
1683 if ((oflags & O_ACCMODE) == O_ACCMODE)
1685 flags = FFLAGS(oflags);
1686 error = falloc(td, &nfp, &indx);
1691 cmode = ((SCARG(uap, mode) &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
1692 FILEDESC_UNLOCK(fdp);
1693 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
1694 td->td_dupfd = -indx - 1; /* XXX check for fdopen */
1696 * Bump the ref count to prevent another process from closing
1697 * the descriptor while we are blocked in vn_open()
1700 error = vn_open(&nd, &flags, cmode);
1703 * release our own reference
1708 * handle special fdopen() case. bleh. dupfdopen() is
1709 * responsible for dropping the old contents of ofiles[indx]
1712 if ((error == ENODEV || error == ENXIO) &&
1713 td->td_dupfd >= 0 && /* XXX from fdopen */
1715 dupfdopen(td, fdp, indx, td->td_dupfd, flags, error)) == 0) {
1716 td->td_retval[0] = indx;
1720 * Clean up the descriptor, but only if another thread hadn't
1721 * replaced or closed it.
1724 if (fdp->fd_ofiles[indx] == fp) {
1725 fdp->fd_ofiles[indx] = NULL;
1726 FILEDESC_UNLOCK(fdp);
1729 FILEDESC_UNLOCK(fdp);
1731 if (error == ERESTART)
1736 NDFREE(&nd, NDF_ONLY_PNBUF);
1740 * There should be 2 references on the file, one from the descriptor
1741 * table, and one for us.
1743 * Handle the case where someone closed the file (via its file
1744 * descriptor) while we were blocked. The end result should look
1745 * like opening the file succeeded but it was immediately closed.
1749 if (fp->f_count == 1) {
1750 KASSERT(fdp->fd_ofiles[indx] != fp,
1751 ("Open file descriptor lost all refs"));
1752 FILEDESC_UNLOCK(fdp);
1754 VOP_UNLOCK(vp, 0, td);
1755 vn_close(vp, flags & FMASK, fp->f_cred, td);
1757 td->td_retval[0] = indx;
1761 fp->f_data = (caddr_t)vp;
1762 fp->f_flag = flags & FMASK;
1764 fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE);
1765 FILEDESC_UNLOCK(fdp);
1767 VOP_UNLOCK(vp, 0, td);
1768 if (flags & (O_EXLOCK | O_SHLOCK)) {
1769 lf.l_whence = SEEK_SET;
1772 if (flags & O_EXLOCK)
1773 lf.l_type = F_WRLCK;
1775 lf.l_type = F_RDLCK;
1777 if ((flags & FNONBLOCK) == 0)
1779 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0)
1781 fp->f_flag |= FHASLOCK;
1783 if (flags & O_TRUNC) {
1784 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
1786 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
1789 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1790 error = VOP_SETATTR(vp, &vat, td->td_ucred, td);
1791 VOP_UNLOCK(vp, 0, td);
1792 vn_finished_write(mp);
1796 /* assert that vn_open created a backing object if one is needed */
1797 KASSERT(!vn_canvmio(vp) || VOP_GETVOBJECT(vp, NULL) == 0,
1798 ("open: vmio vnode has no backing object after vn_open"));
1800 * Release our private reference, leaving the one associated with
1801 * the descriptor table intact.
1804 td->td_retval[0] = indx;
1808 if (fdp->fd_ofiles[indx] == fp) {
1809 fdp->fd_ofiles[indx] = NULL;
1810 FILEDESC_UNLOCK(fdp);
1813 FILEDESC_UNLOCK(fdp);
1821 #ifndef _SYS_SYSPROTO_H_
1822 struct ocreat_args {
1830 register struct ocreat_args /* {
1831 syscallarg(char *) path;
1832 syscallarg(int) mode;
1835 struct open_args /* {
1836 syscallarg(char *) path;
1837 syscallarg(int) flags;
1838 syscallarg(int) mode;
1841 SCARG(&nuap, path) = SCARG(uap, path);
1842 SCARG(&nuap, mode) = SCARG(uap, mode);
1843 SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
1844 return (open(td, &nuap));
1846 #endif /* COMPAT_43 */
1849 * Create a special file.
1851 #ifndef _SYS_SYSPROTO_H_
1862 register struct mknod_args /* {
1863 syscallarg(char *) path;
1864 syscallarg(int) mode;
1865 syscallarg(int) dev;
1873 struct nameidata nd;
1875 switch (SCARG(uap, mode) & S_IFMT) {
1881 error = suser_cred(td->td_ucred, PRISON_ROOT);
1888 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), td);
1889 if ((error = namei(&nd)) != 0)
1897 FILEDESC_LOCK(td->td_proc->p_fd);
1898 vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ td->td_proc->p_fd->fd_cmask;
1899 FILEDESC_UNLOCK(td->td_proc->p_fd);
1900 vattr.va_rdev = SCARG(uap, dev);
1903 switch (SCARG(uap, mode) & S_IFMT) {
1904 case S_IFMT: /* used by badsect to flag bad sectors */
1905 vattr.va_type = VBAD;
1908 vattr.va_type = VCHR;
1911 vattr.va_type = VBLK;
1921 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1922 NDFREE(&nd, NDF_ONLY_PNBUF);
1924 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1929 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1931 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE);
1933 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp,
1934 &nd.ni_cnd, &vattr);
1939 NDFREE(&nd, NDF_ONLY_PNBUF);
1941 vn_finished_write(mp);
1942 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod");
1943 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod");
1948 * Create a named pipe.
1950 #ifndef _SYS_SYSPROTO_H_
1951 struct mkfifo_args {
1960 register struct mkfifo_args /* {
1961 syscallarg(char *) path;
1962 syscallarg(int) mode;
1968 struct nameidata nd;
1972 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), td);
1973 if ((error = namei(&nd)) != 0)
1975 if (nd.ni_vp != NULL) {
1976 NDFREE(&nd, NDF_ONLY_PNBUF);
1981 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1982 NDFREE(&nd, NDF_ONLY_PNBUF);
1984 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1989 vattr.va_type = VFIFO;
1990 FILEDESC_LOCK(td->td_proc->p_fd);
1991 vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ td->td_proc->p_fd->fd_cmask;
1992 FILEDESC_UNLOCK(td->td_proc->p_fd);
1993 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1994 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
1997 NDFREE(&nd, NDF_ONLY_PNBUF);
1999 vn_finished_write(mp);
2004 * Make a hard file link.
2006 #ifndef _SYS_SYSPROTO_H_
2016 register struct link_args /* {
2017 syscallarg(char *) path;
2018 syscallarg(char *) link;
2023 struct nameidata nd;
2027 NDINIT(&nd, LOOKUP, FOLLOW|NOOBJ, UIO_USERSPACE, SCARG(uap, path), td);
2028 if ((error = namei(&nd)) != 0)
2030 NDFREE(&nd, NDF_ONLY_PNBUF);
2032 if (vp->v_type == VDIR) {
2034 return (EPERM); /* POSIX */
2036 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
2040 NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), td);
2041 if ((error = namei(&nd)) == 0) {
2042 if (nd.ni_vp != NULL) {
2046 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
2047 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2048 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
2050 NDFREE(&nd, NDF_ONLY_PNBUF);
2054 vn_finished_write(mp);
2055 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link");
2056 ASSERT_VOP_UNLOCKED(nd.ni_vp, "link");
2061 * Make a symbolic link.
2063 #ifndef _SYS_SYSPROTO_H_
2064 struct symlink_args {
2073 register struct symlink_args /* {
2074 syscallarg(char *) path;
2075 syscallarg(char *) link;
2082 struct nameidata nd;
2084 path = uma_zalloc(namei_zone, M_WAITOK);
2085 if ((error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL)) != 0)
2089 NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), td);
2090 if ((error = namei(&nd)) != 0)
2093 NDFREE(&nd, NDF_ONLY_PNBUF);
2099 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
2100 NDFREE(&nd, NDF_ONLY_PNBUF);
2102 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
2107 FILEDESC_LOCK(td->td_proc->p_fd);
2108 vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask;
2109 FILEDESC_UNLOCK(td->td_proc->p_fd);
2110 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
2111 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path);
2112 NDFREE(&nd, NDF_ONLY_PNBUF);
2116 vn_finished_write(mp);
2117 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink");
2118 ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink");
2120 uma_zfree(namei_zone, path);
2125 * Delete a whiteout from the filesystem.
2131 register struct undelete_args /* {
2132 syscallarg(char *) path;
2137 struct nameidata nd;
2141 NDINIT(&nd, DELETE, LOCKPARENT|DOWHITEOUT, UIO_USERSPACE,
2142 SCARG(uap, path), td);
2147 if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) {
2148 NDFREE(&nd, NDF_ONLY_PNBUF);
2154 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
2155 NDFREE(&nd, NDF_ONLY_PNBUF);
2157 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
2161 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
2162 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE);
2163 NDFREE(&nd, NDF_ONLY_PNBUF);
2165 vn_finished_write(mp);
2166 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "undelete");
2167 ASSERT_VOP_UNLOCKED(nd.ni_vp, "undelete");
2172 * Delete a name from the filesystem.
2174 #ifndef _SYS_SYSPROTO_H_
2175 struct unlink_args {
2183 struct unlink_args /* {
2184 syscallarg(char *) path;
2190 struct nameidata nd;
2194 NDINIT(&nd, DELETE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), td);
2195 if ((error = namei(&nd)) != 0)
2198 if (vp->v_type == VDIR)
2199 error = EPERM; /* POSIX */
2202 * The root of a mounted filesystem cannot be deleted.
2204 * XXX: can this only be a VDIR case?
2206 if (vp->v_flag & VROOT)
2209 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
2210 NDFREE(&nd, NDF_ONLY_PNBUF);
2213 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
2217 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2218 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2220 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
2221 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd);
2223 NDFREE(&nd, NDF_ONLY_PNBUF);
2226 vn_finished_write(mp);
2227 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink");
2228 ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink");
2233 * Reposition read/write file offset.
2235 #ifndef _SYS_SYSPROTO_H_
2246 register struct lseek_args /* {
2248 syscallarg(int) pad;
2249 syscallarg(off_t) offset;
2250 syscallarg(int) whence;
2253 struct ucred *cred = td->td_ucred;
2260 if ((error = fget(td, uap->fd, &fp)) != 0)
2262 if (fp->f_type != DTYPE_VNODE) {
2266 vp = (struct vnode *)fp->f_data;
2267 noneg = (vp->v_type != VCHR);
2268 offset = SCARG(uap, offset);
2269 switch (SCARG(uap, whence)) {
2272 (fp->f_offset < 0 ||
2273 (offset > 0 && fp->f_offset > OFF_MAX - offset)))
2275 offset += fp->f_offset;
2278 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2279 error = VOP_GETATTR(vp, &vattr, cred, td);
2280 VOP_UNLOCK(vp, 0, td);
2284 (vattr.va_size > OFF_MAX ||
2285 (offset > 0 && vattr.va_size > OFF_MAX - offset)))
2287 offset += vattr.va_size;
2295 if (noneg && offset < 0)
2297 fp->f_offset = offset;
2298 *(off_t *)(td->td_retval) = fp->f_offset;
2303 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
2305 * Reposition read/write file offset.
2307 #ifndef _SYS_SYSPROTO_H_
2308 struct olseek_args {
2317 register struct olseek_args /* {
2319 syscallarg(long) offset;
2320 syscallarg(int) whence;
2323 struct lseek_args /* {
2325 syscallarg(int) pad;
2326 syscallarg(off_t) offset;
2327 syscallarg(int) whence;
2331 SCARG(&nuap, fd) = SCARG(uap, fd);
2332 SCARG(&nuap, offset) = SCARG(uap, offset);
2333 SCARG(&nuap, whence) = SCARG(uap, whence);
2334 error = lseek(td, &nuap);
2337 #endif /* COMPAT_43 */
2340 * Check access permissions using passed credentials.
2343 vn_access(vp, user_flags, cred, td)
2351 /* Flags == 0 means only check for existence. */
2355 if (user_flags & R_OK)
2357 if (user_flags & W_OK)
2359 if (user_flags & X_OK)
2361 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
2362 error = VOP_ACCESS(vp, flags, cred, td);
2368 * Check access permissions using "real" credentials.
2370 #ifndef _SYS_SYSPROTO_H_
2371 struct access_args {
2379 register struct access_args /* {
2380 syscallarg(char *) path;
2381 syscallarg(int) flags;
2384 struct ucred *cred, *tmpcred;
2385 register struct vnode *vp;
2387 struct nameidata nd;
2390 * Create and modify a temporary credential instead of one that
2391 * is potentially shared. This could also mess up socket
2392 * buffer accounting which can run in an interrupt context.
2394 * XXX - Depending on how "threads" are finally implemented, it
2395 * may be better to explicitly pass the credential to namei()
2396 * rather than to modify the potentially shared process structure.
2398 cred = td->td_ucred;
2399 tmpcred = crdup(cred);
2400 tmpcred->cr_uid = cred->cr_ruid;
2401 tmpcred->cr_groups[0] = cred->cr_rgid;
2402 td->td_ucred = tmpcred;
2403 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2404 SCARG(uap, path), td);
2405 if ((error = namei(&nd)) != 0)
2409 error = vn_access(vp, SCARG(uap, flags), tmpcred, td);
2410 NDFREE(&nd, NDF_ONLY_PNBUF);
2413 td->td_ucred = cred;
2419 * Check access permissions using "effective" credentials.
2421 #ifndef _SYS_SYSPROTO_H_
2422 struct eaccess_args {
2430 register struct eaccess_args /* {
2431 syscallarg(char *) path;
2432 syscallarg(int) flags;
2435 struct nameidata nd;
2439 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2440 SCARG(uap, path), td);
2441 if ((error = namei(&nd)) != 0)
2445 error = vn_access(vp, SCARG(uap, flags), td->td_ucred, td);
2446 NDFREE(&nd, NDF_ONLY_PNBUF);
2451 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
2453 * Get file status; this version follows links.
2455 #ifndef _SYS_SYSPROTO_H_
2465 register struct ostat_args /* {
2466 syscallarg(char *) path;
2467 syscallarg(struct ostat *) ub;
2473 struct nameidata nd;
2475 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2476 SCARG(uap, path), td);
2477 if ((error = namei(&nd)) != 0)
2479 NDFREE(&nd, NDF_ONLY_PNBUF);
2480 error = vn_stat(nd.ni_vp, &sb, td);
2485 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
2490 * Get file status; this version does not follow links.
2492 #ifndef _SYS_SYSPROTO_H_
2493 struct olstat_args {
2502 register struct olstat_args /* {
2503 syscallarg(char *) path;
2504 syscallarg(struct ostat *) ub;
2511 struct nameidata nd;
2513 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2514 SCARG(uap, path), td);
2515 if ((error = namei(&nd)) != 0)
2518 error = vn_stat(vp, &sb, td);
2519 NDFREE(&nd, NDF_ONLY_PNBUF);
2524 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
2529 * Convert from an old to a new stat structure.
2537 ost->st_dev = st->st_dev;
2538 ost->st_ino = st->st_ino;
2539 ost->st_mode = st->st_mode;
2540 ost->st_nlink = st->st_nlink;
2541 ost->st_uid = st->st_uid;
2542 ost->st_gid = st->st_gid;
2543 ost->st_rdev = st->st_rdev;
2544 if (st->st_size < (quad_t)1 << 32)
2545 ost->st_size = st->st_size;
2548 ost->st_atime = st->st_atime;
2549 ost->st_mtime = st->st_mtime;
2550 ost->st_ctime = st->st_ctime;
2551 ost->st_blksize = st->st_blksize;
2552 ost->st_blocks = st->st_blocks;
2553 ost->st_flags = st->st_flags;
2554 ost->st_gen = st->st_gen;
2556 #endif /* COMPAT_43 || COMPAT_SUNOS */
2559 * Get file status; this version follows links.
2561 #ifndef _SYS_SYSPROTO_H_
2571 register struct stat_args /* {
2572 syscallarg(char *) path;
2573 syscallarg(struct stat *) ub;
2578 struct nameidata nd;
2580 #ifndef LOOKUP_EXCLUSIVE
2581 NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | NOOBJ,
2582 UIO_USERSPACE, SCARG(uap, path), td);
2584 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2585 SCARG(uap, path), td);
2587 if ((error = namei(&nd)) != 0)
2589 error = vn_stat(nd.ni_vp, &sb, td);
2590 NDFREE(&nd, NDF_ONLY_PNBUF);
2594 error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));
2599 * Get file status; this version does not follow links.
2601 #ifndef _SYS_SYSPROTO_H_
2611 register struct lstat_args /* {
2612 syscallarg(char *) path;
2613 syscallarg(struct stat *) ub;
2619 struct nameidata nd;
2621 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2622 SCARG(uap, path), td);
2623 if ((error = namei(&nd)) != 0)
2626 error = vn_stat(vp, &sb, td);
2627 NDFREE(&nd, NDF_ONLY_PNBUF);
2631 error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));
2636 * Implementation of the NetBSD stat() function.
2637 * XXX This should probably be collapsed with the FreeBSD version,
2638 * as the differences are only due to vn_stat() clearing spares at
2639 * the end of the structures. vn_stat could be split to avoid this,
2640 * and thus collapse the following to close to zero code.
2647 nsb->st_dev = sb->st_dev;
2648 nsb->st_ino = sb->st_ino;
2649 nsb->st_mode = sb->st_mode;
2650 nsb->st_nlink = sb->st_nlink;
2651 nsb->st_uid = sb->st_uid;
2652 nsb->st_gid = sb->st_gid;
2653 nsb->st_rdev = sb->st_rdev;
2654 nsb->st_atimespec = sb->st_atimespec;
2655 nsb->st_mtimespec = sb->st_mtimespec;
2656 nsb->st_ctimespec = sb->st_ctimespec;
2657 nsb->st_size = sb->st_size;
2658 nsb->st_blocks = sb->st_blocks;
2659 nsb->st_blksize = sb->st_blksize;
2660 nsb->st_flags = sb->st_flags;
2661 nsb->st_gen = sb->st_gen;
2662 nsb->st_qspare[0] = sb->st_qspare[0];
2663 nsb->st_qspare[1] = sb->st_qspare[1];
2666 #ifndef _SYS_SYSPROTO_H_
2676 register struct nstat_args /* {
2677 syscallarg(char *) path;
2678 syscallarg(struct nstat *) ub;
2684 struct nameidata nd;
2686 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2687 SCARG(uap, path), td);
2688 if ((error = namei(&nd)) != 0)
2690 NDFREE(&nd, NDF_ONLY_PNBUF);
2691 error = vn_stat(nd.ni_vp, &sb, td);
2695 cvtnstat(&sb, &nsb);
2696 error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb));
2701 * NetBSD lstat. Get file status; this version does not follow links.
2703 #ifndef _SYS_SYSPROTO_H_
2713 register struct nlstat_args /* {
2714 syscallarg(char *) path;
2715 syscallarg(struct nstat *) ub;
2722 struct nameidata nd;
2724 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2725 SCARG(uap, path), td);
2726 if ((error = namei(&nd)) != 0)
2729 NDFREE(&nd, NDF_ONLY_PNBUF);
2730 error = vn_stat(vp, &sb, td);
2734 cvtnstat(&sb, &nsb);
2735 error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb));
2740 * Get configurable pathname variables.
2742 #ifndef _SYS_SYSPROTO_H_
2743 struct pathconf_args {
2752 register struct pathconf_args /* {
2753 syscallarg(char *) path;
2754 syscallarg(int) name;
2758 struct nameidata nd;
2760 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2761 SCARG(uap, path), td);
2762 if ((error = namei(&nd)) != 0)
2764 NDFREE(&nd, NDF_ONLY_PNBUF);
2765 error = VOP_PATHCONF(nd.ni_vp, SCARG(uap, name), td->td_retval);
2771 * Return target name of a symbolic link.
2773 #ifndef _SYS_SYSPROTO_H_
2774 struct readlink_args {
2784 register struct readlink_args /* {
2785 syscallarg(char *) path;
2786 syscallarg(char *) buf;
2787 syscallarg(int) count;
2790 register struct vnode *vp;
2794 struct nameidata nd;
2796 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2797 SCARG(uap, path), td);
2798 if ((error = namei(&nd)) != 0)
2800 NDFREE(&nd, NDF_ONLY_PNBUF);
2802 if (vp->v_type != VLNK)
2805 aiov.iov_base = SCARG(uap, buf);
2806 aiov.iov_len = SCARG(uap, count);
2807 auio.uio_iov = &aiov;
2808 auio.uio_iovcnt = 1;
2809 auio.uio_offset = 0;
2810 auio.uio_rw = UIO_READ;
2811 auio.uio_segflg = UIO_USERSPACE;
2813 auio.uio_resid = SCARG(uap, count);
2814 error = VOP_READLINK(vp, &auio, td->td_ucred);
2817 td->td_retval[0] = SCARG(uap, count) - auio.uio_resid;
2822 * Common implementation code for chflags() and fchflags().
2825 setfflags(td, vp, flags)
2835 * Prevent non-root users from setting flags on devices. When
2836 * a device is reused, users can retain ownership of the device
2837 * if they are allowed to set flags and programs assume that
2838 * chown can't fail when done as root.
2840 if (vp->v_type == VCHR || vp->v_type == VBLK) {
2841 error = suser_cred(td->td_ucred, PRISON_ROOT);
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 vattr.va_flags = flags;
2852 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2853 VOP_UNLOCK(vp, 0, td);
2854 vn_finished_write(mp);
2859 * Change flags of a file given a path name.
2861 #ifndef _SYS_SYSPROTO_H_
2862 struct chflags_args {
2871 register struct chflags_args /* {
2872 syscallarg(char *) path;
2873 syscallarg(int) flags;
2877 struct nameidata nd;
2879 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
2880 if ((error = namei(&nd)) != 0)
2882 NDFREE(&nd, NDF_ONLY_PNBUF);
2883 error = setfflags(td, nd.ni_vp, SCARG(uap, flags));
2889 * Change flags of a file given a file descriptor.
2891 #ifndef _SYS_SYSPROTO_H_
2892 struct fchflags_args {
2901 register struct fchflags_args /* {
2903 syscallarg(int) flags;
2909 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
2911 error = setfflags(td, (struct vnode *) fp->f_data, SCARG(uap, flags));
2917 * Common implementation code for chmod(), lchmod() and fchmod().
2920 setfmode(td, vp, mode)
2929 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2931 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2932 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2934 vattr.va_mode = mode & ALLPERMS;
2935 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2936 VOP_UNLOCK(vp, 0, td);
2937 vn_finished_write(mp);
2942 * Change mode of a file given path name.
2944 #ifndef _SYS_SYSPROTO_H_
2954 register struct chmod_args /* {
2955 syscallarg(char *) path;
2956 syscallarg(int) mode;
2960 struct nameidata nd;
2962 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
2963 if ((error = namei(&nd)) != 0)
2965 NDFREE(&nd, NDF_ONLY_PNBUF);
2966 error = setfmode(td, nd.ni_vp, SCARG(uap, mode));
2972 * Change mode of a file given path name (don't follow links.)
2974 #ifndef _SYS_SYSPROTO_H_
2975 struct lchmod_args {
2984 register struct lchmod_args /* {
2985 syscallarg(char *) path;
2986 syscallarg(int) mode;
2990 struct nameidata nd;
2992 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
2993 if ((error = namei(&nd)) != 0)
2995 NDFREE(&nd, NDF_ONLY_PNBUF);
2996 error = setfmode(td, nd.ni_vp, SCARG(uap, mode));
3002 * Change mode of a file given a file descriptor.
3004 #ifndef _SYS_SYSPROTO_H_
3005 struct fchmod_args {
3014 register struct fchmod_args /* {
3016 syscallarg(int) mode;
3023 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3025 vp = (struct vnode *)fp->f_data;
3026 error = setfmode(td, (struct vnode *)fp->f_data, SCARG(uap, mode));
3032 * Common implementation for chown(), lchown(), and fchown()
3035 setfown(td, vp, uid, gid)
3045 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
3047 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3048 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3052 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
3053 VOP_UNLOCK(vp, 0, td);
3054 vn_finished_write(mp);
3059 * Set ownership given a path name.
3061 #ifndef _SYS_SYSPROTO_H_
3072 register struct chown_args /* {
3073 syscallarg(char *) path;
3074 syscallarg(int) uid;
3075 syscallarg(int) gid;
3079 struct nameidata nd;
3081 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
3082 if ((error = namei(&nd)) != 0)
3084 NDFREE(&nd, NDF_ONLY_PNBUF);
3085 error = setfown(td, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid));
3091 * Set ownership given a path name, do not cross symlinks.
3093 #ifndef _SYS_SYSPROTO_H_
3094 struct lchown_args {
3104 register struct lchown_args /* {
3105 syscallarg(char *) path;
3106 syscallarg(int) uid;
3107 syscallarg(int) gid;
3111 struct nameidata nd;
3113 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
3114 if ((error = namei(&nd)) != 0)
3116 NDFREE(&nd, NDF_ONLY_PNBUF);
3117 error = setfown(td, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid));
3123 * Set ownership given a file descriptor.
3125 #ifndef _SYS_SYSPROTO_H_
3126 struct fchown_args {
3136 register struct fchown_args /* {
3138 syscallarg(int) uid;
3139 syscallarg(int) gid;
3146 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3148 vp = (struct vnode *)fp->f_data;
3149 error = setfown(td, (struct vnode *)fp->f_data,
3150 SCARG(uap, uid), SCARG(uap, gid));
3156 * Common implementation code for utimes(), lutimes(), and futimes().
3159 getutimes(usrtvp, tsp)
3160 const struct timeval *usrtvp;
3161 struct timespec *tsp;
3163 struct timeval tv[2];
3166 if (usrtvp == NULL) {
3168 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]);
3171 if ((error = copyin(usrtvp, tv, sizeof (tv))) != 0)
3173 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]);
3174 TIMEVAL_TO_TIMESPEC(&tv[1], &tsp[1]);
3180 * Common implementation code for utimes(), lutimes(), and futimes().
3183 setutimes(td, vp, ts, nullflag)
3186 const struct timespec *ts;
3193 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
3195 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3196 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3198 vattr.va_atime = ts[0];
3199 vattr.va_mtime = ts[1];
3201 vattr.va_vaflags |= VA_UTIMES_NULL;
3202 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
3203 VOP_UNLOCK(vp, 0, td);
3204 vn_finished_write(mp);
3209 * Set the access and modification times of a file.
3211 #ifndef _SYS_SYSPROTO_H_
3212 struct utimes_args {
3214 struct timeval *tptr;
3221 register struct utimes_args /* {
3222 syscallarg(char *) path;
3223 syscallarg(struct timeval *) tptr;
3226 struct timespec ts[2];
3227 struct timeval *usrtvp;
3229 struct nameidata nd;
3231 usrtvp = SCARG(uap, tptr);
3232 if ((error = getutimes(usrtvp, ts)) != 0)
3234 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
3235 if ((error = namei(&nd)) != 0)
3237 NDFREE(&nd, NDF_ONLY_PNBUF);
3238 error = setutimes(td, nd.ni_vp, ts, usrtvp == NULL);
3244 * Set the access and modification times of a file.
3246 #ifndef _SYS_SYSPROTO_H_
3247 struct lutimes_args {
3249 struct timeval *tptr;
3256 register struct lutimes_args /* {
3257 syscallarg(char *) path;
3258 syscallarg(struct timeval *) tptr;
3261 struct timespec ts[2];
3262 struct timeval *usrtvp;
3264 struct nameidata nd;
3266 usrtvp = SCARG(uap, tptr);
3267 if ((error = getutimes(usrtvp, ts)) != 0)
3269 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
3270 if ((error = namei(&nd)) != 0)
3272 NDFREE(&nd, NDF_ONLY_PNBUF);
3273 error = setutimes(td, nd.ni_vp, ts, usrtvp == NULL);
3279 * Set the access and modification times of a file.
3281 #ifndef _SYS_SYSPROTO_H_
3282 struct futimes_args {
3284 struct timeval *tptr;
3291 register struct futimes_args /* {
3292 syscallarg(int ) fd;
3293 syscallarg(struct timeval *) tptr;
3296 struct timespec ts[2];
3298 struct timeval *usrtvp;
3301 usrtvp = SCARG(uap, tptr);
3302 if ((error = getutimes(usrtvp, ts)) != 0)
3304 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3306 error = setutimes(td, (struct vnode *)fp->f_data, ts, usrtvp == NULL);
3312 * Truncate a file given its path name.
3314 #ifndef _SYS_SYSPROTO_H_
3315 struct truncate_args {
3325 register struct truncate_args /* {
3326 syscallarg(char *) path;
3327 syscallarg(int) pad;
3328 syscallarg(off_t) length;
3335 struct nameidata nd;
3337 if (uap->length < 0)
3339 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
3340 if ((error = namei(&nd)) != 0)
3343 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
3347 NDFREE(&nd, NDF_ONLY_PNBUF);
3348 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3349 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3350 if (vp->v_type == VDIR)
3352 else if ((error = vn_writechk(vp)) == 0 &&
3353 (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) {
3355 vattr.va_size = SCARG(uap, length);
3356 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
3359 vn_finished_write(mp);
3364 * Truncate a file given a file descriptor.
3366 #ifndef _SYS_SYSPROTO_H_
3367 struct ftruncate_args {
3377 register struct ftruncate_args /* {
3379 syscallarg(int) pad;
3380 syscallarg(off_t) length;
3389 if (uap->length < 0)
3391 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3393 if ((fp->f_flag & FWRITE) == 0) {
3397 vp = (struct vnode *)fp->f_data;
3398 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
3402 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3403 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3404 if (vp->v_type == VDIR)
3406 else if ((error = vn_writechk(vp)) == 0) {
3408 vattr.va_size = SCARG(uap, length);
3409 error = VOP_SETATTR(vp, &vattr, fp->f_cred, td);
3411 VOP_UNLOCK(vp, 0, td);
3412 vn_finished_write(mp);
3417 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
3419 * Truncate a file given its path name.
3421 #ifndef _SYS_SYSPROTO_H_
3422 struct otruncate_args {
3431 register struct otruncate_args /* {
3432 syscallarg(char *) path;
3433 syscallarg(long) length;
3436 struct truncate_args /* {
3437 syscallarg(char *) path;
3438 syscallarg(int) pad;
3439 syscallarg(off_t) length;
3442 SCARG(&nuap, path) = SCARG(uap, path);
3443 SCARG(&nuap, length) = SCARG(uap, length);
3444 return (truncate(td, &nuap));
3448 * Truncate a file given a file descriptor.
3450 #ifndef _SYS_SYSPROTO_H_
3451 struct oftruncate_args {
3460 register struct oftruncate_args /* {
3462 syscallarg(long) length;
3465 struct ftruncate_args /* {
3467 syscallarg(int) pad;
3468 syscallarg(off_t) length;
3471 SCARG(&nuap, fd) = SCARG(uap, fd);
3472 SCARG(&nuap, length) = SCARG(uap, length);
3473 return (ftruncate(td, &nuap));
3475 #endif /* COMPAT_43 || COMPAT_SUNOS */
3478 * Sync an open file.
3480 #ifndef _SYS_SYSPROTO_H_
3489 struct fsync_args /* {
3501 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3503 vp = (struct vnode *)fp->f_data;
3504 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
3508 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3509 if (VOP_GETVOBJECT(vp, &obj) == 0) {
3510 vm_object_page_clean(obj, 0, 0, 0);
3512 error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, td);
3514 if (error == 0 && vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP))
3515 error = softdep_fsync(vp);
3518 VOP_UNLOCK(vp, 0, td);
3519 vn_finished_write(mp);
3525 * Rename files. Source and destination must either both be directories,
3526 * or both not be directories. If target is a directory, it must be empty.
3528 #ifndef _SYS_SYSPROTO_H_
3529 struct rename_args {
3538 register struct rename_args /* {
3539 syscallarg(char *) from;
3540 syscallarg(char *) to;
3544 struct vnode *tvp, *fvp, *tdvp;
3545 struct nameidata fromnd, tond;
3549 NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE,
3550 SCARG(uap, from), td);
3551 if ((error = namei(&fromnd)) != 0)
3554 if ((error = vn_start_write(fvp, &mp, V_WAIT | PCATCH)) != 0) {
3555 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3556 vrele(fromnd.ni_dvp);
3560 NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | NOOBJ,
3561 UIO_USERSPACE, SCARG(uap, to), td);
3562 if (fromnd.ni_vp->v_type == VDIR)
3563 tond.ni_cnd.cn_flags |= WILLBEDIR;
3564 if ((error = namei(&tond)) != 0) {
3565 /* Translate error code for rename("dir1", "dir2/."). */
3566 if (error == EISDIR && fvp->v_type == VDIR)
3568 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3569 vrele(fromnd.ni_dvp);
3576 if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
3579 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
3587 * If source is the same as the destination (that is the
3588 * same inode number with the same name in the same directory),
3589 * then there is nothing to do.
3591 if (fvp == tvp && fromnd.ni_dvp == tdvp &&
3592 fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen &&
3593 !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr,
3594 fromnd.ni_cnd.cn_namelen))
3598 VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE);
3599 if (fromnd.ni_dvp != tdvp) {
3600 VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3603 VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE);
3605 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
3606 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
3607 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3608 NDFREE(&tond, NDF_ONLY_PNBUF);
3610 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3611 NDFREE(&tond, NDF_ONLY_PNBUF);
3618 vrele(fromnd.ni_dvp);
3621 vrele(tond.ni_startdir);
3622 vn_finished_write(mp);
3623 ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename");
3624 ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename");
3625 ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename");
3626 ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename");
3628 if (fromnd.ni_startdir)
3629 vrele(fromnd.ni_startdir);
3636 * Make a directory file.
3638 #ifndef _SYS_SYSPROTO_H_
3648 register struct mkdir_args /* {
3649 syscallarg(char *) path;
3650 syscallarg(int) mode;
3654 return vn_mkdir(uap->path, uap->mode, UIO_USERSPACE, td);
3658 vn_mkdir(path, mode, segflg, td)
3661 enum uio_seg segflg;
3668 struct nameidata nd;
3672 NDINIT(&nd, CREATE, LOCKPARENT, segflg, path, td);
3673 nd.ni_cnd.cn_flags |= WILLBEDIR;
3674 if ((error = namei(&nd)) != 0)
3678 NDFREE(&nd, NDF_ONLY_PNBUF);
3683 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
3684 NDFREE(&nd, NDF_ONLY_PNBUF);
3686 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
3691 vattr.va_type = VDIR;
3692 FILEDESC_LOCK(td->td_proc->p_fd);
3693 vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask;
3694 FILEDESC_UNLOCK(td->td_proc->p_fd);
3695 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3696 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
3697 NDFREE(&nd, NDF_ONLY_PNBUF);
3701 vn_finished_write(mp);
3702 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir");
3703 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir");
3708 * Remove a directory file.
3710 #ifndef _SYS_SYSPROTO_H_
3719 struct rmdir_args /* {
3720 syscallarg(char *) path;
3726 struct nameidata nd;
3730 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE,
3731 SCARG(uap, path), td);
3732 if ((error = namei(&nd)) != 0)
3735 if (vp->v_type != VDIR) {
3740 * No rmdir "." please.
3742 if (nd.ni_dvp == vp) {
3747 * The root of a mounted filesystem cannot be deleted.
3749 if (vp->v_flag & VROOT) {
3753 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
3754 NDFREE(&nd, NDF_ONLY_PNBUF);
3755 if (nd.ni_dvp == vp)
3760 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
3764 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3765 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3766 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
3767 vn_finished_write(mp);
3769 NDFREE(&nd, NDF_ONLY_PNBUF);
3770 if (nd.ni_dvp == vp)
3775 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir");
3776 ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir");
3782 * Read a block of directory entries in a file system independent format.
3784 #ifndef _SYS_SYSPROTO_H_
3785 struct ogetdirentries_args {
3793 ogetdirentries(td, uap)
3795 register struct ogetdirentries_args /* {
3797 syscallarg(char *) buf;
3798 syscallarg(u_int) count;
3799 syscallarg(long *) basep;
3804 struct uio auio, kuio;
3805 struct iovec aiov, kiov;
3806 struct dirent *dp, *edp;
3808 int error, eofflag, readcnt;
3811 /* XXX arbitrary sanity limit on `count'. */
3812 if (SCARG(uap, count) > 64 * 1024)
3814 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3816 if ((fp->f_flag & FREAD) == 0) {
3820 vp = (struct vnode *)fp->f_data;
3822 if (vp->v_type != VDIR) {
3826 aiov.iov_base = SCARG(uap, buf);
3827 aiov.iov_len = SCARG(uap, count);
3828 auio.uio_iov = &aiov;
3829 auio.uio_iovcnt = 1;
3830 auio.uio_rw = UIO_READ;
3831 auio.uio_segflg = UIO_USERSPACE;
3833 auio.uio_resid = SCARG(uap, count);
3834 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3835 loff = auio.uio_offset = fp->f_offset;
3836 # if (BYTE_ORDER != LITTLE_ENDIAN)
3837 if (vp->v_mount->mnt_maxsymlinklen <= 0) {
3838 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
3840 fp->f_offset = auio.uio_offset;
3845 kuio.uio_iov = &kiov;
3846 kuio.uio_segflg = UIO_SYSSPACE;
3847 kiov.iov_len = SCARG(uap, count);
3848 MALLOC(dirbuf, caddr_t, SCARG(uap, count), M_TEMP, M_WAITOK);
3849 kiov.iov_base = dirbuf;
3850 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag,
3852 fp->f_offset = kuio.uio_offset;
3854 readcnt = SCARG(uap, count) - kuio.uio_resid;
3855 edp = (struct dirent *)&dirbuf[readcnt];
3856 for (dp = (struct dirent *)dirbuf; dp < edp; ) {
3857 # if (BYTE_ORDER == LITTLE_ENDIAN)
3859 * The expected low byte of
3860 * dp->d_namlen is our dp->d_type.
3861 * The high MBZ byte of dp->d_namlen
3862 * is our dp->d_namlen.
3864 dp->d_type = dp->d_namlen;
3868 * The dp->d_type is the high byte
3869 * of the expected dp->d_namlen,
3870 * so must be zero'ed.
3874 if (dp->d_reclen > 0) {
3875 dp = (struct dirent *)
3876 ((char *)dp + dp->d_reclen);
3883 error = uiomove(dirbuf, readcnt, &auio);
3885 FREE(dirbuf, M_TEMP);
3887 VOP_UNLOCK(vp, 0, td);
3892 if (SCARG(uap, count) == auio.uio_resid) {
3893 if (union_dircheckp) {
3894 error = union_dircheckp(td, &vp, fp);
3902 if ((vp->v_flag & VROOT) &&
3903 (vp->v_mount->mnt_flag & MNT_UNION)) {
3904 struct vnode *tvp = vp;
3905 vp = vp->v_mount->mnt_vnodecovered;
3907 fp->f_data = (caddr_t) vp;
3913 error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
3916 td->td_retval[0] = SCARG(uap, count) - auio.uio_resid;
3919 #endif /* COMPAT_43 */
3922 * Read a block of directory entries in a file system independent format.
3924 #ifndef _SYS_SYSPROTO_H_
3925 struct getdirentries_args {
3933 getdirentries(td, uap)
3935 register struct getdirentries_args /* {
3937 syscallarg(char *) buf;
3938 syscallarg(u_int) count;
3939 syscallarg(long *) basep;
3949 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3951 if ((fp->f_flag & FREAD) == 0) {
3955 vp = (struct vnode *)fp->f_data;
3957 if (vp->v_type != VDIR) {
3961 aiov.iov_base = SCARG(uap, buf);
3962 aiov.iov_len = SCARG(uap, count);
3963 auio.uio_iov = &aiov;
3964 auio.uio_iovcnt = 1;
3965 auio.uio_rw = UIO_READ;
3966 auio.uio_segflg = UIO_USERSPACE;
3968 auio.uio_resid = SCARG(uap, count);
3969 /* vn_lock(vp, LK_SHARED | LK_RETRY, td); */
3970 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3971 loff = auio.uio_offset = fp->f_offset;
3972 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL);
3973 fp->f_offset = auio.uio_offset;
3974 VOP_UNLOCK(vp, 0, td);
3979 if (SCARG(uap, count) == auio.uio_resid) {
3980 if (union_dircheckp) {
3981 error = union_dircheckp(td, &vp, fp);
3989 if ((vp->v_flag & VROOT) &&
3990 (vp->v_mount->mnt_flag & MNT_UNION)) {
3991 struct vnode *tvp = vp;
3992 vp = vp->v_mount->mnt_vnodecovered;
3994 fp->f_data = (caddr_t) vp;
4000 if (SCARG(uap, basep) != NULL) {
4001 error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
4004 td->td_retval[0] = SCARG(uap, count) - auio.uio_resid;
4008 #ifndef _SYS_SYSPROTO_H_
4009 struct getdents_args {
4018 register struct getdents_args /* {
4020 syscallarg(char *) buf;
4021 syscallarg(u_int) count;
4024 struct getdirentries_args ap;
4027 ap.count = uap->count;
4029 return getdirentries(td, &ap);
4033 * Set the mode mask for creation of filesystem nodes.
4037 #ifndef _SYS_SYSPROTO_H_
4045 struct umask_args /* {
4046 syscallarg(int) newmask;
4049 register struct filedesc *fdp;
4051 FILEDESC_LOCK(td->td_proc->p_fd);
4052 fdp = td->td_proc->p_fd;
4053 td->td_retval[0] = fdp->fd_cmask;
4054 fdp->fd_cmask = SCARG(uap, newmask) & ALLPERMS;
4055 FILEDESC_UNLOCK(td->td_proc->p_fd);
4060 * Void all references to file by ripping underlying filesystem
4063 #ifndef _SYS_SYSPROTO_H_
4064 struct revoke_args {
4072 register struct revoke_args /* {
4073 syscallarg(char *) path;
4080 struct nameidata nd;
4082 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, SCARG(uap, path),
4084 if ((error = namei(&nd)) != 0)
4087 NDFREE(&nd, NDF_ONLY_PNBUF);
4088 if (vp->v_type != VCHR) {
4092 error = VOP_GETATTR(vp, &vattr, td->td_ucred, td);
4097 VOP_UNLOCK(vp, 0, td);
4098 if (td->td_ucred->cr_uid != vattr.va_uid) {
4099 error = suser_cred(td->td_ucred, PRISON_ROOT);
4103 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
4106 VOP_REVOKE(vp, REVOKEALL);
4107 vn_finished_write(mp);
4114 * Convert a user file descriptor to a kernel file entry.
4115 * The file entry is locked upon returning.
4118 getvnode(fdp, fd, fpp)
4119 struct filedesc *fdp;
4131 if ((u_int)fd >= fdp->fd_nfiles ||
4132 (fp = fdp->fd_ofiles[fd]) == NULL)
4134 else if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO) {
4141 FILEDESC_UNLOCK(fdp);
4147 * Get (NFS) file handle
4149 #ifndef _SYS_SYSPROTO_H_
4158 register struct getfh_args *uap;
4160 struct nameidata nd;
4162 register struct vnode *vp;
4166 * Must be super user
4171 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, td);
4175 NDFREE(&nd, NDF_ONLY_PNBUF);
4177 bzero(&fh, sizeof(fh));
4178 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
4179 error = VFS_VPTOFH(vp, &fh.fh_fid);
4183 error = copyout(&fh, uap->fhp, sizeof (fh));
4188 * syscall for the rpc.lockd to use to translate a NFS file handle into
4189 * an open descriptor.
4191 * warning: do not remove the suser() call or this becomes one giant
4194 #ifndef _SYS_SYSPROTO_H_
4195 struct fhopen_args {
4196 const struct fhandle *u_fhp;
4203 struct fhopen_args /* {
4204 syscallarg(const struct fhandle *) u_fhp;
4205 syscallarg(int) flags;
4208 struct proc *p = td->td_proc;
4213 struct vattr *vap = &vat;
4216 register struct filedesc *fdp = p->p_fd;
4217 int fmode, mode, error, type;
4222 * Must be super user
4228 fmode = FFLAGS(SCARG(uap, flags));
4229 /* why not allow a non-read/write open for our lockd? */
4230 if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT))
4232 error = copyin(SCARG(uap,u_fhp), &fhp, sizeof(fhp));
4235 /* find the mount point */
4236 mp = vfs_getvfs(&fhp.fh_fsid);
4239 /* now give me my vnode, it gets returned to me locked */
4240 error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp);
4244 * from now on we have to make sure not
4245 * to forget about the vnode
4246 * any error that causes an abort must vput(vp)
4247 * just set error = err and 'goto bad;'.
4253 if (vp->v_type == VLNK) {
4257 if (vp->v_type == VSOCK) {
4262 if (fmode & (FWRITE | O_TRUNC)) {
4263 if (vp->v_type == VDIR) {
4267 error = vn_writechk(vp);
4275 error = VOP_ACCESS(vp, mode, td->td_ucred, td);
4279 if (fmode & O_TRUNC) {
4280 VOP_UNLOCK(vp, 0, td); /* XXX */
4281 if ((error = vn_start_write(NULL, &mp, V_WAIT | PCATCH)) != 0) {
4285 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4286 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); /* XXX */
4289 error = VOP_SETATTR(vp, vap, td->td_ucred, td);
4290 vn_finished_write(mp);
4294 error = VOP_OPEN(vp, fmode, td->td_ucred, td);
4298 * Make sure that a VM object is created for VMIO support.
4300 if (vn_canvmio(vp) == TRUE) {
4301 if ((error = vfs_object_create(vp, td, td->td_ucred)) != 0)
4308 * end of vn_open code
4311 if ((error = falloc(td, &nfp, &indx)) != 0) {
4319 * Hold an extra reference to avoid having fp ripped out
4320 * from under us while we block in the lock op
4323 nfp->f_data = (caddr_t)vp;
4324 nfp->f_flag = fmode & FMASK;
4325 nfp->f_ops = &vnops;
4326 nfp->f_type = DTYPE_VNODE;
4327 if (fmode & (O_EXLOCK | O_SHLOCK)) {
4328 lf.l_whence = SEEK_SET;
4331 if (fmode & O_EXLOCK)
4332 lf.l_type = F_WRLCK;
4334 lf.l_type = F_RDLCK;
4336 if ((fmode & FNONBLOCK) == 0)
4338 VOP_UNLOCK(vp, 0, td);
4339 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) {
4341 * The lock request failed. Normally close the
4342 * descriptor but handle the case where someone might
4343 * have dup()d or close()d it when we weren't looking.
4346 if (fdp->fd_ofiles[indx] == fp) {
4347 fdp->fd_ofiles[indx] = NULL;
4348 FILEDESC_UNLOCK(fdp);
4351 FILEDESC_UNLOCK(fdp);
4353 * release our private reference
4358 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4359 fp->f_flag |= FHASLOCK;
4361 if ((vp->v_type == VREG) && (VOP_GETVOBJECT(vp, NULL) != 0))
4362 vfs_object_create(vp, td, td->td_ucred);
4364 VOP_UNLOCK(vp, 0, td);
4366 td->td_retval[0] = indx;
4375 * Stat an (NFS) file handle.
4377 #ifndef _SYS_SYSPROTO_H_
4378 struct fhstat_args {
4379 struct fhandle *u_fhp;
4386 register struct fhstat_args /* {
4387 syscallarg(struct fhandle *) u_fhp;
4388 syscallarg(struct stat *) sb;
4398 * Must be super user
4404 error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t));
4408 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
4410 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
4412 error = vn_stat(vp, &sb, td);
4416 error = copyout(&sb, SCARG(uap, sb), sizeof(sb));
4421 * Implement fstatfs() for (NFS) file handles.
4423 #ifndef _SYS_SYSPROTO_H_
4424 struct fhstatfs_args {
4425 struct fhandle *u_fhp;
4432 struct fhstatfs_args /* {
4433 syscallarg(struct fhandle) *u_fhp;
4434 syscallarg(struct statfs) *buf;
4445 * Must be super user
4451 if ((error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t))) != 0)
4454 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
4456 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
4461 if ((error = VFS_STATFS(mp, sp, td)) != 0)
4463 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
4465 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
4466 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
4469 return (copyout(sp, SCARG(uap, buf), sizeof(*sp)));
4473 * Syscall to push extended attribute configuration information into the
4474 * VFS. Accepts a path, which it converts to a mountpoint, as well as
4475 * a command (int cmd), and attribute name and misc data. For now, the
4476 * attribute name is left in userspace for consumption by the VFS_op.
4477 * It will probably be changed to be copied into sysspace by the
4478 * syscall in the future, once issues with various consumers of the
4479 * attribute code have raised their hands.
4481 * Currently this is used only by UFS Extended Attributes.
4486 struct extattrctl_args *uap;
4488 struct vnode *filename_vp;
4489 struct nameidata nd;
4490 struct mount *mp, *mp_writable;
4491 char attrname[EXTATTR_MAXNAMELEN];
4495 * SCARG(uap, attrname) not always defined. We check again later
4496 * when we invoke the VFS call so as to pass in NULL there if needed.
4498 if (SCARG(uap, attrname) != NULL) {
4499 error = copyinstr(SCARG(uap, attrname), attrname,
4500 EXTATTR_MAXNAMELEN, NULL);
4506 * SCARG(uap, filename) not always defined. If it is, grab
4507 * a vnode lock, which VFS_EXTATTRCTL() will later release.
4510 if (SCARG(uap, filename) != NULL) {
4511 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
4512 SCARG(uap, filename), td);
4513 if ((error = namei(&nd)) != 0)
4515 filename_vp = nd.ni_vp;
4516 NDFREE(&nd, NDF_NO_VP_RELE | NDF_NO_VP_UNLOCK);
4519 /* SCARG(uap, path) always defined. */
4520 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
4521 if ((error = namei(&nd)) != 0) {
4522 if (filename_vp != NULL)
4526 mp = nd.ni_vp->v_mount;
4527 error = vn_start_write(nd.ni_vp, &mp_writable, V_WAIT | PCATCH);
4530 if (filename_vp != NULL)
4535 if (SCARG(uap, attrname) != NULL) {
4536 error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), filename_vp,
4537 SCARG(uap, attrnamespace), attrname, td);
4539 error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), filename_vp,
4540 SCARG(uap, attrnamespace), NULL, td);
4543 vn_finished_write(mp_writable);
4545 * VFS_EXTATTRCTL will have unlocked, but not de-ref'd,
4546 * filename_vp, so vrele it if it is defined.
4548 if (filename_vp != NULL)
4555 * Set a named extended attribute on a file or directory
4557 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4558 * kernelspace string pointer "attrname", userspace buffer
4559 * pointer "data", buffer length "nbytes", thread "td".
4560 * Returns: 0 on success, an error number otherwise
4562 * References: vp must be a valid reference for the duration of the call
4565 extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4566 void *data, size_t nbytes, struct thread *td)
4574 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
4576 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4577 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4579 aiov.iov_base = data;
4580 aiov.iov_len = nbytes;
4581 auio.uio_iov = &aiov;
4582 auio.uio_iovcnt = 1;
4583 auio.uio_offset = 0;
4584 if (nbytes > INT_MAX) {
4588 auio.uio_resid = nbytes;
4589 auio.uio_rw = UIO_WRITE;
4590 auio.uio_segflg = UIO_USERSPACE;
4594 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio,
4596 cnt -= auio.uio_resid;
4597 td->td_retval[0] = cnt;
4600 VOP_UNLOCK(vp, 0, td);
4601 vn_finished_write(mp);
4606 extattr_set_file(td, uap)
4608 struct extattr_set_file_args *uap;
4610 struct nameidata nd;
4611 char attrname[EXTATTR_MAXNAMELEN];
4614 error = copyinstr(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN,
4619 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
4620 if ((error = namei(&nd)) != 0)
4622 NDFREE(&nd, NDF_ONLY_PNBUF);
4624 error = extattr_set_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
4625 SCARG(uap, data), SCARG(uap, nbytes), td);
4632 extattr_set_fd(td, uap)
4634 struct extattr_set_fd_args *uap;
4637 char attrname[EXTATTR_MAXNAMELEN];
4640 error = copyinstr(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN,
4645 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
4648 error = extattr_set_vp((struct vnode *)fp->f_data,
4649 SCARG(uap, attrnamespace), attrname, SCARG(uap, data),
4650 SCARG(uap, nbytes), td);
4657 * Get a named extended attribute on a file or directory
4659 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4660 * kernelspace string pointer "attrname", userspace buffer
4661 * pointer "data", buffer length "nbytes", thread "td".
4662 * Returns: 0 on success, an error number otherwise
4664 * References: vp must be a valid reference for the duration of the call
4667 extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4668 void *data, size_t nbytes, struct thread *td)
4676 VOP_LEASE(vp, td, td->td_ucred, LEASE_READ);
4677 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4680 * Slightly unusual semantics: if the user provides a NULL data
4681 * pointer, they don't want to receive the data, just the
4682 * maximum read length.
4685 aiov.iov_base = data;
4686 aiov.iov_len = nbytes;
4687 auio.uio_iov = &aiov;
4688 auio.uio_offset = 0;
4689 if (nbytes > INT_MAX) {
4693 auio.uio_resid = nbytes;
4694 auio.uio_rw = UIO_READ;
4695 auio.uio_segflg = UIO_USERSPACE;
4698 error = VOP_GETEXTATTR(vp, attrnamespace, attrname, &auio,
4699 NULL, td->td_ucred, td);
4700 cnt -= auio.uio_resid;
4701 td->td_retval[0] = cnt;
4703 error = VOP_GETEXTATTR(vp, attrnamespace, attrname, NULL,
4704 &size, td->td_ucred, td);
4705 td->td_retval[0] = size;
4708 VOP_UNLOCK(vp, 0, td);
4713 extattr_get_file(td, uap)
4715 struct extattr_get_file_args *uap;
4717 struct nameidata nd;
4718 char attrname[EXTATTR_MAXNAMELEN];
4721 error = copyinstr(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN,
4726 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
4727 if ((error = namei(&nd)) != 0)
4729 NDFREE(&nd, NDF_ONLY_PNBUF);
4731 error = extattr_get_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
4732 SCARG(uap, data), SCARG(uap, nbytes), td);
4739 extattr_get_fd(td, uap)
4741 struct extattr_get_fd_args *uap;
4744 char attrname[EXTATTR_MAXNAMELEN];
4747 error = copyinstr(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN,
4752 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
4755 error = extattr_get_vp((struct vnode *)fp->f_data,
4756 SCARG(uap, attrnamespace), attrname, SCARG(uap, data),
4757 SCARG(uap, nbytes), td);
4764 * extattr_delete_vp(): Delete a named extended attribute on a file or
4767 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4768 * kernelspace string pointer "attrname", proc "p"
4769 * Returns: 0 on success, an error number otherwise
4771 * References: vp must be a valid reference for the duration of the call
4774 extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4780 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
4782 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4783 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4785 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL, td->td_ucred,
4788 VOP_UNLOCK(vp, 0, td);
4789 vn_finished_write(mp);
4794 extattr_delete_file(td, uap)
4796 struct extattr_delete_file_args *uap;
4798 struct nameidata nd;
4799 char attrname[EXTATTR_MAXNAMELEN];
4802 error = copyinstr(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN,
4807 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
4808 if ((error = namei(&nd)) != 0)
4810 NDFREE(&nd, NDF_ONLY_PNBUF);
4812 error = extattr_delete_vp(nd.ni_vp, SCARG(uap, attrnamespace),
4820 extattr_delete_fd(td, uap)
4822 struct extattr_delete_fd_args *uap;
4826 char attrname[EXTATTR_MAXNAMELEN];
4829 error = copyinstr(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN,
4834 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
4836 vp = (struct vnode *)fp->f_data;
4838 error = extattr_delete_vp((struct vnode *)fp->f_data,
4839 SCARG(uap, attrnamespace), attrname, td);