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;
228 for (iovcnt = 0; (cp = va_arg(ap, const char *)) != NULL; iovcnt++)
229 len += strlen(cp) + 1;
232 if (iovcnt < 4 || iovcnt & 1)
235 iovlen = iovcnt * sizeof (struct iovec);
236 MALLOC(iovp, struct iovec *, iovlen, M_MOUNT, M_WAITOK);
237 MALLOC(buf, char *, len, M_MOUNT, M_WAITOK);
240 for (i = 0; i < iovcnt; i++) {
241 cp = va_arg(ap, const char *);
242 copystr(cp, pos, len - (pos - buf), &n);
243 iovp[i].iov_base = pos;
250 auio.uio_iovcnt = iovcnt;
251 auio.uio_rw = UIO_WRITE;
252 auio.uio_segflg = UIO_SYSSPACE;
255 auio.uio_resid = len;
257 error = vfs_nmount(curthread, flags, &auio);
264 * vfs_nmount(): actually attempt a filesystem mount.
267 vfs_nmount(td, fsflags, fsoptions)
269 int fsflags; /* Flags common to all filesystems. */
270 struct uio *fsoptions; /* Options local to the filesystem. */
275 struct vfsconf *vfsp;
277 struct vfsoptlist *optlist;
279 char *buf, *fstype, *fspath;
280 int error, flag = 0, kern_flag = 0, i, len, optcnt;
281 int offset, iovcnt, fstypelen, fspathlen;
286 * Allocate memory to hold the vfsopt structures.
288 iovcnt = fsoptions->uio_iovcnt;
289 optcnt = iovcnt >> 1;
290 opt = malloc(sizeof (struct vfsopt) * optcnt,
291 M_MOUNT, M_WAITOK | M_ZERO);
294 * Count the size of the buffer for options,
295 * allocate it, and fill in the vfsopt structures.
297 cur = fsoptions->uio_iov;
298 len = fsoptions->uio_resid;
299 buf = malloc(len, M_TEMP, M_WAITOK | M_ZERO);
301 optlist = malloc(sizeof (struct vfsoptlist), M_MOUNT, M_WAITOK);
303 optlist->optbuf = buf;
304 optlist->optcnt = optcnt;
307 cur = fsoptions->uio_iov;
309 opt[i].name = buf + offset;
310 /* Ensure the name of an option is a string. */
311 if (opt[i].name[cur->iov_len - 1] != '\0') {
315 offset += cur->iov_len;
317 opt[i].len = cur->iov_len;
319 * Prevent consumers from trying to
320 * read the value of a 0 length option
321 * by setting it to NULL.
326 opt[i].value = buf + offset;
327 offset += cur->iov_len;
331 if ((error = uiomove(buf, len, fsoptions)) != 0)
335 * We need these two options before the others,
336 * and they are mandatory for any filesystem.
337 * Ensure they are NULL terminated as well.
340 error = vfs_getopt(optlist, "fstype", (void **)&fstype, &fstypelen);
341 if (error || fstype[fstypelen - 1] != '\0') {
346 error = vfs_getopt(optlist, "fspath", (void **)&fspath, &fspathlen);
347 if (error || fspath[fspathlen - 1] != '\0') {
353 * Be ultra-paranoid about making sure the type and fspath
354 * variables will fit in our mp buffers, including the
357 if (fstypelen >= MFSNAMELEN - 1 || fspathlen >= MNAMELEN - 1) {
358 error = ENAMETOOLONG;
362 if (usermount == 0) {
368 * Do not allow NFS export by non-root users.
370 if (fsflags & MNT_EXPORTED) {
376 * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users.
379 fsflags |= MNT_NOSUID | MNT_NODEV;
381 * Get vnode to be covered
383 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath, td);
384 if ((error = namei(&nd)) != 0)
386 NDFREE(&nd, NDF_ONLY_PNBUF);
388 if (fsflags & MNT_UPDATE) {
389 if ((vp->v_flag & VROOT) == 0) {
396 kern_flag = mp->mnt_kern_flag;
398 * We only allow the filesystem to be reloaded if it
399 * is currently mounted read-only.
401 if ((fsflags & MNT_RELOAD) &&
402 ((mp->mnt_flag & MNT_RDONLY) == 0)) {
404 error = EOPNOTSUPP; /* Needs translation */
408 * Only root, or the user that did the original mount is
409 * permitted to update it.
411 if (mp->mnt_stat.f_owner != td->td_ucred->cr_uid) {
418 if (vfs_busy(mp, LK_NOWAIT, 0, td)) {
423 mtx_lock(&vp->v_interlock);
424 if ((vp->v_flag & VMOUNT) != 0 || vp->v_mountedhere != NULL) {
425 mtx_unlock(&vp->v_interlock);
431 vp->v_flag |= VMOUNT;
432 mtx_unlock(&vp->v_interlock);
433 mp->mnt_flag |= fsflags &
434 (MNT_RELOAD | MNT_FORCE | MNT_UPDATE | MNT_SNAPSHOT);
435 VOP_UNLOCK(vp, 0, td);
436 mp->mnt_optnew = optlist;
440 * If the user is not root, ensure that they own the directory
441 * onto which we are attempting to mount.
443 error = VOP_GETATTR(vp, &va, td->td_ucred, td);
448 if (va.va_uid != td->td_ucred->cr_uid) {
455 if ((error = vinvalbuf(vp, V_SAVE, td->td_ucred, td, 0, 0)) != 0) {
459 if (vp->v_type != VDIR) {
464 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
465 if (!strcmp(vfsp->vfc_name, fstype))
468 /* Only load modules for root (very important!). */
474 error = securelevel_gt(td->td_ucred, 0);
479 error = linker_load_file(fstype, &lf);
480 if (error || lf == NULL) {
487 /* Look up again to see if the VFS was loaded. */
488 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
489 if (!strcmp(vfsp->vfc_name, fstype))
493 linker_file_unload(lf);
499 mtx_lock(&vp->v_interlock);
500 if ((vp->v_flag & VMOUNT) != 0 ||
501 vp->v_mountedhere != NULL) {
502 mtx_unlock(&vp->v_interlock);
507 vp->v_flag |= VMOUNT;
508 mtx_unlock(&vp->v_interlock);
511 * Allocate and initialize the filesystem.
513 mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK | M_ZERO);
514 TAILQ_INIT(&mp->mnt_nvnodelist);
515 TAILQ_INIT(&mp->mnt_reservedvnlist);
516 lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE);
517 (void)vfs_busy(mp, LK_NOWAIT, 0, td);
518 mp->mnt_op = vfsp->vfc_vfsops;
520 vfsp->vfc_refcount++;
521 mp->mnt_stat.f_type = vfsp->vfc_typenum;
522 mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
523 strncpy(mp->mnt_stat.f_fstypename, fstype, MFSNAMELEN);
524 mp->mnt_vnodecovered = vp;
525 mp->mnt_stat.f_owner = td->td_ucred->cr_uid;
526 strncpy(mp->mnt_stat.f_mntonname, fspath, MNAMELEN);
527 mp->mnt_iosize_max = DFLTPHYS;
528 VOP_UNLOCK(vp, 0, td);
530 mp->mnt_opt = optlist;
533 * Check if the fs implements the new VFS_NMOUNT()
534 * function, since the new system call was used.
536 if (mp->mnt_op->vfs_mount != NULL) {
537 printf("%s doesn't support the new mount syscall\n",
538 mp->mnt_vfc->vfc_name);
539 mtx_lock(&vp->v_interlock);
540 vp->v_flag &= ~VMOUNT;
541 mtx_unlock(&vp->v_interlock);
542 if (mp->mnt_flag & MNT_UPDATE)
545 mp->mnt_vfc->vfc_refcount--;
547 free((caddr_t)mp, M_MOUNT);
555 * Set the mount level flags.
557 if (fsflags & MNT_RDONLY)
558 mp->mnt_flag |= MNT_RDONLY;
559 else if (mp->mnt_flag & MNT_RDONLY)
560 mp->mnt_kern_flag |= MNTK_WANTRDWR;
561 mp->mnt_flag &=~ MNT_UPDATEMASK;
562 mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE);
564 * Mount the filesystem.
565 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
566 * get. No freeing of cn_pnbuf.
568 error = VFS_NMOUNT(mp, &nd, td);
569 if (mp->mnt_flag & MNT_UPDATE) {
570 if (mp->mnt_kern_flag & MNTK_WANTRDWR)
571 mp->mnt_flag &= ~MNT_RDONLY;
573 (MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_SNAPSHOT);
574 mp->mnt_kern_flag &=~ MNTK_WANTRDWR;
577 mp->mnt_kern_flag = kern_flag;
578 vfs_freeopts(mp->mnt_optnew);
580 vfs_freeopts(mp->mnt_opt);
581 mp->mnt_opt = mp->mnt_optnew;
583 if ((mp->mnt_flag & MNT_RDONLY) == 0) {
584 if (mp->mnt_syncer == NULL)
585 error = vfs_allocate_syncvnode(mp);
587 if (mp->mnt_syncer != NULL)
588 vrele(mp->mnt_syncer);
589 mp->mnt_syncer = NULL;
592 mtx_lock(&vp->v_interlock);
593 vp->v_flag &= ~VMOUNT;
594 mtx_unlock(&vp->v_interlock);
598 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
600 * Put the new filesystem on the mount list after root.
606 mtx_lock(&vp->v_interlock);
607 vp->v_flag &= ~VMOUNT;
608 vp->v_mountedhere = mp;
609 mtx_unlock(&vp->v_interlock);
610 mtx_lock(&mountlist_mtx);
611 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
612 mtx_unlock(&mountlist_mtx);
613 if (VFS_ROOT(mp, &newdp))
614 panic("mount: lost mount");
615 checkdirs(vp, newdp);
617 VOP_UNLOCK(vp, 0, td);
618 if ((mp->mnt_flag & MNT_RDONLY) == 0)
619 error = vfs_allocate_syncvnode(mp);
621 if ((error = VFS_START(mp, 0, td)) != 0) {
626 mtx_lock(&vp->v_interlock);
627 vp->v_flag &= ~VMOUNT;
628 mtx_unlock(&vp->v_interlock);
629 mp->mnt_vfc->vfc_refcount--;
631 free((caddr_t)mp, M_MOUNT);
637 vfs_freeopts(optlist);
644 #ifndef _SYS_SYSPROTO_H_
656 struct mount_args /* {
657 syscallarg(char *) type;
658 syscallarg(char *) path;
659 syscallarg(int) flags;
660 syscallarg(caddr_t) data;
667 fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK);
668 fspath = malloc(MNAMELEN, M_TEMP, M_WAITOK);
671 * vfs_mount() actually takes a kernel string for `type' and
672 * `path' now, so extract them.
674 error = copyinstr(SCARG(uap, type), fstype, MFSNAMELEN, NULL);
677 error = copyinstr(SCARG(uap, path), fspath, MNAMELEN, NULL);
680 error = vfs_mount(td, fstype, fspath, SCARG(uap, flags),
683 free(fstype, M_TEMP);
684 free(fspath, M_TEMP);
689 * vfs_mount(): actually attempt a filesystem mount.
691 * This routine is designed to be a "generic" entry point for routines
692 * that wish to mount a filesystem. All parameters except `fsdata' are
693 * pointers into kernel space. `fsdata' is currently still a pointer
697 vfs_mount(td, fstype, fspath, fsflags, fsdata)
707 struct vfsconf *vfsp;
708 int error, flag = 0, kern_flag = 0;
713 * Be ultra-paranoid about making sure the type and fspath
714 * variables will fit in our mp buffers, including the
717 if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN)
718 return (ENAMETOOLONG);
720 if (usermount == 0) {
726 * Do not allow NFS export by non-root users.
728 if (fsflags & MNT_EXPORTED) {
734 * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users.
737 fsflags |= MNT_NOSUID | MNT_NODEV;
739 * Get vnode to be covered
741 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath, td);
742 if ((error = namei(&nd)) != 0)
744 NDFREE(&nd, NDF_ONLY_PNBUF);
746 if (fsflags & MNT_UPDATE) {
747 if ((vp->v_flag & VROOT) == 0) {
753 kern_flag = mp->mnt_kern_flag;
755 * We only allow the filesystem to be reloaded if it
756 * is currently mounted read-only.
758 if ((fsflags & MNT_RELOAD) &&
759 ((mp->mnt_flag & MNT_RDONLY) == 0)) {
761 return (EOPNOTSUPP); /* Needs translation */
764 * Only root, or the user that did the original mount is
765 * permitted to update it.
767 if (mp->mnt_stat.f_owner != td->td_ucred->cr_uid) {
774 if (vfs_busy(mp, LK_NOWAIT, 0, td)) {
778 mtx_lock(&vp->v_interlock);
779 if ((vp->v_flag & VMOUNT) != 0 || vp->v_mountedhere != NULL) {
780 mtx_unlock(&vp->v_interlock);
785 vp->v_flag |= VMOUNT;
786 mtx_unlock(&vp->v_interlock);
787 mp->mnt_flag |= fsflags &
788 (MNT_RELOAD | MNT_FORCE | MNT_UPDATE | MNT_SNAPSHOT);
789 VOP_UNLOCK(vp, 0, td);
793 * If the user is not root, ensure that they own the directory
794 * onto which we are attempting to mount.
796 error = VOP_GETATTR(vp, &va, td->td_ucred, td);
801 if (va.va_uid != td->td_ucred->cr_uid) {
808 if ((error = vinvalbuf(vp, V_SAVE, td->td_ucred, td, 0, 0)) != 0) {
812 if (vp->v_type != VDIR) {
816 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
817 if (!strcmp(vfsp->vfc_name, fstype))
820 /* Only load modules for root (very important!). */
826 error = securelevel_gt(td->td_ucred, 0);
831 error = linker_load_file(fstype, &lf);
832 if (error || lf == NULL) {
839 /* Look up again to see if the VFS was loaded. */
840 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
841 if (!strcmp(vfsp->vfc_name, fstype))
845 linker_file_unload(lf);
850 mtx_lock(&vp->v_interlock);
851 if ((vp->v_flag & VMOUNT) != 0 ||
852 vp->v_mountedhere != NULL) {
853 mtx_unlock(&vp->v_interlock);
857 vp->v_flag |= VMOUNT;
858 mtx_unlock(&vp->v_interlock);
861 * Allocate and initialize the filesystem.
863 mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK | M_ZERO);
864 TAILQ_INIT(&mp->mnt_nvnodelist);
865 TAILQ_INIT(&mp->mnt_reservedvnlist);
866 lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE);
867 (void)vfs_busy(mp, LK_NOWAIT, 0, td);
868 mp->mnt_op = vfsp->vfc_vfsops;
870 vfsp->vfc_refcount++;
871 mp->mnt_stat.f_type = vfsp->vfc_typenum;
872 mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
873 strncpy(mp->mnt_stat.f_fstypename, fstype, MFSNAMELEN);
874 mp->mnt_vnodecovered = vp;
875 mp->mnt_stat.f_owner = td->td_ucred->cr_uid;
876 strncpy(mp->mnt_stat.f_mntonname, fspath, MNAMELEN);
877 mp->mnt_iosize_max = DFLTPHYS;
878 VOP_UNLOCK(vp, 0, td);
881 * Check if the fs implements the old VFS_MOUNT()
882 * function, since the old system call was used.
884 if (mp->mnt_op->vfs_mount == NULL) {
885 printf("%s doesn't support the old mount syscall\n",
886 mp->mnt_vfc->vfc_name);
887 mtx_lock(&vp->v_interlock);
888 vp->v_flag &= ~VMOUNT;
889 mtx_unlock(&vp->v_interlock);
890 if (mp->mnt_flag & MNT_UPDATE)
893 mp->mnt_vfc->vfc_refcount--;
895 free((caddr_t)mp, M_MOUNT);
902 * Set the mount level flags.
904 if (fsflags & MNT_RDONLY)
905 mp->mnt_flag |= MNT_RDONLY;
906 else if (mp->mnt_flag & MNT_RDONLY)
907 mp->mnt_kern_flag |= MNTK_WANTRDWR;
908 mp->mnt_flag &=~ MNT_UPDATEMASK;
909 mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE);
911 * Mount the filesystem.
912 * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
913 * get. No freeing of cn_pnbuf.
915 error = VFS_MOUNT(mp, fspath, fsdata, &nd, td);
916 if (mp->mnt_flag & MNT_UPDATE) {
917 if (mp->mnt_kern_flag & MNTK_WANTRDWR)
918 mp->mnt_flag &= ~MNT_RDONLY;
920 (MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_SNAPSHOT);
921 mp->mnt_kern_flag &=~ MNTK_WANTRDWR;
924 mp->mnt_kern_flag = kern_flag;
926 if ((mp->mnt_flag & MNT_RDONLY) == 0) {
927 if (mp->mnt_syncer == NULL)
928 error = vfs_allocate_syncvnode(mp);
930 if (mp->mnt_syncer != NULL)
931 vrele(mp->mnt_syncer);
932 mp->mnt_syncer = NULL;
935 mtx_lock(&vp->v_interlock);
936 vp->v_flag &= ~VMOUNT;
937 mtx_unlock(&vp->v_interlock);
941 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
943 * Put the new filesystem on the mount list after root.
949 mtx_lock(&vp->v_interlock);
950 vp->v_flag &= ~VMOUNT;
951 vp->v_mountedhere = mp;
952 mtx_unlock(&vp->v_interlock);
953 mtx_lock(&mountlist_mtx);
954 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
955 mtx_unlock(&mountlist_mtx);
956 if (VFS_ROOT(mp, &newdp))
957 panic("mount: lost mount");
958 checkdirs(vp, newdp);
960 VOP_UNLOCK(vp, 0, td);
961 if ((mp->mnt_flag & MNT_RDONLY) == 0)
962 error = vfs_allocate_syncvnode(mp);
964 if ((error = VFS_START(mp, 0, td)) != 0)
967 mtx_lock(&vp->v_interlock);
968 vp->v_flag &= ~VMOUNT;
969 mtx_unlock(&vp->v_interlock);
970 mp->mnt_vfc->vfc_refcount--;
972 free((caddr_t)mp, M_MOUNT);
979 * Scan all active processes to see if any of them have a current
980 * or root directory of `olddp'. If so, replace them with the new
984 checkdirs(olddp, newdp)
985 struct vnode *olddp, *newdp;
987 struct filedesc *fdp;
991 if (olddp->v_usecount == 1)
993 sx_slock(&allproc_lock);
994 LIST_FOREACH(p, &allproc, p_list) {
1003 if (fdp->fd_cdir == olddp) {
1005 fdp->fd_cdir = newdp;
1008 if (fdp->fd_rdir == olddp) {
1010 fdp->fd_rdir = newdp;
1013 FILEDESC_UNLOCK(fdp);
1018 sx_sunlock(&allproc_lock);
1019 if (rootvnode == olddp) {
1027 * Unmount a file system.
1029 * Note: unmount takes a path to the vnode mounted on as argument,
1030 * not special file (as before).
1032 #ifndef _SYS_SYSPROTO_H_
1033 struct unmount_args {
1042 register struct unmount_args /* {
1043 syscallarg(char *) path;
1044 syscallarg(int) flags;
1047 register struct vnode *vp;
1050 struct nameidata nd;
1052 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
1053 SCARG(uap, path), td);
1054 if ((error = namei(&nd)) != 0)
1057 NDFREE(&nd, NDF_ONLY_PNBUF);
1061 * Only root, or the user that did the original mount is
1062 * permitted to unmount this filesystem.
1064 if (mp->mnt_stat.f_owner != td->td_ucred->cr_uid) {
1073 * Don't allow unmounting the root file system.
1075 if (mp->mnt_flag & MNT_ROOTFS) {
1081 * Must be the root of the filesystem
1083 if ((vp->v_flag & VROOT) == 0) {
1088 return (dounmount(mp, SCARG(uap, flags), td));
1092 * Do the actual file system unmount.
1095 dounmount(mp, flags, td)
1100 struct vnode *coveredvp, *fsrootvp;
1104 mtx_lock(&mountlist_mtx);
1105 mp->mnt_kern_flag |= MNTK_UNMOUNT;
1106 error = lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK |
1107 ((flags & MNT_FORCE) ? 0 : LK_NOWAIT), &mountlist_mtx, td);
1109 mp->mnt_kern_flag &= ~MNTK_UNMOUNT;
1110 if (mp->mnt_kern_flag & MNTK_MWAIT)
1111 wakeup((caddr_t)mp);
1114 vn_start_write(NULL, &mp, V_WAIT);
1116 if (mp->mnt_flag & MNT_EXPUBLIC)
1117 vfs_setpublicfs(NULL, NULL, NULL);
1119 vfs_msync(mp, MNT_WAIT);
1120 async_flag = mp->mnt_flag & MNT_ASYNC;
1121 mp->mnt_flag &=~ MNT_ASYNC;
1122 cache_purgevfs(mp); /* remove cache entries for this file sys */
1123 if (mp->mnt_syncer != NULL)
1124 vrele(mp->mnt_syncer);
1125 /* Move process cdir/rdir refs on fs root to underlying vnode. */
1126 if (VFS_ROOT(mp, &fsrootvp) == 0) {
1127 if (mp->mnt_vnodecovered != NULL)
1128 checkdirs(fsrootvp, mp->mnt_vnodecovered);
1129 if (fsrootvp == rootvnode) {
1135 if (((mp->mnt_flag & MNT_RDONLY) ||
1136 (error = VFS_SYNC(mp, MNT_WAIT, td->td_ucred, td)) == 0) ||
1137 (flags & MNT_FORCE)) {
1138 error = VFS_UNMOUNT(mp, flags, td);
1140 vn_finished_write(mp);
1142 /* Undo cdir/rdir and rootvnode changes made above. */
1143 if (VFS_ROOT(mp, &fsrootvp) == 0) {
1144 if (mp->mnt_vnodecovered != NULL)
1145 checkdirs(mp->mnt_vnodecovered, fsrootvp);
1146 if (rootvnode == NULL) {
1147 rootvnode = fsrootvp;
1152 if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL)
1153 (void) vfs_allocate_syncvnode(mp);
1154 mtx_lock(&mountlist_mtx);
1155 mp->mnt_kern_flag &= ~MNTK_UNMOUNT;
1156 mp->mnt_flag |= async_flag;
1157 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK,
1158 &mountlist_mtx, td);
1159 if (mp->mnt_kern_flag & MNTK_MWAIT)
1160 wakeup((caddr_t)mp);
1163 mtx_lock(&mountlist_mtx);
1164 TAILQ_REMOVE(&mountlist, mp, mnt_list);
1165 if ((coveredvp = mp->mnt_vnodecovered) != NULL)
1166 coveredvp->v_mountedhere = NULL;
1167 mp->mnt_vfc->vfc_refcount--;
1168 if (!TAILQ_EMPTY(&mp->mnt_nvnodelist))
1169 panic("unmount: dangling vnode");
1170 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_mtx, td);
1171 lockdestroy(&mp->mnt_lock);
1172 if (coveredvp != NULL)
1174 if (mp->mnt_kern_flag & MNTK_MWAIT)
1175 wakeup((caddr_t)mp);
1176 if (mp->mnt_op->vfs_mount == NULL)
1177 vfs_freeopts(mp->mnt_opt);
1178 free((caddr_t)mp, M_MOUNT);
1183 * Sync each mounted filesystem.
1185 #ifndef _SYS_SYSPROTO_H_
1192 static int syncprt = 0;
1193 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, "");
1200 struct sync_args *uap;
1202 struct mount *mp, *nmp;
1205 mtx_lock(&mountlist_mtx);
1206 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
1207 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
1208 nmp = TAILQ_NEXT(mp, mnt_list);
1211 if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
1212 vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
1213 asyncflag = mp->mnt_flag & MNT_ASYNC;
1214 mp->mnt_flag &= ~MNT_ASYNC;
1215 vfs_msync(mp, MNT_NOWAIT);
1216 VFS_SYNC(mp, MNT_NOWAIT,
1217 ((td != NULL) ? td->td_ucred : NOCRED), td);
1218 mp->mnt_flag |= asyncflag;
1219 vn_finished_write(mp);
1221 mtx_lock(&mountlist_mtx);
1222 nmp = TAILQ_NEXT(mp, mnt_list);
1225 mtx_unlock(&mountlist_mtx);
1228 * XXX don't call vfs_bufstats() yet because that routine
1229 * was not imported in the Lite2 merge.
1234 #endif /* DIAGNOSTIC */
1239 /* XXX PRISON: could be per prison flag */
1240 static int prison_quotas;
1242 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, "");
1246 * Change filesystem quotas.
1248 #ifndef _SYS_SYSPROTO_H_
1249 struct quotactl_args {
1260 register struct quotactl_args /* {
1261 syscallarg(char *) path;
1262 syscallarg(int) cmd;
1263 syscallarg(int) uid;
1264 syscallarg(caddr_t) arg;
1269 struct nameidata nd;
1271 if (jailed(td->td_ucred) && !prison_quotas)
1273 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
1274 if ((error = namei(&nd)) != 0)
1276 NDFREE(&nd, NDF_ONLY_PNBUF);
1277 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
1281 error = VFS_QUOTACTL(mp, SCARG(uap, cmd), SCARG(uap, uid),
1282 SCARG(uap, arg), td);
1283 vn_finished_write(mp);
1288 * Get filesystem statistics.
1290 #ifndef _SYS_SYSPROTO_H_
1291 struct statfs_args {
1300 register struct statfs_args /* {
1301 syscallarg(char *) path;
1302 syscallarg(struct statfs *) buf;
1305 register struct mount *mp;
1306 register struct statfs *sp;
1308 struct nameidata nd;
1311 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
1312 if ((error = namei(&nd)) != 0)
1314 mp = nd.ni_vp->v_mount;
1316 NDFREE(&nd, NDF_ONLY_PNBUF);
1318 error = VFS_STATFS(mp, sp, td);
1321 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
1323 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
1324 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
1327 return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp)));
1331 * Get filesystem statistics.
1333 #ifndef _SYS_SYSPROTO_H_
1334 struct fstatfs_args {
1343 register struct fstatfs_args /* {
1345 syscallarg(struct statfs *) buf;
1350 register struct statfs *sp;
1354 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
1356 mp = ((struct vnode *)fp->f_data)->v_mount;
1361 error = VFS_STATFS(mp, sp, td);
1364 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
1366 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
1367 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
1370 return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp)));
1374 * Get statistics on all filesystems.
1376 #ifndef _SYS_SYSPROTO_H_
1377 struct getfsstat_args {
1386 register struct getfsstat_args /* {
1387 syscallarg(struct statfs *) buf;
1388 syscallarg(long) bufsize;
1389 syscallarg(int) flags;
1392 register struct mount *mp, *nmp;
1393 register struct statfs *sp;
1395 long count, maxcount, error;
1397 maxcount = SCARG(uap, bufsize) / sizeof(struct statfs);
1398 sfsp = (caddr_t)SCARG(uap, buf);
1400 mtx_lock(&mountlist_mtx);
1401 for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
1402 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
1403 nmp = TAILQ_NEXT(mp, mnt_list);
1406 if (sfsp && count < maxcount) {
1409 * If MNT_NOWAIT or MNT_LAZY is specified, do not
1410 * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
1411 * overrides MNT_WAIT.
1413 if (((SCARG(uap, flags) & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
1414 (SCARG(uap, flags) & MNT_WAIT)) &&
1415 (error = VFS_STATFS(mp, sp, td))) {
1416 mtx_lock(&mountlist_mtx);
1417 nmp = TAILQ_NEXT(mp, mnt_list);
1421 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
1422 error = copyout((caddr_t)sp, sfsp, sizeof(*sp));
1427 sfsp += sizeof(*sp);
1430 mtx_lock(&mountlist_mtx);
1431 nmp = TAILQ_NEXT(mp, mnt_list);
1434 mtx_unlock(&mountlist_mtx);
1435 if (sfsp && count > maxcount)
1436 td->td_retval[0] = maxcount;
1438 td->td_retval[0] = count;
1443 * Change current working directory to a given file descriptor.
1445 #ifndef _SYS_SYSPROTO_H_
1446 struct fchdir_args {
1454 struct fchdir_args /* {
1458 register struct filedesc *fdp = td->td_proc->p_fd;
1459 struct vnode *vp, *tdp, *vpold;
1464 if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0)
1466 vp = (struct vnode *)fp->f_data;
1469 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1470 if (vp->v_type != VDIR)
1473 error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td);
1474 while (!error && (mp = vp->v_mountedhere) != NULL) {
1475 if (vfs_busy(mp, 0, 0, td))
1477 error = VFS_ROOT(mp, &tdp);
1488 VOP_UNLOCK(vp, 0, td);
1490 vpold = fdp->fd_cdir;
1492 FILEDESC_UNLOCK(fdp);
1498 * Change current working directory (``.'').
1500 #ifndef _SYS_SYSPROTO_H_
1509 struct chdir_args /* {
1510 syscallarg(char *) path;
1513 register struct filedesc *fdp = td->td_proc->p_fd;
1515 struct nameidata nd;
1518 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
1519 SCARG(uap, path), td);
1520 if ((error = change_dir(&nd, td)) != 0)
1522 NDFREE(&nd, NDF_ONLY_PNBUF);
1525 fdp->fd_cdir = nd.ni_vp;
1526 FILEDESC_UNLOCK(fdp);
1532 * Helper function for raised chroot(2) security function: Refuse if
1533 * any filedescriptors are open directories.
1536 chroot_refuse_vdir_fds(fdp)
1537 struct filedesc *fdp;
1544 for (fd = 0; fd < fdp->fd_nfiles ; fd++) {
1545 fp = fget_locked(fdp, fd);
1548 if (fp->f_type == DTYPE_VNODE) {
1549 vp = (struct vnode *)fp->f_data;
1550 if (vp->v_type == VDIR) {
1551 FILEDESC_UNLOCK(fdp);
1556 FILEDESC_UNLOCK(fdp);
1561 * This sysctl determines if we will allow a process to chroot(2) if it
1562 * has a directory open:
1563 * 0: disallowed for all processes.
1564 * 1: allowed for processes that were not already chroot(2)'ed.
1565 * 2: allowed for all processes.
1568 static int chroot_allow_open_directories = 1;
1570 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW,
1571 &chroot_allow_open_directories, 0, "");
1574 * Change notion of root (``/'') directory.
1576 #ifndef _SYS_SYSPROTO_H_
1577 struct chroot_args {
1585 struct chroot_args /* {
1586 syscallarg(char *) path;
1589 register struct filedesc *fdp = td->td_proc->p_fd;
1591 struct nameidata nd;
1594 error = suser_cred(td->td_ucred, PRISON_ROOT);
1598 if (chroot_allow_open_directories == 0 ||
1599 (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) {
1600 FILEDESC_UNLOCK(fdp);
1601 error = chroot_refuse_vdir_fds(fdp);
1603 FILEDESC_UNLOCK(fdp);
1606 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
1607 SCARG(uap, path), td);
1608 if ((error = change_dir(&nd, td)) != 0)
1610 NDFREE(&nd, NDF_ONLY_PNBUF);
1613 fdp->fd_rdir = nd.ni_vp;
1614 if (!fdp->fd_jdir) {
1615 fdp->fd_jdir = nd.ni_vp;
1618 FILEDESC_UNLOCK(fdp);
1624 * Common routine for chroot and chdir.
1628 register struct nameidata *ndp;
1638 if (vp->v_type != VDIR)
1641 error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td);
1645 VOP_UNLOCK(vp, 0, td);
1650 * Check permissions, allocate an open file structure,
1651 * and call the device open routine if any.
1653 #ifndef _SYS_SYSPROTO_H_
1663 register struct open_args /* {
1664 syscallarg(char *) path;
1665 syscallarg(int) flags;
1666 syscallarg(int) mode;
1669 struct proc *p = td->td_proc;
1670 struct filedesc *fdp = p->p_fd;
1675 int cmode, flags, oflags;
1677 int type, indx, error;
1679 struct nameidata nd;
1681 oflags = SCARG(uap, flags);
1682 if ((oflags & O_ACCMODE) == O_ACCMODE)
1684 flags = FFLAGS(oflags);
1685 error = falloc(td, &nfp, &indx);
1690 cmode = ((SCARG(uap, mode) &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
1691 FILEDESC_UNLOCK(fdp);
1692 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
1693 td->td_dupfd = -indx - 1; /* XXX check for fdopen */
1695 * Bump the ref count to prevent another process from closing
1696 * the descriptor while we are blocked in vn_open()
1699 error = vn_open(&nd, &flags, cmode);
1702 * release our own reference
1707 * handle special fdopen() case. bleh. dupfdopen() is
1708 * responsible for dropping the old contents of ofiles[indx]
1711 if ((error == ENODEV || error == ENXIO) &&
1712 td->td_dupfd >= 0 && /* XXX from fdopen */
1714 dupfdopen(td, fdp, indx, td->td_dupfd, flags, error)) == 0) {
1715 td->td_retval[0] = indx;
1719 * Clean up the descriptor, but only if another thread hadn't
1720 * replaced or closed it.
1723 if (fdp->fd_ofiles[indx] == fp) {
1724 fdp->fd_ofiles[indx] = NULL;
1725 FILEDESC_UNLOCK(fdp);
1728 FILEDESC_UNLOCK(fdp);
1730 if (error == ERESTART)
1735 NDFREE(&nd, NDF_ONLY_PNBUF);
1739 * There should be 2 references on the file, one from the descriptor
1740 * table, and one for us.
1742 * Handle the case where someone closed the file (via its file
1743 * descriptor) while we were blocked. The end result should look
1744 * like opening the file succeeded but it was immediately closed.
1748 if (fp->f_count == 1) {
1749 KASSERT(fdp->fd_ofiles[indx] != fp,
1750 ("Open file descriptor lost all refs"));
1751 FILEDESC_UNLOCK(fdp);
1753 VOP_UNLOCK(vp, 0, td);
1754 vn_close(vp, flags & FMASK, fp->f_cred, td);
1756 td->td_retval[0] = indx;
1760 fp->f_data = (caddr_t)vp;
1761 fp->f_flag = flags & FMASK;
1763 fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE);
1764 FILEDESC_UNLOCK(fdp);
1766 VOP_UNLOCK(vp, 0, td);
1767 if (flags & (O_EXLOCK | O_SHLOCK)) {
1768 lf.l_whence = SEEK_SET;
1771 if (flags & O_EXLOCK)
1772 lf.l_type = F_WRLCK;
1774 lf.l_type = F_RDLCK;
1776 if ((flags & FNONBLOCK) == 0)
1778 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0)
1780 fp->f_flag |= FHASLOCK;
1782 if (flags & O_TRUNC) {
1783 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
1785 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
1788 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1789 error = VOP_SETATTR(vp, &vat, td->td_ucred, td);
1790 VOP_UNLOCK(vp, 0, td);
1791 vn_finished_write(mp);
1795 /* assert that vn_open created a backing object if one is needed */
1796 KASSERT(!vn_canvmio(vp) || VOP_GETVOBJECT(vp, NULL) == 0,
1797 ("open: vmio vnode has no backing object after vn_open"));
1799 * Release our private reference, leaving the one associated with
1800 * the descriptor table intact.
1803 td->td_retval[0] = indx;
1807 if (fdp->fd_ofiles[indx] == fp) {
1808 fdp->fd_ofiles[indx] = NULL;
1809 FILEDESC_UNLOCK(fdp);
1812 FILEDESC_UNLOCK(fdp);
1820 #ifndef _SYS_SYSPROTO_H_
1821 struct ocreat_args {
1829 register struct ocreat_args /* {
1830 syscallarg(char *) path;
1831 syscallarg(int) mode;
1834 struct open_args /* {
1835 syscallarg(char *) path;
1836 syscallarg(int) flags;
1837 syscallarg(int) mode;
1840 SCARG(&nuap, path) = SCARG(uap, path);
1841 SCARG(&nuap, mode) = SCARG(uap, mode);
1842 SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
1843 return (open(td, &nuap));
1845 #endif /* COMPAT_43 */
1848 * Create a special file.
1850 #ifndef _SYS_SYSPROTO_H_
1861 register struct mknod_args /* {
1862 syscallarg(char *) path;
1863 syscallarg(int) mode;
1864 syscallarg(int) dev;
1872 struct nameidata nd;
1874 switch (SCARG(uap, mode) & S_IFMT) {
1880 error = suser_cred(td->td_ucred, PRISON_ROOT);
1887 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), td);
1888 if ((error = namei(&nd)) != 0)
1896 FILEDESC_LOCK(td->td_proc->p_fd);
1897 vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ td->td_proc->p_fd->fd_cmask;
1898 FILEDESC_UNLOCK(td->td_proc->p_fd);
1899 vattr.va_rdev = SCARG(uap, dev);
1902 switch (SCARG(uap, mode) & S_IFMT) {
1903 case S_IFMT: /* used by badsect to flag bad sectors */
1904 vattr.va_type = VBAD;
1907 vattr.va_type = VCHR;
1910 vattr.va_type = VBLK;
1920 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1921 NDFREE(&nd, NDF_ONLY_PNBUF);
1923 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1928 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1930 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE);
1932 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp,
1933 &nd.ni_cnd, &vattr);
1938 NDFREE(&nd, NDF_ONLY_PNBUF);
1940 vn_finished_write(mp);
1941 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod");
1942 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod");
1947 * Create a named pipe.
1949 #ifndef _SYS_SYSPROTO_H_
1950 struct mkfifo_args {
1959 register struct mkfifo_args /* {
1960 syscallarg(char *) path;
1961 syscallarg(int) mode;
1967 struct nameidata nd;
1971 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), td);
1972 if ((error = namei(&nd)) != 0)
1974 if (nd.ni_vp != NULL) {
1975 NDFREE(&nd, NDF_ONLY_PNBUF);
1980 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1981 NDFREE(&nd, NDF_ONLY_PNBUF);
1983 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1988 vattr.va_type = VFIFO;
1989 FILEDESC_LOCK(td->td_proc->p_fd);
1990 vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ td->td_proc->p_fd->fd_cmask;
1991 FILEDESC_UNLOCK(td->td_proc->p_fd);
1992 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1993 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
1996 NDFREE(&nd, NDF_ONLY_PNBUF);
1998 vn_finished_write(mp);
2003 * Make a hard file link.
2005 #ifndef _SYS_SYSPROTO_H_
2015 register struct link_args /* {
2016 syscallarg(char *) path;
2017 syscallarg(char *) link;
2022 struct nameidata nd;
2026 NDINIT(&nd, LOOKUP, FOLLOW|NOOBJ, UIO_USERSPACE, SCARG(uap, path), td);
2027 if ((error = namei(&nd)) != 0)
2029 NDFREE(&nd, NDF_ONLY_PNBUF);
2031 if (vp->v_type == VDIR) {
2033 return (EPERM); /* POSIX */
2035 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
2039 NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), td);
2040 if ((error = namei(&nd)) == 0) {
2041 if (nd.ni_vp != NULL) {
2045 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
2046 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2047 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
2049 NDFREE(&nd, NDF_ONLY_PNBUF);
2053 vn_finished_write(mp);
2054 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link");
2055 ASSERT_VOP_UNLOCKED(nd.ni_vp, "link");
2060 * Make a symbolic link.
2062 #ifndef _SYS_SYSPROTO_H_
2063 struct symlink_args {
2072 register struct symlink_args /* {
2073 syscallarg(char *) path;
2074 syscallarg(char *) link;
2081 struct nameidata nd;
2083 path = uma_zalloc(namei_zone, M_WAITOK);
2084 if ((error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL)) != 0)
2088 NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), td);
2089 if ((error = namei(&nd)) != 0)
2092 NDFREE(&nd, NDF_ONLY_PNBUF);
2098 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
2099 NDFREE(&nd, NDF_ONLY_PNBUF);
2101 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
2106 FILEDESC_LOCK(td->td_proc->p_fd);
2107 vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask;
2108 FILEDESC_UNLOCK(td->td_proc->p_fd);
2109 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
2110 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path);
2111 NDFREE(&nd, NDF_ONLY_PNBUF);
2115 vn_finished_write(mp);
2116 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink");
2117 ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink");
2119 uma_zfree(namei_zone, path);
2124 * Delete a whiteout from the filesystem.
2130 register struct undelete_args /* {
2131 syscallarg(char *) path;
2136 struct nameidata nd;
2140 NDINIT(&nd, DELETE, LOCKPARENT|DOWHITEOUT, UIO_USERSPACE,
2141 SCARG(uap, path), td);
2146 if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) {
2147 NDFREE(&nd, NDF_ONLY_PNBUF);
2153 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
2154 NDFREE(&nd, NDF_ONLY_PNBUF);
2156 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
2160 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
2161 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE);
2162 NDFREE(&nd, NDF_ONLY_PNBUF);
2164 vn_finished_write(mp);
2165 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "undelete");
2166 ASSERT_VOP_UNLOCKED(nd.ni_vp, "undelete");
2171 * Delete a name from the filesystem.
2173 #ifndef _SYS_SYSPROTO_H_
2174 struct unlink_args {
2182 struct unlink_args /* {
2183 syscallarg(char *) path;
2189 struct nameidata nd;
2193 NDINIT(&nd, DELETE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), td);
2194 if ((error = namei(&nd)) != 0)
2197 if (vp->v_type == VDIR)
2198 error = EPERM; /* POSIX */
2201 * The root of a mounted filesystem cannot be deleted.
2203 * XXX: can this only be a VDIR case?
2205 if (vp->v_flag & VROOT)
2208 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
2209 NDFREE(&nd, NDF_ONLY_PNBUF);
2212 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
2216 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2217 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2219 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
2220 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd);
2222 NDFREE(&nd, NDF_ONLY_PNBUF);
2225 vn_finished_write(mp);
2226 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink");
2227 ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink");
2232 * Reposition read/write file offset.
2234 #ifndef _SYS_SYSPROTO_H_
2245 register struct lseek_args /* {
2247 syscallarg(int) pad;
2248 syscallarg(off_t) offset;
2249 syscallarg(int) whence;
2252 struct ucred *cred = td->td_ucred;
2259 if ((error = fget(td, uap->fd, &fp)) != 0)
2261 if (fp->f_type != DTYPE_VNODE) {
2265 vp = (struct vnode *)fp->f_data;
2266 noneg = (vp->v_type != VCHR);
2267 offset = SCARG(uap, offset);
2268 switch (SCARG(uap, whence)) {
2271 (fp->f_offset < 0 ||
2272 (offset > 0 && fp->f_offset > OFF_MAX - offset)))
2274 offset += fp->f_offset;
2277 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2278 error = VOP_GETATTR(vp, &vattr, cred, td);
2279 VOP_UNLOCK(vp, 0, td);
2283 (vattr.va_size > OFF_MAX ||
2284 (offset > 0 && vattr.va_size > OFF_MAX - offset)))
2286 offset += vattr.va_size;
2294 if (noneg && offset < 0)
2296 fp->f_offset = offset;
2297 *(off_t *)(td->td_retval) = fp->f_offset;
2302 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
2304 * Reposition read/write file offset.
2306 #ifndef _SYS_SYSPROTO_H_
2307 struct olseek_args {
2316 register struct olseek_args /* {
2318 syscallarg(long) offset;
2319 syscallarg(int) whence;
2322 struct lseek_args /* {
2324 syscallarg(int) pad;
2325 syscallarg(off_t) offset;
2326 syscallarg(int) whence;
2330 SCARG(&nuap, fd) = SCARG(uap, fd);
2331 SCARG(&nuap, offset) = SCARG(uap, offset);
2332 SCARG(&nuap, whence) = SCARG(uap, whence);
2333 error = lseek(td, &nuap);
2336 #endif /* COMPAT_43 */
2339 * Check access permissions using passed credentials.
2342 vn_access(vp, user_flags, cred, td)
2350 /* Flags == 0 means only check for existence. */
2354 if (user_flags & R_OK)
2356 if (user_flags & W_OK)
2358 if (user_flags & X_OK)
2360 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
2361 error = VOP_ACCESS(vp, flags, cred, td);
2367 * Check access permissions using "real" credentials.
2369 #ifndef _SYS_SYSPROTO_H_
2370 struct access_args {
2378 register struct access_args /* {
2379 syscallarg(char *) path;
2380 syscallarg(int) flags;
2383 struct ucred *cred, *tmpcred;
2384 register struct vnode *vp;
2386 struct nameidata nd;
2389 * Create and modify a temporary credential instead of one that
2390 * is potentially shared. This could also mess up socket
2391 * buffer accounting which can run in an interrupt context.
2393 * XXX - Depending on how "threads" are finally implemented, it
2394 * may be better to explicitly pass the credential to namei()
2395 * rather than to modify the potentially shared process structure.
2397 cred = td->td_ucred;
2398 tmpcred = crdup(cred);
2399 tmpcred->cr_uid = cred->cr_ruid;
2400 tmpcred->cr_groups[0] = cred->cr_rgid;
2401 td->td_ucred = tmpcred;
2402 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2403 SCARG(uap, path), td);
2404 if ((error = namei(&nd)) != 0)
2408 error = vn_access(vp, SCARG(uap, flags), tmpcred, td);
2409 NDFREE(&nd, NDF_ONLY_PNBUF);
2412 td->td_ucred = cred;
2418 * Check access permissions using "effective" credentials.
2420 #ifndef _SYS_SYSPROTO_H_
2421 struct eaccess_args {
2429 register struct eaccess_args /* {
2430 syscallarg(char *) path;
2431 syscallarg(int) flags;
2434 struct nameidata nd;
2438 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2439 SCARG(uap, path), td);
2440 if ((error = namei(&nd)) != 0)
2444 error = vn_access(vp, SCARG(uap, flags), td->td_ucred, td);
2445 NDFREE(&nd, NDF_ONLY_PNBUF);
2450 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
2452 * Get file status; this version follows links.
2454 #ifndef _SYS_SYSPROTO_H_
2464 register struct ostat_args /* {
2465 syscallarg(char *) path;
2466 syscallarg(struct ostat *) ub;
2472 struct nameidata nd;
2474 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2475 SCARG(uap, path), td);
2476 if ((error = namei(&nd)) != 0)
2478 NDFREE(&nd, NDF_ONLY_PNBUF);
2479 error = vn_stat(nd.ni_vp, &sb, td);
2484 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
2489 * Get file status; this version does not follow links.
2491 #ifndef _SYS_SYSPROTO_H_
2492 struct olstat_args {
2501 register struct olstat_args /* {
2502 syscallarg(char *) path;
2503 syscallarg(struct ostat *) ub;
2510 struct nameidata nd;
2512 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2513 SCARG(uap, path), td);
2514 if ((error = namei(&nd)) != 0)
2517 error = vn_stat(vp, &sb, td);
2518 NDFREE(&nd, NDF_ONLY_PNBUF);
2523 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
2528 * Convert from an old to a new stat structure.
2536 ost->st_dev = st->st_dev;
2537 ost->st_ino = st->st_ino;
2538 ost->st_mode = st->st_mode;
2539 ost->st_nlink = st->st_nlink;
2540 ost->st_uid = st->st_uid;
2541 ost->st_gid = st->st_gid;
2542 ost->st_rdev = st->st_rdev;
2543 if (st->st_size < (quad_t)1 << 32)
2544 ost->st_size = st->st_size;
2547 ost->st_atime = st->st_atime;
2548 ost->st_mtime = st->st_mtime;
2549 ost->st_ctime = st->st_ctime;
2550 ost->st_blksize = st->st_blksize;
2551 ost->st_blocks = st->st_blocks;
2552 ost->st_flags = st->st_flags;
2553 ost->st_gen = st->st_gen;
2555 #endif /* COMPAT_43 || COMPAT_SUNOS */
2558 * Get file status; this version follows links.
2560 #ifndef _SYS_SYSPROTO_H_
2570 register struct stat_args /* {
2571 syscallarg(char *) path;
2572 syscallarg(struct stat *) ub;
2577 struct nameidata nd;
2579 #ifdef LOOKUP_SHARED
2580 NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | NOOBJ,
2581 UIO_USERSPACE, SCARG(uap, path), td);
2583 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2584 SCARG(uap, path), td);
2586 if ((error = namei(&nd)) != 0)
2588 error = vn_stat(nd.ni_vp, &sb, td);
2589 NDFREE(&nd, NDF_ONLY_PNBUF);
2593 error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));
2598 * Get file status; this version does not follow links.
2600 #ifndef _SYS_SYSPROTO_H_
2610 register struct lstat_args /* {
2611 syscallarg(char *) path;
2612 syscallarg(struct stat *) ub;
2618 struct nameidata nd;
2620 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2621 SCARG(uap, path), td);
2622 if ((error = namei(&nd)) != 0)
2625 error = vn_stat(vp, &sb, td);
2626 NDFREE(&nd, NDF_ONLY_PNBUF);
2630 error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));
2635 * Implementation of the NetBSD stat() function.
2636 * XXX This should probably be collapsed with the FreeBSD version,
2637 * as the differences are only due to vn_stat() clearing spares at
2638 * the end of the structures. vn_stat could be split to avoid this,
2639 * and thus collapse the following to close to zero code.
2646 nsb->st_dev = sb->st_dev;
2647 nsb->st_ino = sb->st_ino;
2648 nsb->st_mode = sb->st_mode;
2649 nsb->st_nlink = sb->st_nlink;
2650 nsb->st_uid = sb->st_uid;
2651 nsb->st_gid = sb->st_gid;
2652 nsb->st_rdev = sb->st_rdev;
2653 nsb->st_atimespec = sb->st_atimespec;
2654 nsb->st_mtimespec = sb->st_mtimespec;
2655 nsb->st_ctimespec = sb->st_ctimespec;
2656 nsb->st_size = sb->st_size;
2657 nsb->st_blocks = sb->st_blocks;
2658 nsb->st_blksize = sb->st_blksize;
2659 nsb->st_flags = sb->st_flags;
2660 nsb->st_gen = sb->st_gen;
2661 nsb->st_qspare[0] = sb->st_qspare[0];
2662 nsb->st_qspare[1] = sb->st_qspare[1];
2665 #ifndef _SYS_SYSPROTO_H_
2675 register struct nstat_args /* {
2676 syscallarg(char *) path;
2677 syscallarg(struct nstat *) ub;
2683 struct nameidata nd;
2685 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2686 SCARG(uap, path), td);
2687 if ((error = namei(&nd)) != 0)
2689 NDFREE(&nd, NDF_ONLY_PNBUF);
2690 error = vn_stat(nd.ni_vp, &sb, td);
2694 cvtnstat(&sb, &nsb);
2695 error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb));
2700 * NetBSD lstat. Get file status; this version does not follow links.
2702 #ifndef _SYS_SYSPROTO_H_
2712 register struct nlstat_args /* {
2713 syscallarg(char *) path;
2714 syscallarg(struct nstat *) ub;
2721 struct nameidata nd;
2723 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2724 SCARG(uap, path), td);
2725 if ((error = namei(&nd)) != 0)
2728 NDFREE(&nd, NDF_ONLY_PNBUF);
2729 error = vn_stat(vp, &sb, td);
2733 cvtnstat(&sb, &nsb);
2734 error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb));
2739 * Get configurable pathname variables.
2741 #ifndef _SYS_SYSPROTO_H_
2742 struct pathconf_args {
2751 register struct pathconf_args /* {
2752 syscallarg(char *) path;
2753 syscallarg(int) name;
2757 struct nameidata nd;
2759 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2760 SCARG(uap, path), td);
2761 if ((error = namei(&nd)) != 0)
2763 NDFREE(&nd, NDF_ONLY_PNBUF);
2764 error = VOP_PATHCONF(nd.ni_vp, SCARG(uap, name), td->td_retval);
2770 * Return target name of a symbolic link.
2772 #ifndef _SYS_SYSPROTO_H_
2773 struct readlink_args {
2783 register struct readlink_args /* {
2784 syscallarg(char *) path;
2785 syscallarg(char *) buf;
2786 syscallarg(int) count;
2789 register struct vnode *vp;
2793 struct nameidata nd;
2795 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
2796 SCARG(uap, path), td);
2797 if ((error = namei(&nd)) != 0)
2799 NDFREE(&nd, NDF_ONLY_PNBUF);
2801 if (vp->v_type != VLNK)
2804 aiov.iov_base = SCARG(uap, buf);
2805 aiov.iov_len = SCARG(uap, count);
2806 auio.uio_iov = &aiov;
2807 auio.uio_iovcnt = 1;
2808 auio.uio_offset = 0;
2809 auio.uio_rw = UIO_READ;
2810 auio.uio_segflg = UIO_USERSPACE;
2812 auio.uio_resid = SCARG(uap, count);
2813 error = VOP_READLINK(vp, &auio, td->td_ucred);
2816 td->td_retval[0] = SCARG(uap, count) - auio.uio_resid;
2821 * Common implementation code for chflags() and fchflags().
2824 setfflags(td, vp, flags)
2834 * Prevent non-root users from setting flags on devices. When
2835 * a device is reused, users can retain ownership of the device
2836 * if they are allowed to set flags and programs assume that
2837 * chown can't fail when done as root.
2839 if (vp->v_type == VCHR || vp->v_type == VBLK) {
2840 error = suser_cred(td->td_ucred, PRISON_ROOT);
2845 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2847 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2848 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2850 vattr.va_flags = flags;
2851 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2852 VOP_UNLOCK(vp, 0, td);
2853 vn_finished_write(mp);
2858 * Change flags of a file given a path name.
2860 #ifndef _SYS_SYSPROTO_H_
2861 struct chflags_args {
2870 register struct chflags_args /* {
2871 syscallarg(char *) path;
2872 syscallarg(int) flags;
2876 struct nameidata nd;
2878 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
2879 if ((error = namei(&nd)) != 0)
2881 NDFREE(&nd, NDF_ONLY_PNBUF);
2882 error = setfflags(td, nd.ni_vp, SCARG(uap, flags));
2888 * Change flags of a file given a file descriptor.
2890 #ifndef _SYS_SYSPROTO_H_
2891 struct fchflags_args {
2900 register struct fchflags_args /* {
2902 syscallarg(int) flags;
2908 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
2910 error = setfflags(td, (struct vnode *) fp->f_data, SCARG(uap, flags));
2916 * Common implementation code for chmod(), lchmod() and fchmod().
2919 setfmode(td, vp, mode)
2928 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2930 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2931 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2933 vattr.va_mode = mode & ALLPERMS;
2934 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2935 VOP_UNLOCK(vp, 0, td);
2936 vn_finished_write(mp);
2941 * Change mode of a file given path name.
2943 #ifndef _SYS_SYSPROTO_H_
2953 register struct chmod_args /* {
2954 syscallarg(char *) path;
2955 syscallarg(int) mode;
2959 struct nameidata nd;
2961 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
2962 if ((error = namei(&nd)) != 0)
2964 NDFREE(&nd, NDF_ONLY_PNBUF);
2965 error = setfmode(td, nd.ni_vp, SCARG(uap, mode));
2971 * Change mode of a file given path name (don't follow links.)
2973 #ifndef _SYS_SYSPROTO_H_
2974 struct lchmod_args {
2983 register struct lchmod_args /* {
2984 syscallarg(char *) path;
2985 syscallarg(int) mode;
2989 struct nameidata nd;
2991 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
2992 if ((error = namei(&nd)) != 0)
2994 NDFREE(&nd, NDF_ONLY_PNBUF);
2995 error = setfmode(td, nd.ni_vp, SCARG(uap, mode));
3001 * Change mode of a file given a file descriptor.
3003 #ifndef _SYS_SYSPROTO_H_
3004 struct fchmod_args {
3013 register struct fchmod_args /* {
3015 syscallarg(int) mode;
3022 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3024 vp = (struct vnode *)fp->f_data;
3025 error = setfmode(td, (struct vnode *)fp->f_data, SCARG(uap, mode));
3031 * Common implementation for chown(), lchown(), and fchown()
3034 setfown(td, vp, uid, gid)
3044 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
3046 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3047 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3051 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
3052 VOP_UNLOCK(vp, 0, td);
3053 vn_finished_write(mp);
3058 * Set ownership given a path name.
3060 #ifndef _SYS_SYSPROTO_H_
3071 register struct chown_args /* {
3072 syscallarg(char *) path;
3073 syscallarg(int) uid;
3074 syscallarg(int) gid;
3078 struct nameidata nd;
3080 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
3081 if ((error = namei(&nd)) != 0)
3083 NDFREE(&nd, NDF_ONLY_PNBUF);
3084 error = setfown(td, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid));
3090 * Set ownership given a path name, do not cross symlinks.
3092 #ifndef _SYS_SYSPROTO_H_
3093 struct lchown_args {
3103 register struct lchown_args /* {
3104 syscallarg(char *) path;
3105 syscallarg(int) uid;
3106 syscallarg(int) gid;
3110 struct nameidata nd;
3112 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
3113 if ((error = namei(&nd)) != 0)
3115 NDFREE(&nd, NDF_ONLY_PNBUF);
3116 error = setfown(td, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid));
3122 * Set ownership given a file descriptor.
3124 #ifndef _SYS_SYSPROTO_H_
3125 struct fchown_args {
3135 register struct fchown_args /* {
3137 syscallarg(int) uid;
3138 syscallarg(int) gid;
3145 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3147 vp = (struct vnode *)fp->f_data;
3148 error = setfown(td, (struct vnode *)fp->f_data,
3149 SCARG(uap, uid), SCARG(uap, gid));
3155 * Common implementation code for utimes(), lutimes(), and futimes().
3158 getutimes(usrtvp, tsp)
3159 const struct timeval *usrtvp;
3160 struct timespec *tsp;
3162 struct timeval tv[2];
3165 if (usrtvp == NULL) {
3167 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]);
3170 if ((error = copyin(usrtvp, tv, sizeof (tv))) != 0)
3172 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]);
3173 TIMEVAL_TO_TIMESPEC(&tv[1], &tsp[1]);
3179 * Common implementation code for utimes(), lutimes(), and futimes().
3182 setutimes(td, vp, ts, nullflag)
3185 const struct timespec *ts;
3192 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
3194 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3195 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3197 vattr.va_atime = ts[0];
3198 vattr.va_mtime = ts[1];
3200 vattr.va_vaflags |= VA_UTIMES_NULL;
3201 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
3202 VOP_UNLOCK(vp, 0, td);
3203 vn_finished_write(mp);
3208 * Set the access and modification times of a file.
3210 #ifndef _SYS_SYSPROTO_H_
3211 struct utimes_args {
3213 struct timeval *tptr;
3220 register struct utimes_args /* {
3221 syscallarg(char *) path;
3222 syscallarg(struct timeval *) tptr;
3225 struct timespec ts[2];
3226 struct timeval *usrtvp;
3228 struct nameidata nd;
3230 usrtvp = SCARG(uap, tptr);
3231 if ((error = getutimes(usrtvp, ts)) != 0)
3233 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
3234 if ((error = namei(&nd)) != 0)
3236 NDFREE(&nd, NDF_ONLY_PNBUF);
3237 error = setutimes(td, nd.ni_vp, ts, usrtvp == NULL);
3243 * Set the access and modification times of a file.
3245 #ifndef _SYS_SYSPROTO_H_
3246 struct lutimes_args {
3248 struct timeval *tptr;
3255 register struct lutimes_args /* {
3256 syscallarg(char *) path;
3257 syscallarg(struct timeval *) tptr;
3260 struct timespec ts[2];
3261 struct timeval *usrtvp;
3263 struct nameidata nd;
3265 usrtvp = SCARG(uap, tptr);
3266 if ((error = getutimes(usrtvp, ts)) != 0)
3268 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
3269 if ((error = namei(&nd)) != 0)
3271 NDFREE(&nd, NDF_ONLY_PNBUF);
3272 error = setutimes(td, nd.ni_vp, ts, usrtvp == NULL);
3278 * Set the access and modification times of a file.
3280 #ifndef _SYS_SYSPROTO_H_
3281 struct futimes_args {
3283 struct timeval *tptr;
3290 register struct futimes_args /* {
3291 syscallarg(int ) fd;
3292 syscallarg(struct timeval *) tptr;
3295 struct timespec ts[2];
3297 struct timeval *usrtvp;
3300 usrtvp = SCARG(uap, tptr);
3301 if ((error = getutimes(usrtvp, ts)) != 0)
3303 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3305 error = setutimes(td, (struct vnode *)fp->f_data, ts, usrtvp == NULL);
3311 * Truncate a file given its path name.
3313 #ifndef _SYS_SYSPROTO_H_
3314 struct truncate_args {
3324 register struct truncate_args /* {
3325 syscallarg(char *) path;
3326 syscallarg(int) pad;
3327 syscallarg(off_t) length;
3334 struct nameidata nd;
3336 if (uap->length < 0)
3338 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
3339 if ((error = namei(&nd)) != 0)
3342 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
3346 NDFREE(&nd, NDF_ONLY_PNBUF);
3347 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3348 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3349 if (vp->v_type == VDIR)
3351 else if ((error = vn_writechk(vp)) == 0 &&
3352 (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) {
3354 vattr.va_size = SCARG(uap, length);
3355 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
3358 vn_finished_write(mp);
3363 * Truncate a file given a file descriptor.
3365 #ifndef _SYS_SYSPROTO_H_
3366 struct ftruncate_args {
3376 register struct ftruncate_args /* {
3378 syscallarg(int) pad;
3379 syscallarg(off_t) length;
3388 if (uap->length < 0)
3390 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3392 if ((fp->f_flag & FWRITE) == 0) {
3396 vp = (struct vnode *)fp->f_data;
3397 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
3401 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3402 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3403 if (vp->v_type == VDIR)
3405 else if ((error = vn_writechk(vp)) == 0) {
3407 vattr.va_size = SCARG(uap, length);
3408 error = VOP_SETATTR(vp, &vattr, fp->f_cred, td);
3410 VOP_UNLOCK(vp, 0, td);
3411 vn_finished_write(mp);
3416 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
3418 * Truncate a file given its path name.
3420 #ifndef _SYS_SYSPROTO_H_
3421 struct otruncate_args {
3430 register struct otruncate_args /* {
3431 syscallarg(char *) path;
3432 syscallarg(long) length;
3435 struct truncate_args /* {
3436 syscallarg(char *) path;
3437 syscallarg(int) pad;
3438 syscallarg(off_t) length;
3441 SCARG(&nuap, path) = SCARG(uap, path);
3442 SCARG(&nuap, length) = SCARG(uap, length);
3443 return (truncate(td, &nuap));
3447 * Truncate a file given a file descriptor.
3449 #ifndef _SYS_SYSPROTO_H_
3450 struct oftruncate_args {
3459 register struct oftruncate_args /* {
3461 syscallarg(long) length;
3464 struct ftruncate_args /* {
3466 syscallarg(int) pad;
3467 syscallarg(off_t) length;
3470 SCARG(&nuap, fd) = SCARG(uap, fd);
3471 SCARG(&nuap, length) = SCARG(uap, length);
3472 return (ftruncate(td, &nuap));
3474 #endif /* COMPAT_43 || COMPAT_SUNOS */
3477 * Sync an open file.
3479 #ifndef _SYS_SYSPROTO_H_
3488 struct fsync_args /* {
3500 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3502 vp = (struct vnode *)fp->f_data;
3503 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
3507 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3508 if (VOP_GETVOBJECT(vp, &obj) == 0) {
3509 vm_object_page_clean(obj, 0, 0, 0);
3511 error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, td);
3513 if (error == 0 && vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP))
3514 error = softdep_fsync(vp);
3517 VOP_UNLOCK(vp, 0, td);
3518 vn_finished_write(mp);
3524 * Rename files. Source and destination must either both be directories,
3525 * or both not be directories. If target is a directory, it must be empty.
3527 #ifndef _SYS_SYSPROTO_H_
3528 struct rename_args {
3537 register struct rename_args /* {
3538 syscallarg(char *) from;
3539 syscallarg(char *) to;
3543 struct vnode *tvp, *fvp, *tdvp;
3544 struct nameidata fromnd, tond;
3548 NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE,
3549 SCARG(uap, from), td);
3550 if ((error = namei(&fromnd)) != 0)
3553 if ((error = vn_start_write(fvp, &mp, V_WAIT | PCATCH)) != 0) {
3554 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3555 vrele(fromnd.ni_dvp);
3559 NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | NOOBJ,
3560 UIO_USERSPACE, SCARG(uap, to), td);
3561 if (fromnd.ni_vp->v_type == VDIR)
3562 tond.ni_cnd.cn_flags |= WILLBEDIR;
3563 if ((error = namei(&tond)) != 0) {
3564 /* Translate error code for rename("dir1", "dir2/."). */
3565 if (error == EISDIR && fvp->v_type == VDIR)
3567 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3568 vrele(fromnd.ni_dvp);
3575 if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
3578 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
3586 * If source is the same as the destination (that is the
3587 * same inode number with the same name in the same directory),
3588 * then there is nothing to do.
3590 if (fvp == tvp && fromnd.ni_dvp == tdvp &&
3591 fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen &&
3592 !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr,
3593 fromnd.ni_cnd.cn_namelen))
3597 VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE);
3598 if (fromnd.ni_dvp != tdvp) {
3599 VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3602 VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE);
3604 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
3605 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
3606 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3607 NDFREE(&tond, NDF_ONLY_PNBUF);
3609 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3610 NDFREE(&tond, NDF_ONLY_PNBUF);
3617 vrele(fromnd.ni_dvp);
3620 vrele(tond.ni_startdir);
3621 vn_finished_write(mp);
3622 ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename");
3623 ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename");
3624 ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename");
3625 ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename");
3627 if (fromnd.ni_startdir)
3628 vrele(fromnd.ni_startdir);
3635 * Make a directory file.
3637 #ifndef _SYS_SYSPROTO_H_
3647 register struct mkdir_args /* {
3648 syscallarg(char *) path;
3649 syscallarg(int) mode;
3653 return vn_mkdir(uap->path, uap->mode, UIO_USERSPACE, td);
3657 vn_mkdir(path, mode, segflg, td)
3660 enum uio_seg segflg;
3667 struct nameidata nd;
3671 NDINIT(&nd, CREATE, LOCKPARENT, segflg, path, td);
3672 nd.ni_cnd.cn_flags |= WILLBEDIR;
3673 if ((error = namei(&nd)) != 0)
3677 NDFREE(&nd, NDF_ONLY_PNBUF);
3682 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
3683 NDFREE(&nd, NDF_ONLY_PNBUF);
3685 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
3690 vattr.va_type = VDIR;
3691 FILEDESC_LOCK(td->td_proc->p_fd);
3692 vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask;
3693 FILEDESC_UNLOCK(td->td_proc->p_fd);
3694 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3695 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
3696 NDFREE(&nd, NDF_ONLY_PNBUF);
3700 vn_finished_write(mp);
3701 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir");
3702 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir");
3707 * Remove a directory file.
3709 #ifndef _SYS_SYSPROTO_H_
3718 struct rmdir_args /* {
3719 syscallarg(char *) path;
3725 struct nameidata nd;
3729 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE,
3730 SCARG(uap, path), td);
3731 if ((error = namei(&nd)) != 0)
3734 if (vp->v_type != VDIR) {
3739 * No rmdir "." please.
3741 if (nd.ni_dvp == vp) {
3746 * The root of a mounted filesystem cannot be deleted.
3748 if (vp->v_flag & VROOT) {
3752 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
3753 NDFREE(&nd, NDF_ONLY_PNBUF);
3754 if (nd.ni_dvp == vp)
3759 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
3763 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3764 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3765 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
3766 vn_finished_write(mp);
3768 NDFREE(&nd, NDF_ONLY_PNBUF);
3769 if (nd.ni_dvp == vp)
3774 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir");
3775 ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir");
3781 * Read a block of directory entries in a file system independent format.
3783 #ifndef _SYS_SYSPROTO_H_
3784 struct ogetdirentries_args {
3792 ogetdirentries(td, uap)
3794 register struct ogetdirentries_args /* {
3796 syscallarg(char *) buf;
3797 syscallarg(u_int) count;
3798 syscallarg(long *) basep;
3803 struct uio auio, kuio;
3804 struct iovec aiov, kiov;
3805 struct dirent *dp, *edp;
3807 int error, eofflag, readcnt;
3810 /* XXX arbitrary sanity limit on `count'. */
3811 if (SCARG(uap, count) > 64 * 1024)
3813 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3815 if ((fp->f_flag & FREAD) == 0) {
3819 vp = (struct vnode *)fp->f_data;
3821 if (vp->v_type != VDIR) {
3825 aiov.iov_base = SCARG(uap, buf);
3826 aiov.iov_len = SCARG(uap, count);
3827 auio.uio_iov = &aiov;
3828 auio.uio_iovcnt = 1;
3829 auio.uio_rw = UIO_READ;
3830 auio.uio_segflg = UIO_USERSPACE;
3832 auio.uio_resid = SCARG(uap, count);
3833 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3834 loff = auio.uio_offset = fp->f_offset;
3835 # if (BYTE_ORDER != LITTLE_ENDIAN)
3836 if (vp->v_mount->mnt_maxsymlinklen <= 0) {
3837 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
3839 fp->f_offset = auio.uio_offset;
3844 kuio.uio_iov = &kiov;
3845 kuio.uio_segflg = UIO_SYSSPACE;
3846 kiov.iov_len = SCARG(uap, count);
3847 MALLOC(dirbuf, caddr_t, SCARG(uap, count), M_TEMP, M_WAITOK);
3848 kiov.iov_base = dirbuf;
3849 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag,
3851 fp->f_offset = kuio.uio_offset;
3853 readcnt = SCARG(uap, count) - kuio.uio_resid;
3854 edp = (struct dirent *)&dirbuf[readcnt];
3855 for (dp = (struct dirent *)dirbuf; dp < edp; ) {
3856 # if (BYTE_ORDER == LITTLE_ENDIAN)
3858 * The expected low byte of
3859 * dp->d_namlen is our dp->d_type.
3860 * The high MBZ byte of dp->d_namlen
3861 * is our dp->d_namlen.
3863 dp->d_type = dp->d_namlen;
3867 * The dp->d_type is the high byte
3868 * of the expected dp->d_namlen,
3869 * so must be zero'ed.
3873 if (dp->d_reclen > 0) {
3874 dp = (struct dirent *)
3875 ((char *)dp + dp->d_reclen);
3882 error = uiomove(dirbuf, readcnt, &auio);
3884 FREE(dirbuf, M_TEMP);
3886 VOP_UNLOCK(vp, 0, td);
3891 if (SCARG(uap, count) == auio.uio_resid) {
3892 if (union_dircheckp) {
3893 error = union_dircheckp(td, &vp, fp);
3901 if ((vp->v_flag & VROOT) &&
3902 (vp->v_mount->mnt_flag & MNT_UNION)) {
3903 struct vnode *tvp = vp;
3904 vp = vp->v_mount->mnt_vnodecovered;
3906 fp->f_data = (caddr_t) vp;
3912 error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
3915 td->td_retval[0] = SCARG(uap, count) - auio.uio_resid;
3918 #endif /* COMPAT_43 */
3921 * Read a block of directory entries in a file system independent format.
3923 #ifndef _SYS_SYSPROTO_H_
3924 struct getdirentries_args {
3932 getdirentries(td, uap)
3934 register struct getdirentries_args /* {
3936 syscallarg(char *) buf;
3937 syscallarg(u_int) count;
3938 syscallarg(long *) basep;
3948 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
3950 if ((fp->f_flag & FREAD) == 0) {
3954 vp = (struct vnode *)fp->f_data;
3956 if (vp->v_type != VDIR) {
3960 aiov.iov_base = SCARG(uap, buf);
3961 aiov.iov_len = SCARG(uap, count);
3962 auio.uio_iov = &aiov;
3963 auio.uio_iovcnt = 1;
3964 auio.uio_rw = UIO_READ;
3965 auio.uio_segflg = UIO_USERSPACE;
3967 auio.uio_resid = SCARG(uap, count);
3968 /* vn_lock(vp, LK_SHARED | LK_RETRY, td); */
3969 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3970 loff = auio.uio_offset = fp->f_offset;
3971 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL);
3972 fp->f_offset = auio.uio_offset;
3973 VOP_UNLOCK(vp, 0, td);
3978 if (SCARG(uap, count) == auio.uio_resid) {
3979 if (union_dircheckp) {
3980 error = union_dircheckp(td, &vp, fp);
3988 if ((vp->v_flag & VROOT) &&
3989 (vp->v_mount->mnt_flag & MNT_UNION)) {
3990 struct vnode *tvp = vp;
3991 vp = vp->v_mount->mnt_vnodecovered;
3993 fp->f_data = (caddr_t) vp;
3999 if (SCARG(uap, basep) != NULL) {
4000 error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
4003 td->td_retval[0] = SCARG(uap, count) - auio.uio_resid;
4007 #ifndef _SYS_SYSPROTO_H_
4008 struct getdents_args {
4017 register struct getdents_args /* {
4019 syscallarg(char *) buf;
4020 syscallarg(u_int) count;
4023 struct getdirentries_args ap;
4026 ap.count = uap->count;
4028 return getdirentries(td, &ap);
4032 * Set the mode mask for creation of filesystem nodes.
4036 #ifndef _SYS_SYSPROTO_H_
4044 struct umask_args /* {
4045 syscallarg(int) newmask;
4048 register struct filedesc *fdp;
4050 FILEDESC_LOCK(td->td_proc->p_fd);
4051 fdp = td->td_proc->p_fd;
4052 td->td_retval[0] = fdp->fd_cmask;
4053 fdp->fd_cmask = SCARG(uap, newmask) & ALLPERMS;
4054 FILEDESC_UNLOCK(td->td_proc->p_fd);
4059 * Void all references to file by ripping underlying filesystem
4062 #ifndef _SYS_SYSPROTO_H_
4063 struct revoke_args {
4071 register struct revoke_args /* {
4072 syscallarg(char *) path;
4079 struct nameidata nd;
4081 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, SCARG(uap, path),
4083 if ((error = namei(&nd)) != 0)
4086 NDFREE(&nd, NDF_ONLY_PNBUF);
4087 if (vp->v_type != VCHR) {
4091 error = VOP_GETATTR(vp, &vattr, td->td_ucred, td);
4096 VOP_UNLOCK(vp, 0, td);
4097 if (td->td_ucred->cr_uid != vattr.va_uid) {
4098 error = suser_cred(td->td_ucred, PRISON_ROOT);
4102 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
4105 VOP_REVOKE(vp, REVOKEALL);
4106 vn_finished_write(mp);
4113 * Convert a user file descriptor to a kernel file entry.
4114 * The file entry is locked upon returning.
4117 getvnode(fdp, fd, fpp)
4118 struct filedesc *fdp;
4130 if ((u_int)fd >= fdp->fd_nfiles ||
4131 (fp = fdp->fd_ofiles[fd]) == NULL)
4133 else if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO) {
4140 FILEDESC_UNLOCK(fdp);
4146 * Get (NFS) file handle
4148 #ifndef _SYS_SYSPROTO_H_
4157 register struct getfh_args *uap;
4159 struct nameidata nd;
4161 register struct vnode *vp;
4165 * Must be super user
4170 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, td);
4174 NDFREE(&nd, NDF_ONLY_PNBUF);
4176 bzero(&fh, sizeof(fh));
4177 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
4178 error = VFS_VPTOFH(vp, &fh.fh_fid);
4182 error = copyout(&fh, uap->fhp, sizeof (fh));
4187 * syscall for the rpc.lockd to use to translate a NFS file handle into
4188 * an open descriptor.
4190 * warning: do not remove the suser() call or this becomes one giant
4193 #ifndef _SYS_SYSPROTO_H_
4194 struct fhopen_args {
4195 const struct fhandle *u_fhp;
4202 struct fhopen_args /* {
4203 syscallarg(const struct fhandle *) u_fhp;
4204 syscallarg(int) flags;
4207 struct proc *p = td->td_proc;
4212 struct vattr *vap = &vat;
4215 register struct filedesc *fdp = p->p_fd;
4216 int fmode, mode, error, type;
4221 * Must be super user
4227 fmode = FFLAGS(SCARG(uap, flags));
4228 /* why not allow a non-read/write open for our lockd? */
4229 if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT))
4231 error = copyin(SCARG(uap,u_fhp), &fhp, sizeof(fhp));
4234 /* find the mount point */
4235 mp = vfs_getvfs(&fhp.fh_fsid);
4238 /* now give me my vnode, it gets returned to me locked */
4239 error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp);
4243 * from now on we have to make sure not
4244 * to forget about the vnode
4245 * any error that causes an abort must vput(vp)
4246 * just set error = err and 'goto bad;'.
4252 if (vp->v_type == VLNK) {
4256 if (vp->v_type == VSOCK) {
4261 if (fmode & (FWRITE | O_TRUNC)) {
4262 if (vp->v_type == VDIR) {
4266 error = vn_writechk(vp);
4274 error = VOP_ACCESS(vp, mode, td->td_ucred, td);
4278 if (fmode & O_TRUNC) {
4279 VOP_UNLOCK(vp, 0, td); /* XXX */
4280 if ((error = vn_start_write(NULL, &mp, V_WAIT | PCATCH)) != 0) {
4284 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4285 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); /* XXX */
4288 error = VOP_SETATTR(vp, vap, td->td_ucred, td);
4289 vn_finished_write(mp);
4293 error = VOP_OPEN(vp, fmode, td->td_ucred, td);
4297 * Make sure that a VM object is created for VMIO support.
4299 if (vn_canvmio(vp) == TRUE) {
4300 if ((error = vfs_object_create(vp, td, td->td_ucred)) != 0)
4307 * end of vn_open code
4310 if ((error = falloc(td, &nfp, &indx)) != 0) {
4318 * Hold an extra reference to avoid having fp ripped out
4319 * from under us while we block in the lock op
4322 nfp->f_data = (caddr_t)vp;
4323 nfp->f_flag = fmode & FMASK;
4324 nfp->f_ops = &vnops;
4325 nfp->f_type = DTYPE_VNODE;
4326 if (fmode & (O_EXLOCK | O_SHLOCK)) {
4327 lf.l_whence = SEEK_SET;
4330 if (fmode & O_EXLOCK)
4331 lf.l_type = F_WRLCK;
4333 lf.l_type = F_RDLCK;
4335 if ((fmode & FNONBLOCK) == 0)
4337 VOP_UNLOCK(vp, 0, td);
4338 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) {
4340 * The lock request failed. Normally close the
4341 * descriptor but handle the case where someone might
4342 * have dup()d or close()d it when we weren't looking.
4345 if (fdp->fd_ofiles[indx] == fp) {
4346 fdp->fd_ofiles[indx] = NULL;
4347 FILEDESC_UNLOCK(fdp);
4350 FILEDESC_UNLOCK(fdp);
4352 * release our private reference
4357 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4358 fp->f_flag |= FHASLOCK;
4360 if ((vp->v_type == VREG) && (VOP_GETVOBJECT(vp, NULL) != 0))
4361 vfs_object_create(vp, td, td->td_ucred);
4363 VOP_UNLOCK(vp, 0, td);
4365 td->td_retval[0] = indx;
4374 * Stat an (NFS) file handle.
4376 #ifndef _SYS_SYSPROTO_H_
4377 struct fhstat_args {
4378 struct fhandle *u_fhp;
4385 register struct fhstat_args /* {
4386 syscallarg(struct fhandle *) u_fhp;
4387 syscallarg(struct stat *) sb;
4397 * Must be super user
4403 error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t));
4407 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
4409 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
4411 error = vn_stat(vp, &sb, td);
4415 error = copyout(&sb, SCARG(uap, sb), sizeof(sb));
4420 * Implement fstatfs() for (NFS) file handles.
4422 #ifndef _SYS_SYSPROTO_H_
4423 struct fhstatfs_args {
4424 struct fhandle *u_fhp;
4431 struct fhstatfs_args /* {
4432 syscallarg(struct fhandle) *u_fhp;
4433 syscallarg(struct statfs) *buf;
4444 * Must be super user
4450 if ((error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t))) != 0)
4453 if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
4455 if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
4460 if ((error = VFS_STATFS(mp, sp, td)) != 0)
4462 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
4464 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
4465 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
4468 return (copyout(sp, SCARG(uap, buf), sizeof(*sp)));
4472 * Syscall to push extended attribute configuration information into the
4473 * VFS. Accepts a path, which it converts to a mountpoint, as well as
4474 * a command (int cmd), and attribute name and misc data. For now, the
4475 * attribute name is left in userspace for consumption by the VFS_op.
4476 * It will probably be changed to be copied into sysspace by the
4477 * syscall in the future, once issues with various consumers of the
4478 * attribute code have raised their hands.
4480 * Currently this is used only by UFS Extended Attributes.
4485 struct extattrctl_args *uap;
4487 struct vnode *filename_vp;
4488 struct nameidata nd;
4489 struct mount *mp, *mp_writable;
4490 char attrname[EXTATTR_MAXNAMELEN];
4494 * SCARG(uap, attrname) not always defined. We check again later
4495 * when we invoke the VFS call so as to pass in NULL there if needed.
4497 if (SCARG(uap, attrname) != NULL) {
4498 error = copyinstr(SCARG(uap, attrname), attrname,
4499 EXTATTR_MAXNAMELEN, NULL);
4505 * SCARG(uap, filename) not always defined. If it is, grab
4506 * a vnode lock, which VFS_EXTATTRCTL() will later release.
4509 if (SCARG(uap, filename) != NULL) {
4510 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
4511 SCARG(uap, filename), td);
4512 if ((error = namei(&nd)) != 0)
4514 filename_vp = nd.ni_vp;
4515 NDFREE(&nd, NDF_NO_VP_RELE | NDF_NO_VP_UNLOCK);
4518 /* SCARG(uap, path) always defined. */
4519 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
4520 if ((error = namei(&nd)) != 0) {
4521 if (filename_vp != NULL)
4525 mp = nd.ni_vp->v_mount;
4526 error = vn_start_write(nd.ni_vp, &mp_writable, V_WAIT | PCATCH);
4529 if (filename_vp != NULL)
4534 if (SCARG(uap, attrname) != NULL) {
4535 error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), filename_vp,
4536 SCARG(uap, attrnamespace), attrname, td);
4538 error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), filename_vp,
4539 SCARG(uap, attrnamespace), NULL, td);
4542 vn_finished_write(mp_writable);
4544 * VFS_EXTATTRCTL will have unlocked, but not de-ref'd,
4545 * filename_vp, so vrele it if it is defined.
4547 if (filename_vp != NULL)
4554 * Set a named extended attribute on a file or directory
4556 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4557 * kernelspace string pointer "attrname", userspace buffer
4558 * pointer "data", buffer length "nbytes", thread "td".
4559 * Returns: 0 on success, an error number otherwise
4561 * References: vp must be a valid reference for the duration of the call
4564 extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4565 void *data, size_t nbytes, struct thread *td)
4573 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
4575 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4576 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4578 aiov.iov_base = data;
4579 aiov.iov_len = nbytes;
4580 auio.uio_iov = &aiov;
4581 auio.uio_iovcnt = 1;
4582 auio.uio_offset = 0;
4583 if (nbytes > INT_MAX) {
4587 auio.uio_resid = nbytes;
4588 auio.uio_rw = UIO_WRITE;
4589 auio.uio_segflg = UIO_USERSPACE;
4593 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio,
4595 cnt -= auio.uio_resid;
4596 td->td_retval[0] = cnt;
4599 VOP_UNLOCK(vp, 0, td);
4600 vn_finished_write(mp);
4605 extattr_set_file(td, uap)
4607 struct extattr_set_file_args *uap;
4609 struct nameidata nd;
4610 char attrname[EXTATTR_MAXNAMELEN];
4613 error = copyinstr(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN,
4618 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
4619 if ((error = namei(&nd)) != 0)
4621 NDFREE(&nd, NDF_ONLY_PNBUF);
4623 error = extattr_set_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
4624 SCARG(uap, data), SCARG(uap, nbytes), td);
4631 extattr_set_fd(td, uap)
4633 struct extattr_set_fd_args *uap;
4636 char attrname[EXTATTR_MAXNAMELEN];
4639 error = copyinstr(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN,
4644 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
4647 error = extattr_set_vp((struct vnode *)fp->f_data,
4648 SCARG(uap, attrnamespace), attrname, SCARG(uap, data),
4649 SCARG(uap, nbytes), td);
4656 * Get a named extended attribute on a file or directory
4658 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4659 * kernelspace string pointer "attrname", userspace buffer
4660 * pointer "data", buffer length "nbytes", thread "td".
4661 * Returns: 0 on success, an error number otherwise
4663 * References: vp must be a valid reference for the duration of the call
4666 extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4667 void *data, size_t nbytes, struct thread *td)
4675 VOP_LEASE(vp, td, td->td_ucred, LEASE_READ);
4676 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4679 * Slightly unusual semantics: if the user provides a NULL data
4680 * pointer, they don't want to receive the data, just the
4681 * maximum read length.
4684 aiov.iov_base = data;
4685 aiov.iov_len = nbytes;
4686 auio.uio_iov = &aiov;
4687 auio.uio_offset = 0;
4688 if (nbytes > INT_MAX) {
4692 auio.uio_resid = nbytes;
4693 auio.uio_rw = UIO_READ;
4694 auio.uio_segflg = UIO_USERSPACE;
4697 error = VOP_GETEXTATTR(vp, attrnamespace, attrname, &auio,
4698 NULL, td->td_ucred, td);
4699 cnt -= auio.uio_resid;
4700 td->td_retval[0] = cnt;
4702 error = VOP_GETEXTATTR(vp, attrnamespace, attrname, NULL,
4703 &size, td->td_ucred, td);
4704 td->td_retval[0] = size;
4707 VOP_UNLOCK(vp, 0, td);
4712 extattr_get_file(td, uap)
4714 struct extattr_get_file_args *uap;
4716 struct nameidata nd;
4717 char attrname[EXTATTR_MAXNAMELEN];
4720 error = copyinstr(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN,
4725 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
4726 if ((error = namei(&nd)) != 0)
4728 NDFREE(&nd, NDF_ONLY_PNBUF);
4730 error = extattr_get_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
4731 SCARG(uap, data), SCARG(uap, nbytes), td);
4738 extattr_get_fd(td, uap)
4740 struct extattr_get_fd_args *uap;
4743 char attrname[EXTATTR_MAXNAMELEN];
4746 error = copyinstr(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN,
4751 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
4754 error = extattr_get_vp((struct vnode *)fp->f_data,
4755 SCARG(uap, attrnamespace), attrname, SCARG(uap, data),
4756 SCARG(uap, nbytes), td);
4763 * extattr_delete_vp(): Delete a named extended attribute on a file or
4766 * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4767 * kernelspace string pointer "attrname", proc "p"
4768 * Returns: 0 on success, an error number otherwise
4770 * References: vp must be a valid reference for the duration of the call
4773 extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4779 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
4781 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4782 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4784 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL, td->td_ucred,
4787 VOP_UNLOCK(vp, 0, td);
4788 vn_finished_write(mp);
4793 extattr_delete_file(td, uap)
4795 struct extattr_delete_file_args *uap;
4797 struct nameidata nd;
4798 char attrname[EXTATTR_MAXNAMELEN];
4801 error = copyinstr(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN,
4806 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
4807 if ((error = namei(&nd)) != 0)
4809 NDFREE(&nd, NDF_ONLY_PNBUF);
4811 error = extattr_delete_vp(nd.ni_vp, SCARG(uap, attrnamespace),
4819 extattr_delete_fd(td, uap)
4821 struct extattr_delete_fd_args *uap;
4825 char attrname[EXTATTR_MAXNAMELEN];
4828 error = copyinstr(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN,
4833 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
4835 vp = (struct vnode *)fp->f_data;
4837 error = extattr_delete_vp((struct vnode *)fp->f_data,
4838 SCARG(uap, attrnamespace), attrname, td);