Make modules work again part 1: linkup vfs, rename Makefile.module files,
[dragonfly.git] / sys / kern / vfs_syscalls.c
1 /*
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.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
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.
25  *
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
36  * SUCH DAMAGE.
37  *
38  *      @(#)vfs_syscalls.c      8.13 (Berkeley) 4/15/94
39  * $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $
40  * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.15 2003/08/07 21:17:23 dillon Exp $
41  */
42
43 /* For 4.3 integer FS ID compatibility */
44 #include "opt_compat.h"
45
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/buf.h>
49 #include <sys/sysent.h>
50 #include <sys/malloc.h>
51 #include <sys/mount.h>
52 #include <sys/sysproto.h>
53 #include <sys/filedesc.h>
54 #include <sys/kernel.h>
55 #include <sys/fcntl.h>
56 #include <sys/file.h>
57 #include <sys/linker.h>
58 #include <sys/stat.h>
59 #include <sys/unistd.h>
60 #include <sys/vnode.h>
61 #include <sys/proc.h>
62 #include <sys/namei.h>
63 #include <sys/dirent.h>
64 #include <sys/extattr.h>
65
66 #include <machine/limits.h>
67 #include <vfs/union/union.h>
68 #include <sys/sysctl.h>
69 #include <vm/vm.h>
70 #include <vm/vm_object.h>
71 #include <vm/vm_zone.h>
72 #include <vm/vm_page.h>
73
74 #include <sys/file2.h>
75
76 static int change_dir __P((struct nameidata *ndp, struct thread *td));
77 static void checkdirs __P((struct vnode *olddp));
78 static int chroot_refuse_vdir_fds __P((struct filedesc *fdp));
79 static int getutimes __P((const struct timeval *, struct timespec *));
80 static int setfown __P((struct vnode *, uid_t, gid_t));
81 static int setfmode __P((struct vnode *, int));
82 static int setfflags __P((struct vnode *, int));
83 static int setutimes __P((struct vnode *, const struct timespec *, int));
84 static int      usermount = 0;  /* if 1, non-root can mount fs. */
85
86 int (*union_dircheckp) __P((struct thread *, struct vnode **, struct file *));
87
88 SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, "");
89
90 /*
91  * Virtual File System System Calls
92  */
93
94 /*
95  * Mount a file system.
96  */
97 /*
98  * mount_args(char *type, char *path, int flags, caddr_t data)
99  */
100 /* ARGSUSED */
101 int
102 mount(struct mount_args *uap)
103 {
104         struct thread *td = curthread;
105         struct proc *p = td->td_proc;
106         struct vnode *vp;
107         struct mount *mp;
108         struct vfsconf *vfsp;
109         int error, flag = 0, flag2 = 0;
110         struct vattr va;
111 #ifdef COMPAT_43
112         u_long fstypenum;
113 #endif
114         struct nameidata nd;
115         char fstypename[MFSNAMELEN];
116
117         if (usermount == 0 && (error = suser(td)))
118                 return (error);
119         /*
120          * Do not allow NFS export by non-root users.
121          */
122         if (SCARG(uap, flags) & MNT_EXPORTED) {
123                 error = suser(td);
124                 if (error)
125                         return (error);
126         }
127         /*
128          * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users
129          */
130         if (suser(td)) 
131                 SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
132         /*
133          * Get vnode to be covered
134          */
135         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
136             SCARG(uap, path), td);
137         if ((error = namei(&nd)) != 0)
138                 return (error);
139         NDFREE(&nd, NDF_ONLY_PNBUF);
140         vp = nd.ni_vp;
141         if (SCARG(uap, flags) & MNT_UPDATE) {
142                 if ((vp->v_flag & VROOT) == 0) {
143                         vput(vp);
144                         return (EINVAL);
145                 }
146                 mp = vp->v_mount;
147                 flag = mp->mnt_flag;
148                 flag2 = mp->mnt_kern_flag;
149                 /*
150                  * We only allow the filesystem to be reloaded if it
151                  * is currently mounted read-only.
152                  */
153                 if ((SCARG(uap, flags) & MNT_RELOAD) &&
154                     ((mp->mnt_flag & MNT_RDONLY) == 0)) {
155                         vput(vp);
156                         return (EOPNOTSUPP);    /* Needs translation */
157                 }
158                 /*
159                  * Only root, or the user that did the original mount is
160                  * permitted to update it.
161                  */
162                 if (mp->mnt_stat.f_owner != p->p_ucred->cr_uid &&
163                     (error = suser(td))) {
164                         vput(vp);
165                         return (error);
166                 }
167                 if (vfs_busy(mp, LK_NOWAIT, 0, td)) {
168                         vput(vp);
169                         return (EBUSY);
170                 }
171                 lwkt_gettoken(&vp->v_interlock);
172                 if ((vp->v_flag & VMOUNT) != 0 ||
173                     vp->v_mountedhere != NULL) {
174                         lwkt_reltoken(&vp->v_interlock);
175                         vfs_unbusy(mp, td);
176                         vput(vp);
177                         return (EBUSY);
178                 }
179                 vp->v_flag |= VMOUNT;
180                 lwkt_reltoken(&vp->v_interlock);
181                 mp->mnt_flag |=
182                     SCARG(uap, flags) & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE);
183                 VOP_UNLOCK(vp, 0, td);
184                 goto update;
185         }
186         /*
187          * If the user is not root, ensure that they own the directory
188          * onto which we are attempting to mount.
189          */
190         if ((error = VOP_GETATTR(vp, &va, td)) ||
191             (va.va_uid != p->p_ucred->cr_uid &&
192              (error = suser(td)))) {
193                 vput(vp);
194                 return (error);
195         }
196         if ((error = vinvalbuf(vp, V_SAVE, td, 0, 0)) != 0) {
197                 vput(vp);
198                 return (error);
199         }
200         if (vp->v_type != VDIR) {
201                 vput(vp);
202                 return (ENOTDIR);
203         }
204 #ifdef COMPAT_43
205         /*
206          * Historically filesystem types were identified by number. If we
207          * get an integer for the filesystem type instead of a string, we
208          * check to see if it matches one of the historic filesystem types.
209          */
210         fstypenum = (uintptr_t)SCARG(uap, type);
211         if (fstypenum < maxvfsconf) {
212                 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
213                         if (vfsp->vfc_typenum == fstypenum)
214                                 break;
215                 if (vfsp == NULL) {
216                         vput(vp);
217                         return (ENODEV);
218                 }
219                 strncpy(fstypename, vfsp->vfc_name, MFSNAMELEN);
220         } else
221 #endif /* COMPAT_43 */
222         if ((error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL)) != 0) {
223                 vput(vp);
224                 return (error);
225         }
226         for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
227                 if (!strcmp(vfsp->vfc_name, fstypename))
228                         break;
229         if (vfsp == NULL) {
230                 linker_file_t lf;
231
232                 /* Only load modules for root (very important!) */
233                 if ((error = suser(td)) != 0) {
234                         vput(vp);
235                         return error;
236                 }
237                 error = linker_load_file(fstypename, &lf);
238                 if (error || lf == NULL) {
239                         vput(vp);
240                         if (lf == NULL)
241                                 error = ENODEV;
242                         return error;
243                 }
244                 lf->userrefs++;
245                 /* lookup again, see if the VFS was loaded */
246                 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
247                         if (!strcmp(vfsp->vfc_name, fstypename))
248                                 break;
249                 if (vfsp == NULL) {
250                         lf->userrefs--;
251                         linker_file_unload(lf);
252                         vput(vp);
253                         return (ENODEV);
254                 }
255         }
256         lwkt_gettoken(&vp->v_interlock);
257         if ((vp->v_flag & VMOUNT) != 0 ||
258             vp->v_mountedhere != NULL) {
259                 lwkt_reltoken(&vp->v_interlock);
260                 vput(vp);
261                 return (EBUSY);
262         }
263         vp->v_flag |= VMOUNT;
264         lwkt_reltoken(&vp->v_interlock);
265
266         /*
267          * Allocate and initialize the filesystem.
268          */
269         mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK);
270         bzero((char *)mp, (u_long)sizeof(struct mount));
271         TAILQ_INIT(&mp->mnt_nvnodelist);
272         TAILQ_INIT(&mp->mnt_reservedvnlist);
273         mp->mnt_nvnodelistsize = 0;
274         lockinit(&mp->mnt_lock, 0, "vfslock", 0, LK_NOPAUSE);
275         (void)vfs_busy(mp, LK_NOWAIT, 0, td);
276         mp->mnt_op = vfsp->vfc_vfsops;
277         mp->mnt_vfc = vfsp;
278         vfsp->vfc_refcount++;
279         mp->mnt_stat.f_type = vfsp->vfc_typenum;
280         mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
281         strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
282         mp->mnt_vnodecovered = vp;
283         mp->mnt_stat.f_owner = p->p_ucred->cr_uid;
284         mp->mnt_iosize_max = DFLTPHYS;
285         VOP_UNLOCK(vp, 0, td);
286 update:
287         /*
288          * Set the mount level flags.
289          */
290         if (SCARG(uap, flags) & MNT_RDONLY)
291                 mp->mnt_flag |= MNT_RDONLY;
292         else if (mp->mnt_flag & MNT_RDONLY)
293                 mp->mnt_kern_flag |= MNTK_WANTRDWR;
294         mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
295             MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME |
296             MNT_NOSYMFOLLOW | MNT_IGNORE |
297             MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR);
298         mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC |
299             MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE |
300             MNT_NOSYMFOLLOW | MNT_IGNORE |
301             MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR);
302         /*
303          * Mount the filesystem.
304          * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
305          * get.  No freeing of cn_pnbuf.
306          */
307         error = VFS_MOUNT(mp, SCARG(uap, path), SCARG(uap, data), &nd, td);
308         if (mp->mnt_flag & MNT_UPDATE) {
309                 if (mp->mnt_kern_flag & MNTK_WANTRDWR)
310                         mp->mnt_flag &= ~MNT_RDONLY;
311                 mp->mnt_flag &=~ (MNT_UPDATE | MNT_RELOAD | MNT_FORCE);
312                 mp->mnt_kern_flag &=~ MNTK_WANTRDWR;
313                 if (error) {
314                         mp->mnt_flag = flag;
315                         mp->mnt_kern_flag = flag2;
316                 }
317                 if ((mp->mnt_flag & MNT_RDONLY) == 0) {
318                         if (mp->mnt_syncer == NULL)
319                                 error = vfs_allocate_syncvnode(mp);
320                 } else {
321                         if (mp->mnt_syncer != NULL)
322                                 vrele(mp->mnt_syncer);
323                         mp->mnt_syncer = NULL;
324                 }
325                 vfs_unbusy(mp, td);
326                 lwkt_gettoken(&vp->v_interlock);
327                 vp->v_flag &= ~VMOUNT;
328                 lwkt_reltoken(&vp->v_interlock);
329                 vrele(vp);
330                 return (error);
331         }
332         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
333         /*
334          * Put the new filesystem on the mount list after root.
335          */
336         cache_purge(vp);
337         if (!error) {
338                 lwkt_gettoken(&vp->v_interlock);
339                 vp->v_flag &= ~VMOUNT;
340                 vp->v_mountedhere = mp;
341                 lwkt_reltoken(&vp->v_interlock);
342                 lwkt_gettoken(&mountlist_token);
343                 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
344                 lwkt_reltoken(&mountlist_token);
345                 checkdirs(vp);
346                 VOP_UNLOCK(vp, 0, td);
347                 if ((mp->mnt_flag & MNT_RDONLY) == 0)
348                         error = vfs_allocate_syncvnode(mp);
349                 vfs_unbusy(mp, td);
350                 if ((error = VFS_START(mp, 0, td)) != 0)
351                         vrele(vp);
352         } else {
353                 lwkt_gettoken(&vp->v_interlock);
354                 vp->v_flag &= ~VMOUNT;
355                 lwkt_reltoken(&vp->v_interlock);
356                 mp->mnt_vfc->vfc_refcount--;
357                 vfs_unbusy(mp, td);
358                 free((caddr_t)mp, M_MOUNT);
359                 vput(vp);
360         }
361         return (error);
362 }
363
364 /*
365  * Scan all active processes to see if any of them have a current
366  * or root directory onto which the new filesystem has just been
367  * mounted. If so, replace them with the new mount point.
368  */
369 static void
370 checkdirs(struct vnode *olddp)
371 {
372         struct filedesc *fdp;
373         struct vnode *newdp;
374         struct proc *p;
375
376         if (olddp->v_usecount == 1)
377                 return;
378         if (VFS_ROOT(olddp->v_mountedhere, &newdp))
379                 panic("mount: lost mount");
380         FOREACH_PROC_IN_SYSTEM(p) {
381                 fdp = p->p_fd;
382                 if (fdp->fd_cdir == olddp) {
383                         vrele(fdp->fd_cdir);
384                         VREF(newdp);
385                         fdp->fd_cdir = newdp;
386                 }
387                 if (fdp->fd_rdir == olddp) {
388                         vrele(fdp->fd_rdir);
389                         VREF(newdp);
390                         fdp->fd_rdir = newdp;
391                 }
392         }
393         if (rootvnode == olddp) {
394                 vrele(rootvnode);
395                 VREF(newdp);
396                 rootvnode = newdp;
397         }
398         vput(newdp);
399 }
400
401 /*
402  * Unmount a file system.
403  *
404  * Note: unmount takes a path to the vnode mounted on as argument,
405  * not special file (as before).
406  */
407 /*
408  * umount_args(char *path, int flags)
409  */
410 /* ARGSUSED */
411 int
412 unmount(struct unmount_args *uap)
413 {
414         struct thread *td = curthread;
415         struct proc *p = td->td_proc;
416         struct vnode *vp;
417         struct mount *mp;
418         int error;
419         struct nameidata nd;
420
421         KKASSERT(p);
422         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
423             SCARG(uap, path), td);
424         if ((error = namei(&nd)) != 0)
425                 return (error);
426         vp = nd.ni_vp;
427         NDFREE(&nd, NDF_ONLY_PNBUF);
428         mp = vp->v_mount;
429
430         /*
431          * Only root, or the user that did the original mount is
432          * permitted to unmount this filesystem.
433          */
434         if ((mp->mnt_stat.f_owner != p->p_ucred->cr_uid) &&
435             (error = suser(td))) {
436                 vput(vp);
437                 return (error);
438         }
439
440         /*
441          * Don't allow unmounting the root file system.
442          */
443         if (mp->mnt_flag & MNT_ROOTFS) {
444                 vput(vp);
445                 return (EINVAL);
446         }
447
448         /*
449          * Must be the root of the filesystem
450          */
451         if ((vp->v_flag & VROOT) == 0) {
452                 vput(vp);
453                 return (EINVAL);
454         }
455         vput(vp);
456         return (dounmount(mp, SCARG(uap, flags), td));
457 }
458
459 /*
460  * Do the actual file system unmount.
461  */
462 int
463 dounmount(struct mount *mp, int flags, struct thread *td)
464 {
465         struct vnode *coveredvp;
466         int error;
467         int async_flag;
468
469         lwkt_gettoken(&mountlist_token);
470         if (mp->mnt_kern_flag & MNTK_UNMOUNT) {
471                 lwkt_reltoken(&mountlist_token);
472                 return (EBUSY);
473         }
474         mp->mnt_kern_flag |= MNTK_UNMOUNT;
475         /* Allow filesystems to detect that a forced unmount is in progress. */
476         if (flags & MNT_FORCE)
477                 mp->mnt_kern_flag |= MNTK_UNMOUNTF;
478         error = lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK |
479             ((flags & MNT_FORCE) ? 0 : LK_NOWAIT), &mountlist_token, td);
480         if (error) {
481                 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF);
482                 if (mp->mnt_kern_flag & MNTK_MWAIT)
483                         wakeup((caddr_t)mp);
484                 return (error);
485         }
486
487         if (mp->mnt_flag & MNT_EXPUBLIC)
488                 vfs_setpublicfs(NULL, NULL, NULL);
489
490         vfs_msync(mp, MNT_WAIT);
491         async_flag = mp->mnt_flag & MNT_ASYNC;
492         mp->mnt_flag &=~ MNT_ASYNC;
493         cache_purgevfs(mp);     /* remove cache entries for this file sys */
494         if (mp->mnt_syncer != NULL)
495                 vrele(mp->mnt_syncer);
496         if (((mp->mnt_flag & MNT_RDONLY) ||
497              (error = VFS_SYNC(mp, MNT_WAIT, td)) == 0) ||
498             (flags & MNT_FORCE))
499                 error = VFS_UNMOUNT(mp, flags, td);
500         lwkt_gettoken(&mountlist_token);
501         if (error) {
502                 if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL)
503                         (void) vfs_allocate_syncvnode(mp);
504                 mp->mnt_kern_flag &= ~(MNTK_UNMOUNT | MNTK_UNMOUNTF);
505                 mp->mnt_flag |= async_flag;
506                 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE,
507                     &mountlist_token, td);
508                 if (mp->mnt_kern_flag & MNTK_MWAIT)
509                         wakeup((caddr_t)mp);
510                 return (error);
511         }
512         TAILQ_REMOVE(&mountlist, mp, mnt_list);
513         if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) {
514                 coveredvp->v_mountedhere = (struct mount *)0;
515                 vrele(coveredvp);
516         }
517         mp->mnt_vfc->vfc_refcount--;
518         if (!TAILQ_EMPTY(&mp->mnt_nvnodelist))
519                 panic("unmount: dangling vnode");
520         lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_token, td);
521         if (mp->mnt_kern_flag & MNTK_MWAIT)
522                 wakeup((caddr_t)mp);
523         free((caddr_t)mp, M_MOUNT);
524         return (0);
525 }
526
527 /*
528  * Sync each mounted filesystem.
529  */
530
531 #ifdef DEBUG
532 static int syncprt = 0;
533 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, "");
534 #endif
535
536 /* ARGSUSED */
537 int
538 sync(struct sync_args *uap)
539 {
540         struct thread *td = curthread;
541         struct mount *mp, *nmp;
542         int asyncflag;
543
544         lwkt_gettoken(&mountlist_token);
545         for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
546                 if (vfs_busy(mp, LK_NOWAIT, &mountlist_token, td)) {
547                         nmp = TAILQ_NEXT(mp, mnt_list);
548                         continue;
549                 }
550                 if ((mp->mnt_flag & MNT_RDONLY) == 0) {
551                         asyncflag = mp->mnt_flag & MNT_ASYNC;
552                         mp->mnt_flag &= ~MNT_ASYNC;
553                         vfs_msync(mp, MNT_NOWAIT);
554                         VFS_SYNC(mp, MNT_NOWAIT, td);
555                         mp->mnt_flag |= asyncflag;
556                 }
557                 lwkt_gettoken(&mountlist_token);
558                 nmp = TAILQ_NEXT(mp, mnt_list);
559                 vfs_unbusy(mp, td);
560         }
561         lwkt_reltoken(&mountlist_token);
562 #if 0
563 /*
564  * XXX don't call vfs_bufstats() yet because that routine
565  * was not imported in the Lite2 merge.
566  */
567 #ifdef DIAGNOSTIC
568         if (syncprt)
569                 vfs_bufstats();
570 #endif /* DIAGNOSTIC */
571 #endif
572         return (0);
573 }
574
575 /* XXX PRISON: could be per prison flag */
576 static int prison_quotas;
577 #if 0
578 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, "");
579 #endif
580
581 /*
582  *  quotactl_args(char *path, int fcmd, int uid, caddr_t arg)
583  *
584  * Change filesystem quotas.
585  */
586 /* ARGSUSED */
587 int
588 quotactl(struct quotactl_args *uap)
589 {
590         struct thread *td = curthread;
591         struct proc *p = td->td_proc;
592         struct mount *mp;
593         int error;
594         struct nameidata nd;
595
596         KKASSERT(p);
597         if (p->p_ucred->cr_prison && !prison_quotas)
598                 return (EPERM);
599         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
600         if ((error = namei(&nd)) != 0)
601                 return (error);
602         mp = nd.ni_vp->v_mount;
603         NDFREE(&nd, NDF_ONLY_PNBUF);
604         vrele(nd.ni_vp);
605         return (VFS_QUOTACTL(mp, SCARG(uap, cmd), SCARG(uap, uid),
606             SCARG(uap, arg), td));
607 }
608
609 /*
610  * statfs_args(char *path, struct statfs *buf)
611  *
612  * Get filesystem statistics.
613  */
614 /* ARGSUSED */
615 int
616 statfs(struct statfs_args *uap)
617 {
618         struct thread *td = curthread;
619         struct mount *mp;
620         struct statfs *sp;
621         int error;
622         struct nameidata nd;
623         struct statfs sb;
624
625         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
626         if ((error = namei(&nd)) != 0)
627                 return (error);
628         mp = nd.ni_vp->v_mount;
629         sp = &mp->mnt_stat;
630         NDFREE(&nd, NDF_ONLY_PNBUF);
631         vrele(nd.ni_vp);
632         error = VFS_STATFS(mp, sp, td);
633         if (error)
634                 return (error);
635         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
636         if (suser(td)) {
637                 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
638                 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
639                 sp = &sb;
640         }
641         return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp)));
642 }
643
644 /*
645  * fstatfs_args(int fd, struct statfs *buf)
646  *
647  * Get filesystem statistics.
648  */
649 /* ARGSUSED */
650 int
651 fstatfs(struct fstatfs_args *uap)
652 {
653         struct thread *td = curthread;
654         struct proc *p = td->td_proc;
655         struct file *fp;
656         struct mount *mp;
657         struct statfs *sp;
658         int error;
659         struct statfs sb;
660
661         KKASSERT(p);
662         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
663                 return (error);
664         mp = ((struct vnode *)fp->f_data)->v_mount;
665         if (mp == NULL)
666                 return (EBADF);
667         sp = &mp->mnt_stat;
668         error = VFS_STATFS(mp, sp, td);
669         if (error)
670                 return (error);
671         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
672         if (suser(td)) {
673                 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
674                 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
675                 sp = &sb;
676         }
677         return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp)));
678 }
679
680 /*
681  * getfsstat_args(struct statfs *buf, long bufsize, int flags)
682  *
683  * Get statistics on all filesystems.
684  */
685 /* ARGSUSED */
686 int
687 getfsstat(struct getfsstat_args *uap)
688 {
689         struct thread *td = curthread;
690         struct mount *mp, *nmp;
691         struct statfs *sp;
692         caddr_t sfsp;
693         long count, maxcount, error;
694
695         maxcount = SCARG(uap, bufsize) / sizeof(struct statfs);
696         sfsp = (caddr_t)SCARG(uap, buf);
697         count = 0;
698         lwkt_gettoken(&mountlist_token);
699         for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
700                 if (vfs_busy(mp, LK_NOWAIT, &mountlist_token, td)) {
701                         nmp = TAILQ_NEXT(mp, mnt_list);
702                         continue;
703                 }
704                 if (sfsp && count < maxcount) {
705                         sp = &mp->mnt_stat;
706                         /*
707                          * If MNT_NOWAIT or MNT_LAZY is specified, do not
708                          * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
709                          * overrides MNT_WAIT.
710                          */
711                         if (((SCARG(uap, flags) & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
712                             (SCARG(uap, flags) & MNT_WAIT)) &&
713                             (error = VFS_STATFS(mp, sp, td))) {
714                                 lwkt_gettoken(&mountlist_token);
715                                 nmp = TAILQ_NEXT(mp, mnt_list);
716                                 vfs_unbusy(mp, td);
717                                 continue;
718                         }
719                         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
720                         error = copyout((caddr_t)sp, sfsp, sizeof(*sp));
721                         if (error) {
722                                 vfs_unbusy(mp, td);
723                                 return (error);
724                         }
725                         sfsp += sizeof(*sp);
726                 }
727                 count++;
728                 lwkt_gettoken(&mountlist_token);
729                 nmp = TAILQ_NEXT(mp, mnt_list);
730                 vfs_unbusy(mp, td);
731         }
732         lwkt_reltoken(&mountlist_token);
733         if (sfsp && count > maxcount)
734                 uap->sysmsg_result = maxcount;
735         else
736                 uap->sysmsg_result = count;
737         return (0);
738 }
739
740 /*
741  * fchdir_args(int fd)
742  *
743  * Change current working directory to a given file descriptor.
744  */
745 /* ARGSUSED */
746 int
747 fchdir(struct fchdir_args *uap)
748 {
749         struct thread *td = curthread;
750         struct proc *p = td->td_proc;
751         struct filedesc *fdp = p->p_fd;
752         struct vnode *vp, *tdp;
753         struct mount *mp;
754         struct file *fp;
755         int error;
756
757         if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0)
758                 return (error);
759         vp = (struct vnode *)fp->f_data;
760         VREF(vp);
761         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
762         if (vp->v_type != VDIR)
763                 error = ENOTDIR;
764         else
765                 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, td);
766         while (!error && (mp = vp->v_mountedhere) != NULL) {
767                 if (vfs_busy(mp, 0, 0, td))
768                         continue;
769                 error = VFS_ROOT(mp, &tdp);
770                 vfs_unbusy(mp, td);
771                 if (error)
772                         break;
773                 vput(vp);
774                 vp = tdp;
775         }
776         if (error) {
777                 vput(vp);
778                 return (error);
779         }
780         VOP_UNLOCK(vp, 0, td);
781         vrele(fdp->fd_cdir);
782         fdp->fd_cdir = vp;
783         return (0);
784 }
785
786 /*
787  * chdir_args(char *path)
788  *
789  * Change current working directory (``.'').
790  */
791 /* ARGSUSED */
792 int
793 chdir(struct chdir_args *uap)
794 {
795         struct thread *td = curthread;
796         struct proc *p = td->td_proc;
797         struct filedesc *fdp = p->p_fd;
798         int error;
799         struct nameidata nd;
800
801         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
802             SCARG(uap, path), td);
803         if ((error = change_dir(&nd, td)) != 0)
804                 return (error);
805         NDFREE(&nd, NDF_ONLY_PNBUF);
806         vrele(fdp->fd_cdir);
807         fdp->fd_cdir = nd.ni_vp;
808         return (0);
809 }
810
811 /*
812  * Helper function for raised chroot(2) security function:  Refuse if
813  * any filedescriptors are open directories.
814  */
815 static int
816 chroot_refuse_vdir_fds(fdp)
817         struct filedesc *fdp;
818 {
819         struct vnode *vp;
820         struct file *fp;
821         int error;
822         int fd;
823
824         for (fd = 0; fd < fdp->fd_nfiles ; fd++) {
825                 error = getvnode(fdp, fd, &fp);
826                 if (error)
827                         continue;
828                 vp = (struct vnode *)fp->f_data;
829                 if (vp->v_type != VDIR)
830                         continue;
831                 return(EPERM);
832         }
833         return (0);
834 }
835
836 /*
837  * This sysctl determines if we will allow a process to chroot(2) if it
838  * has a directory open:
839  *      0: disallowed for all processes.
840  *      1: allowed for processes that were not already chroot(2)'ed.
841  *      2: allowed for all processes.
842  */
843
844 static int chroot_allow_open_directories = 1;
845
846 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW,
847      &chroot_allow_open_directories, 0, "");
848
849 /*
850  * chroot_args(char *path)
851  *
852  * Change notion of root (``/'') directory.
853  */
854 /* ARGSUSED */
855 int
856 chroot(struct chroot_args *uap)
857 {
858         struct thread *td = curthread;
859         struct proc *p = td->td_proc;
860         struct filedesc *fdp = p->p_fd;
861         int error;
862         struct nameidata nd;
863
864         KKASSERT(p);
865         error = suser_cred(p->p_ucred, PRISON_ROOT);
866         if (error)
867                 return (error);
868         if (chroot_allow_open_directories == 0 ||
869             (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode))
870                 error = chroot_refuse_vdir_fds(fdp);
871         if (error)
872                 return (error);
873         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
874             SCARG(uap, path), td);
875         if ((error = change_dir(&nd, td)) != 0)
876                 return (error);
877         NDFREE(&nd, NDF_ONLY_PNBUF);
878         vrele(fdp->fd_rdir);
879         fdp->fd_rdir = nd.ni_vp;
880         if (!fdp->fd_jdir) {
881                 fdp->fd_jdir = nd.ni_vp;
882                 VREF(fdp->fd_jdir);
883         }
884         return (0);
885 }
886
887 /*
888  * Common routine for chroot and chdir.
889  */
890 static int
891 change_dir(struct nameidata *ndp, struct thread *td)
892 {
893         struct vnode *vp;
894         int error;
895
896         error = namei(ndp);
897         if (error)
898                 return (error);
899         vp = ndp->ni_vp;
900         if (vp->v_type != VDIR)
901                 error = ENOTDIR;
902         else
903                 error = VOP_ACCESS(vp, VEXEC, ndp->ni_cnd.cn_cred, td);
904         if (error)
905                 vput(vp);
906         else
907                 VOP_UNLOCK(vp, 0, td);
908         return (error);
909 }
910
911 /*
912  * open_args(char *path, int flags, int mode)
913  *
914  * Check permissions, allocate an open file structure,
915  * and call the device open routine if any.
916  */
917 int
918 open(struct open_args *uap)
919 {
920         struct thread *td = curthread;
921         struct proc *p = td->td_proc;
922         struct filedesc *fdp = p->p_fd;
923         struct file *fp;
924         struct vnode *vp;
925         int cmode, flags, oflags;
926         struct file *nfp;
927         int type, indx, error;
928         struct flock lf;
929         struct nameidata nd;
930
931         oflags = SCARG(uap, flags);
932         if ((oflags & O_ACCMODE) == O_ACCMODE)
933                 return (EINVAL);
934         flags = FFLAGS(oflags);
935         error = falloc(p, &nfp, &indx);
936         if (error)
937                 return (error);
938         fp = nfp;
939         cmode = ((SCARG(uap, mode) &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
940         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
941         p->p_dupfd = -indx - 1;                 /* XXX check for fdopen */
942         /*
943          * Bump the ref count to prevent another process from closing
944          * the descriptor while we are blocked in vn_open()
945          */
946         fhold(fp);
947         error = vn_open(&nd, flags, cmode);
948         if (error) {
949                 /*
950                  * release our own reference
951                  */
952                 fdrop(fp, td);
953
954                 /*
955                  * handle special fdopen() case.  bleh.  dupfdopen() is
956                  * responsible for dropping the old contents of ofiles[indx]
957                  * if it succeeds.
958                  */
959                 if ((error == ENODEV || error == ENXIO) &&
960                     p->p_dupfd >= 0 &&                  /* XXX from fdopen */
961                     (error =
962                         dupfdopen(fdp, indx, p->p_dupfd, flags, error)) == 0) {
963                         uap->sysmsg_result = indx;
964                         return (0);
965                 }
966                 /*
967                  * Clean up the descriptor, but only if another thread hadn't
968                  * replaced or closed it.
969                  */
970                 if (fdp->fd_ofiles[indx] == fp) {
971                         fdp->fd_ofiles[indx] = NULL;
972                         fdrop(fp, td);
973                 }
974
975                 if (error == ERESTART)
976                         error = EINTR;
977                 return (error);
978         }
979         p->p_dupfd = 0;
980         NDFREE(&nd, NDF_ONLY_PNBUF);
981         vp = nd.ni_vp;
982
983         /*
984          * There should be 2 references on the file, one from the descriptor
985          * table, and one for us.
986          *
987          * Handle the case where someone closed the file (via its file
988          * descriptor) while we were blocked.  The end result should look
989          * like opening the file succeeded but it was immediately closed.
990          */
991         if (fp->f_count == 1) {
992                 KASSERT(fdp->fd_ofiles[indx] != fp,
993                     ("Open file descriptor lost all refs"));
994                 VOP_UNLOCK(vp, 0, td);
995                 vn_close(vp, flags & FMASK, td);
996                 fdrop(fp, td);
997                 uap->sysmsg_result = indx;
998                 return 0;
999         }
1000
1001         fp->f_data = (caddr_t)vp;
1002         fp->f_flag = flags & FMASK;
1003         fp->f_ops = &vnops;
1004         fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE);
1005         if (flags & (O_EXLOCK | O_SHLOCK)) {
1006                 lf.l_whence = SEEK_SET;
1007                 lf.l_start = 0;
1008                 lf.l_len = 0;
1009                 if (flags & O_EXLOCK)
1010                         lf.l_type = F_WRLCK;
1011                 else
1012                         lf.l_type = F_RDLCK;
1013                 type = F_FLOCK;
1014                 if ((flags & FNONBLOCK) == 0)
1015                         type |= F_WAIT;
1016                 VOP_UNLOCK(vp, 0, td);
1017                 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) {
1018                         /*
1019                          * lock request failed.  Normally close the descriptor
1020                          * but handle the case where someone might have dup()d
1021                          * it when we weren't looking.  One reference is
1022                          * owned by the descriptor array, the other by us.
1023                          */
1024                         if (fdp->fd_ofiles[indx] == fp) {
1025                                 fdp->fd_ofiles[indx] = NULL;
1026                                 fdrop(fp, td);
1027                         }
1028                         fdrop(fp, td);
1029                         return (error);
1030                 }
1031                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1032                 fp->f_flag |= FHASLOCK;
1033         }
1034         /* assert that vn_open created a backing object if one is needed */
1035         KASSERT(!vn_canvmio(vp) || VOP_GETVOBJECT(vp, NULL) == 0,
1036                 ("open: vmio vnode has no backing object after vn_open"));
1037         VOP_UNLOCK(vp, 0, td);
1038
1039         /*
1040          * release our private reference, leaving the one associated with the
1041          * descriptor table intact.
1042          */
1043         fdrop(fp, td);
1044         uap->sysmsg_result = indx;
1045         return (0);
1046 }
1047
1048 #ifdef COMPAT_43
1049 /*
1050  * ocreat(char *path, int mode)
1051  *
1052  * Create a file.
1053  */
1054 int
1055 ocreat(struct ocreat_args *uap)
1056 {
1057         struct open_args /* {
1058                 syscallarg(char *) path;
1059                 syscallarg(int) flags;
1060                 syscallarg(int) mode;
1061         } */ nuap;
1062
1063         SCARG(&nuap, path) = SCARG(uap, path);
1064         SCARG(&nuap, mode) = SCARG(uap, mode);
1065         SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
1066         return (open(&nuap));
1067 }
1068 #endif /* COMPAT_43 */
1069
1070 /*
1071  * mknod_args(char *path, int mode, int dev)
1072  *
1073  * Create a special file.
1074  */
1075 /* ARGSUSED */
1076 int
1077 mknod(struct mknod_args *uap)
1078 {
1079         struct thread *td = curthread;
1080         struct proc *p = td->td_proc;
1081         struct vnode *vp;
1082         struct vattr vattr;
1083         int error;
1084         int whiteout = 0;
1085         struct nameidata nd;
1086
1087         KKASSERT(p);
1088
1089         switch (SCARG(uap, mode) & S_IFMT) {
1090         case S_IFCHR:
1091         case S_IFBLK:
1092                 error = suser(td);
1093                 break;
1094         default:
1095                 error = suser_cred(p->p_ucred, PRISON_ROOT);
1096                 break;
1097         }
1098         if (error)
1099                 return (error);
1100         bwillwrite();
1101         NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), td);
1102         if ((error = namei(&nd)) != 0)
1103                 return (error);
1104         vp = nd.ni_vp;
1105         if (vp != NULL)
1106                 error = EEXIST;
1107         else {
1108                 VATTR_NULL(&vattr);
1109                 vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask;
1110                 vattr.va_rdev = SCARG(uap, dev);
1111                 whiteout = 0;
1112
1113                 switch (SCARG(uap, mode) & S_IFMT) {
1114                 case S_IFMT:    /* used by badsect to flag bad sectors */
1115                         vattr.va_type = VBAD;
1116                         break;
1117                 case S_IFCHR:
1118                         vattr.va_type = VCHR;
1119                         break;
1120                 case S_IFBLK:
1121                         vattr.va_type = VBLK;
1122                         break;
1123                 case S_IFWHT:
1124                         whiteout = 1;
1125                         break;
1126                 default:
1127                         error = EINVAL;
1128                         break;
1129                 }
1130         }
1131         if (!error) {
1132                 VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE);
1133                 if (whiteout)
1134                         error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE);
1135                 else {
1136                         error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp,
1137                                                 &nd.ni_cnd, &vattr);
1138                         if (error == 0)
1139                                 vput(nd.ni_vp);
1140                 }
1141                 NDFREE(&nd, NDF_ONLY_PNBUF);
1142                 vput(nd.ni_dvp);
1143         } else {
1144                 NDFREE(&nd, NDF_ONLY_PNBUF);
1145                 if (nd.ni_dvp == vp)
1146                         vrele(nd.ni_dvp);
1147                 else
1148                         vput(nd.ni_dvp);
1149                 if (vp)
1150                         vrele(vp);
1151         }
1152         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod");
1153         ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod");
1154         return (error);
1155 }
1156
1157 /*
1158  * mkfifo_args(char *path, int mode)
1159  *
1160  * Create a named pipe.
1161  */
1162 /* ARGSUSED */
1163 int
1164 mkfifo(struct mkfifo_args *uap)
1165 {
1166         struct thread *td = curthread;
1167         struct proc *p = td->td_proc;
1168         struct vattr vattr;
1169         int error;
1170         struct nameidata nd;
1171
1172         bwillwrite();
1173         NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), td);
1174         if ((error = namei(&nd)) != 0)
1175                 return (error);
1176         if (nd.ni_vp != NULL) {
1177                 NDFREE(&nd, NDF_ONLY_PNBUF);
1178                 if (nd.ni_dvp == nd.ni_vp)
1179                         vrele(nd.ni_dvp);
1180                 else
1181                         vput(nd.ni_dvp);
1182                 vrele(nd.ni_vp);
1183                 return (EEXIST);
1184         }
1185         VATTR_NULL(&vattr);
1186         vattr.va_type = VFIFO;
1187         vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask;
1188         VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE);
1189         error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
1190         if (error == 0)
1191                 vput(nd.ni_vp);
1192         NDFREE(&nd, NDF_ONLY_PNBUF);
1193         vput(nd.ni_dvp);
1194         return (error);
1195 }
1196
1197 /*
1198  * link_args(char *path, char *link)
1199  *
1200  * Make a hard file link.
1201  */
1202 /* ARGSUSED */
1203 int
1204 link(struct link_args *uap)
1205 {
1206         struct thread *td = curthread;
1207         struct proc *p = td->td_proc;
1208         struct vnode *vp;
1209         struct nameidata nd;
1210         int error;
1211
1212         bwillwrite();
1213         NDINIT(&nd, LOOKUP, FOLLOW|NOOBJ, UIO_USERSPACE, SCARG(uap, path), td);
1214         if ((error = namei(&nd)) != 0)
1215                 return (error);
1216         NDFREE(&nd, NDF_ONLY_PNBUF);
1217         vp = nd.ni_vp;
1218         if (vp->v_type == VDIR)
1219                 error = EPERM;          /* POSIX */
1220         else {
1221                 NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), td);
1222                 error = namei(&nd);
1223                 if (!error) {
1224                         if (nd.ni_vp != NULL) {
1225                                 if (nd.ni_vp)
1226                                         vrele(nd.ni_vp);
1227                                 error = EEXIST;
1228                         } else {
1229                                 VOP_LEASE(nd.ni_dvp, td, p->p_ucred,
1230                                     LEASE_WRITE);
1231                                 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE);
1232                                 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
1233                         }
1234                         NDFREE(&nd, NDF_ONLY_PNBUF);
1235                         if (nd.ni_dvp == nd.ni_vp)
1236                                 vrele(nd.ni_dvp);
1237                         else
1238                                 vput(nd.ni_dvp);
1239                 }
1240         }
1241         vrele(vp);
1242         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link");
1243         ASSERT_VOP_UNLOCKED(nd.ni_vp, "link");
1244         return (error);
1245 }
1246
1247 /*
1248  * symlink(char *path, char *link)
1249  *
1250  * Make a symbolic link.
1251  */
1252 /* ARGSUSED */
1253 int
1254 symlink(struct symlink_args *uap)
1255 {
1256         struct thread *td = curthread;
1257         struct proc *p = td->td_proc;
1258         struct vattr vattr;
1259         char *path;
1260         int error;
1261         struct nameidata nd;
1262
1263         path = zalloc(namei_zone);
1264         if ((error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL)) != 0)
1265                 goto out;
1266         bwillwrite();
1267         NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), td);
1268         if ((error = namei(&nd)) != 0)
1269                 goto out;
1270         if (nd.ni_vp) {
1271                 NDFREE(&nd, NDF_ONLY_PNBUF);
1272                 if (nd.ni_dvp == nd.ni_vp)
1273                         vrele(nd.ni_dvp);
1274                 else
1275                         vput(nd.ni_dvp);
1276                 vrele(nd.ni_vp);
1277                 error = EEXIST;
1278                 goto out;
1279         }
1280         VATTR_NULL(&vattr);
1281         vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask;
1282         VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE);
1283         error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path);
1284         NDFREE(&nd, NDF_ONLY_PNBUF);
1285         if (error == 0)
1286                 vput(nd.ni_vp);
1287         vput(nd.ni_dvp);
1288         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink");
1289         ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink");
1290 out:
1291         zfree(namei_zone, path);
1292         return (error);
1293 }
1294
1295 /*
1296  * undelete_args(char *path)
1297  *
1298  * Delete a whiteout from the filesystem.
1299  */
1300 /* ARGSUSED */
1301 int
1302 undelete(struct undelete_args *uap)
1303 {
1304         struct thread *td = curthread;
1305         struct proc *p = td->td_proc;
1306         int error;
1307         struct nameidata nd;
1308
1309         bwillwrite();
1310         NDINIT(&nd, DELETE, LOCKPARENT|DOWHITEOUT, UIO_USERSPACE,
1311             SCARG(uap, path), td);
1312         error = namei(&nd);
1313         if (error)
1314                 return (error);
1315
1316         if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) {
1317                 NDFREE(&nd, NDF_ONLY_PNBUF);
1318                 if (nd.ni_dvp == nd.ni_vp)
1319                         vrele(nd.ni_dvp);
1320                 else
1321                         vput(nd.ni_dvp);
1322                 if (nd.ni_vp)
1323                         vrele(nd.ni_vp);
1324                 return (EEXIST);
1325         }
1326
1327         VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE);
1328         error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE);
1329         NDFREE(&nd, NDF_ONLY_PNBUF);
1330         vput(nd.ni_dvp);
1331         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "undelete");
1332         ASSERT_VOP_UNLOCKED(nd.ni_vp, "undelete");
1333         return (error);
1334 }
1335
1336 /*
1337  * unlink_args(char *path)
1338  *
1339  * Delete a name from the filesystem.
1340  */
1341 int
1342 unlink(struct unlink_args *uap)
1343 {
1344         struct thread *td = curthread;
1345         struct proc *p = td->td_proc;
1346         struct vnode *vp;
1347         int error;
1348         struct nameidata nd;
1349
1350         bwillwrite();
1351         NDINIT(&nd, DELETE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), td);
1352         if ((error = namei(&nd)) != 0)
1353                 return (error);
1354         vp = nd.ni_vp;
1355         VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE);
1356         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1357
1358         if (vp->v_type == VDIR)
1359                 error = EPERM;          /* POSIX */
1360         else {
1361                 /*
1362                  * The root of a mounted filesystem cannot be deleted.
1363                  *
1364                  * XXX: can this only be a VDIR case?
1365                  */
1366                 if (vp->v_flag & VROOT)
1367                         error = EBUSY;
1368         }
1369
1370         if (!error) {
1371                 VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE);
1372                 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd);
1373         }
1374         NDFREE(&nd, NDF_ONLY_PNBUF);
1375         if (nd.ni_dvp == vp)
1376                 vrele(nd.ni_dvp);
1377         else
1378                 vput(nd.ni_dvp);
1379         if (vp != NULLVP)
1380                 vput(vp);
1381         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink");
1382         ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink");
1383         return (error);
1384 }
1385
1386 /*
1387  * lseek_args(int fd, int pad, off_t offset, int whence)
1388  *
1389  * Reposition read/write file offset.
1390  */
1391 int
1392 lseek(struct lseek_args *uap)
1393 {
1394         struct thread *td = curthread;
1395         struct proc *p = td->td_proc;
1396         struct filedesc *fdp = p->p_fd;
1397         struct file *fp;
1398         struct vattr vattr;
1399         int error;
1400
1401         if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
1402             (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
1403                 return (EBADF);
1404         if (fp->f_type != DTYPE_VNODE)
1405                 return (ESPIPE);
1406         switch (SCARG(uap, whence)) {
1407         case L_INCR:
1408                 fp->f_offset += SCARG(uap, offset);
1409                 break;
1410         case L_XTND:
1411                 error=VOP_GETATTR((struct vnode *)fp->f_data, &vattr, td);
1412                 if (error)
1413                         return (error);
1414                 fp->f_offset = SCARG(uap, offset) + vattr.va_size;
1415                 break;
1416         case L_SET:
1417                 fp->f_offset = SCARG(uap, offset);
1418                 break;
1419         default:
1420                 return (EINVAL);
1421         }
1422         uap->sysmsg_offset = fp->f_offset;
1423         return (0);
1424 }
1425
1426 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1427 /*
1428  * Reposition read/write file offset.
1429  *
1430  * olseek_args(int fd, long offset, int whence)
1431  */
1432 int
1433 olseek(struct olseek_args *uap)
1434 {
1435         struct lseek_args /* {
1436                 syscallarg(int) fd;
1437                 syscallarg(int) pad;
1438                 syscallarg(off_t) offset;
1439                 syscallarg(int) whence;
1440         } */ nuap;
1441         int error;
1442
1443         SCARG(&nuap, fd) = SCARG(uap, fd);
1444         SCARG(&nuap, offset) = SCARG(uap, offset);
1445         SCARG(&nuap, whence) = SCARG(uap, whence);
1446         error = lseek(&nuap);
1447         return (error);
1448 }
1449 #endif /* COMPAT_43 */
1450
1451 /*
1452  * access_args(char *path, int flags)
1453  *
1454  * Check access permissions.
1455  */
1456 int
1457 access(struct access_args *uap)
1458 {
1459         struct thread *td = curthread;
1460         struct proc *p = td->td_proc;
1461         struct ucred *cred, *tmpcred;
1462         struct vnode *vp;
1463         int error, flags;
1464         struct nameidata nd;
1465
1466         cred = p->p_ucred;
1467         /*
1468          * Create and modify a temporary credential instead of one that
1469          * is potentially shared.  This could also mess up socket
1470          * buffer accounting which can run in an interrupt context.
1471          */
1472         tmpcred = crdup(cred);
1473         tmpcred->cr_uid = p->p_ucred->cr_ruid;
1474         tmpcred->cr_groups[0] = p->p_ucred->cr_rgid;
1475         p->p_ucred = tmpcred;
1476         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1477             SCARG(uap, path), td);
1478         if ((error = namei(&nd)) != 0)
1479                 goto out1;
1480         vp = nd.ni_vp;
1481
1482         /* Flags == 0 means only check for existence. */
1483         if (SCARG(uap, flags)) {
1484                 flags = 0;
1485                 if (SCARG(uap, flags) & R_OK)
1486                         flags |= VREAD;
1487                 if (SCARG(uap, flags) & W_OK)
1488                         flags |= VWRITE;
1489                 if (SCARG(uap, flags) & X_OK)
1490                         flags |= VEXEC;
1491                 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
1492                         error = VOP_ACCESS(vp, flags, tmpcred, td);
1493         }
1494         NDFREE(&nd, NDF_ONLY_PNBUF);
1495         vput(vp);
1496 out1:
1497         p->p_ucred = cred;
1498         crfree(tmpcred);
1499         return (error);
1500 }
1501
1502 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1503 /*
1504  * ostat_args(char *path, struct ostat *ub)
1505  *
1506  * Get file status; this version follows links.
1507  */
1508 /* ARGSUSED */
1509 int
1510 ostat(struct ostat_args *uap)
1511 {
1512         struct thread *td = curthread;
1513         struct stat sb;
1514         struct ostat osb;
1515         int error;
1516         struct nameidata nd;
1517
1518         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1519             SCARG(uap, path), td);
1520         if ((error = namei(&nd)) != 0)
1521                 return (error);
1522         NDFREE(&nd, NDF_ONLY_PNBUF);
1523         error = vn_stat(nd.ni_vp, &sb, td);
1524         vput(nd.ni_vp);
1525         if (error)
1526                 return (error);
1527         cvtstat(&sb, &osb);
1528         error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
1529         return (error);
1530 }
1531
1532 /*
1533  * olstat_args(char *path, struct ostat *ub)
1534  *
1535  * Get file status; this version does not follow links.
1536  */
1537 /* ARGSUSED */
1538 int
1539 olstat(struct olstat_args *uap)
1540 {
1541         struct thread *td = curthread;
1542         struct vnode *vp;
1543         struct stat sb;
1544         struct ostat osb;
1545         int error;
1546         struct nameidata nd;
1547
1548         NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1549             SCARG(uap, path), td);
1550         if ((error = namei(&nd)) != 0)
1551                 return (error);
1552         vp = nd.ni_vp;
1553         error = vn_stat(vp, &sb, td);
1554         NDFREE(&nd, NDF_ONLY_PNBUF);
1555         vput(vp);
1556         if (error)
1557                 return (error);
1558         cvtstat(&sb, &osb);
1559         error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
1560         return (error);
1561 }
1562
1563 /*
1564  * Convert from an old to a new stat structure.
1565  */
1566 void
1567 cvtstat(st, ost)
1568         struct stat *st;
1569         struct ostat *ost;
1570 {
1571         ost->st_dev = st->st_dev;
1572         ost->st_ino = st->st_ino;
1573         ost->st_mode = st->st_mode;
1574         ost->st_nlink = st->st_nlink;
1575         ost->st_uid = st->st_uid;
1576         ost->st_gid = st->st_gid;
1577         ost->st_rdev = st->st_rdev;
1578         if (st->st_size < (quad_t)1 << 32)
1579                 ost->st_size = st->st_size;
1580         else
1581                 ost->st_size = -2;
1582         ost->st_atime = st->st_atime;
1583         ost->st_mtime = st->st_mtime;
1584         ost->st_ctime = st->st_ctime;
1585         ost->st_blksize = st->st_blksize;
1586         ost->st_blocks = st->st_blocks;
1587         ost->st_flags = st->st_flags;
1588         ost->st_gen = st->st_gen;
1589 }
1590 #endif /* COMPAT_43 || COMPAT_SUNOS */
1591
1592 /*
1593  * stat_args(char *path, struct stat *ub)
1594  *
1595  * Get file status; this version follows links.
1596  */
1597 /* ARGSUSED */
1598 int
1599 stat(struct stat_args *uap)
1600 {
1601         struct thread *td = curthread;
1602         struct stat sb;
1603         int error;
1604         struct nameidata nd;
1605
1606         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1607             SCARG(uap, path), td);
1608         if ((error = namei(&nd)) != 0)
1609                 return (error);
1610         error = vn_stat(nd.ni_vp, &sb, td);
1611         NDFREE(&nd, NDF_ONLY_PNBUF);
1612         vput(nd.ni_vp);
1613         if (error)
1614                 return (error);
1615         error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));
1616         return (error);
1617 }
1618
1619 /*
1620  * lstat_args(char *path, struct stat *ub)
1621  *
1622  * Get file status; this version does not follow links.
1623  */
1624 /* ARGSUSED */
1625 int
1626 lstat(struct lstat_args *uap)
1627 {
1628         struct thread *td = curthread;
1629         int error;
1630         struct vnode *vp;
1631         struct stat sb;
1632         struct nameidata nd;
1633
1634         NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1635             SCARG(uap, path), td);
1636         if ((error = namei(&nd)) != 0)
1637                 return (error);
1638         vp = nd.ni_vp;
1639         error = vn_stat(vp, &sb, td);
1640         NDFREE(&nd, NDF_ONLY_PNBUF);
1641         vput(vp);
1642         if (error)
1643                 return (error);
1644         error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));
1645         return (error);
1646 }
1647
1648 void
1649 cvtnstat(sb, nsb)
1650         struct stat *sb;
1651         struct nstat *nsb;
1652 {
1653         nsb->st_dev = sb->st_dev;
1654         nsb->st_ino = sb->st_ino;
1655         nsb->st_mode = sb->st_mode;
1656         nsb->st_nlink = sb->st_nlink;
1657         nsb->st_uid = sb->st_uid;
1658         nsb->st_gid = sb->st_gid;
1659         nsb->st_rdev = sb->st_rdev;
1660         nsb->st_atimespec = sb->st_atimespec;
1661         nsb->st_mtimespec = sb->st_mtimespec;
1662         nsb->st_ctimespec = sb->st_ctimespec;
1663         nsb->st_size = sb->st_size;
1664         nsb->st_blocks = sb->st_blocks;
1665         nsb->st_blksize = sb->st_blksize;
1666         nsb->st_flags = sb->st_flags;
1667         nsb->st_gen = sb->st_gen;
1668         nsb->st_qspare[0] = sb->st_qspare[0];
1669         nsb->st_qspare[1] = sb->st_qspare[1];
1670 }
1671
1672 /*
1673  * nstat_args(char *path, struct nstat *ub)
1674  */
1675 /* ARGSUSED */
1676 int
1677 nstat(struct nstat_args *uap)
1678 {
1679         struct thread *td = curthread;
1680         struct stat sb;
1681         struct nstat nsb;
1682         int error;
1683         struct nameidata nd;
1684
1685         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1686             SCARG(uap, path), td);
1687         if ((error = namei(&nd)) != 0)
1688                 return (error);
1689         NDFREE(&nd, NDF_ONLY_PNBUF);
1690         error = vn_stat(nd.ni_vp, &sb, td);
1691         vput(nd.ni_vp);
1692         if (error)
1693                 return (error);
1694         cvtnstat(&sb, &nsb);
1695         error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb));
1696         return (error);
1697 }
1698
1699 /*
1700  * lstat_args(char *path, struct stat *ub)
1701  *
1702  * Get file status; this version does not follow links.
1703  */
1704 /* ARGSUSED */
1705 int
1706 nlstat(struct nlstat_args *uap)
1707 {
1708         struct thread *td = curthread;
1709         int error;
1710         struct vnode *vp;
1711         struct stat sb;
1712         struct nstat nsb;
1713         struct nameidata nd;
1714
1715         NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1716             SCARG(uap, path), td);
1717         if ((error = namei(&nd)) != 0)
1718                 return (error);
1719         vp = nd.ni_vp;
1720         NDFREE(&nd, NDF_ONLY_PNBUF);
1721         error = vn_stat(vp, &sb, td);
1722         vput(vp);
1723         if (error)
1724                 return (error);
1725         cvtnstat(&sb, &nsb);
1726         error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb));
1727         return (error);
1728 }
1729
1730 /*
1731  * pathconf_Args(char *path, int name)
1732  *
1733  * Get configurable pathname variables.
1734  */
1735 /* ARGSUSED */
1736 int
1737 pathconf(struct pathconf_args *uap)
1738 {
1739         struct thread *td = curthread;
1740         int error;
1741         struct nameidata nd;
1742
1743         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1744             SCARG(uap, path), td);
1745         if ((error = namei(&nd)) != 0)
1746                 return (error);
1747         NDFREE(&nd, NDF_ONLY_PNBUF);
1748         error = VOP_PATHCONF(nd.ni_vp, SCARG(uap, name), uap->sysmsg_fds);
1749         vput(nd.ni_vp);
1750         return (error);
1751 }
1752
1753 /*
1754  * readlink_args(char *path, char *buf, int count)
1755  *
1756  * Return target name of a symbolic link.
1757  */
1758 /* ARGSUSED */
1759 int
1760 readlink(struct readlink_args *uap)
1761 {
1762         struct thread *td = curthread;
1763         struct proc *p = td->td_proc;
1764         struct vnode *vp;
1765         struct iovec aiov;
1766         struct uio auio;
1767         int error;
1768         struct nameidata nd;
1769
1770         NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1771             SCARG(uap, path), td);
1772         if ((error = namei(&nd)) != 0)
1773                 return (error);
1774         NDFREE(&nd, NDF_ONLY_PNBUF);
1775         vp = nd.ni_vp;
1776         if (vp->v_type != VLNK)
1777                 error = EINVAL;
1778         else {
1779                 aiov.iov_base = SCARG(uap, buf);
1780                 aiov.iov_len = SCARG(uap, count);
1781                 auio.uio_iov = &aiov;
1782                 auio.uio_iovcnt = 1;
1783                 auio.uio_offset = 0;
1784                 auio.uio_rw = UIO_READ;
1785                 auio.uio_segflg = UIO_USERSPACE;
1786                 auio.uio_td = td;
1787                 auio.uio_resid = SCARG(uap, count);
1788                 error = VOP_READLINK(vp, &auio, p->p_ucred);
1789         }
1790         vput(vp);
1791         uap->sysmsg_result = SCARG(uap, count) - auio.uio_resid;
1792         return (error);
1793 }
1794
1795 static int
1796 setfflags(struct vnode *vp, int flags)
1797 {
1798         struct thread *td = curthread;
1799         struct proc *p = td->td_proc;
1800         int error;
1801         struct vattr vattr;
1802
1803         /*
1804          * Prevent non-root users from setting flags on devices.  When
1805          * a device is reused, users can retain ownership of the device
1806          * if they are allowed to set flags and programs assume that
1807          * chown can't fail when done as root.
1808          */
1809         if ((vp->v_type == VCHR || vp->v_type == VBLK) && 
1810             ((error = suser_cred(p->p_ucred, PRISON_ROOT)) != 0))
1811                 return (error);
1812
1813         VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE);
1814         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1815         VATTR_NULL(&vattr);
1816         vattr.va_flags = flags;
1817         error = VOP_SETATTR(vp, &vattr, p->p_ucred, td);
1818         VOP_UNLOCK(vp, 0, td);
1819         return (error);
1820 }
1821
1822 /*
1823  * chflags(char *path, int flags)
1824  *
1825  * Change flags of a file given a path name.
1826  */
1827 /* ARGSUSED */
1828 int
1829 chflags(struct chflags_args *uap)
1830 {
1831         struct thread *td = curthread;
1832         int error;
1833         struct nameidata nd;
1834
1835         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
1836         if ((error = namei(&nd)) != 0)
1837                 return (error);
1838         NDFREE(&nd, NDF_ONLY_PNBUF);
1839         error = setfflags(nd.ni_vp, SCARG(uap, flags));
1840         vrele(nd.ni_vp);
1841         return error;
1842 }
1843
1844 /*
1845  * fchflags_args(int fd, int flags)
1846  *
1847  * Change flags of a file given a file descriptor.
1848  */
1849 /* ARGSUSED */
1850 int
1851 fchflags(struct fchflags_args *uap)
1852 {
1853         struct thread *td = curthread;
1854         struct proc *p = td->td_proc;
1855         struct file *fp;
1856         int error;
1857
1858         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
1859                 return (error);
1860         return setfflags((struct vnode *) fp->f_data, SCARG(uap, flags));
1861 }
1862
1863 static int
1864 setfmode(struct vnode *vp, int mode)
1865 {
1866         struct thread *td = curthread;
1867         struct proc *p = td->td_proc;
1868         int error;
1869         struct vattr vattr;
1870
1871         VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE);
1872         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1873         VATTR_NULL(&vattr);
1874         vattr.va_mode = mode & ALLPERMS;
1875         error = VOP_SETATTR(vp, &vattr, p->p_ucred, td);
1876         VOP_UNLOCK(vp, 0, td);
1877         return error;
1878 }
1879
1880 /*
1881  * chmod_args(char *path, int mode)
1882  *
1883  * Change mode of a file given path name.
1884  */
1885 /* ARGSUSED */
1886 int
1887 chmod(struct chmod_args *uap)
1888 {
1889         struct thread *td = curthread;
1890         int error;
1891         struct nameidata nd;
1892
1893         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
1894         if ((error = namei(&nd)) != 0)
1895                 return (error);
1896         NDFREE(&nd, NDF_ONLY_PNBUF);
1897         error = setfmode(nd.ni_vp, SCARG(uap, mode));
1898         vrele(nd.ni_vp);
1899         return error;
1900 }
1901
1902 /*
1903  * lchmod_args(char *path, int mode)
1904  *
1905  * Change mode of a file given path name (don't follow links.)
1906  */
1907 /* ARGSUSED */
1908 int
1909 lchmod(struct lchmod_args *uap)
1910 {
1911         struct thread *td = curthread;
1912         int error;
1913         struct nameidata nd;
1914
1915         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
1916         if ((error = namei(&nd)) != 0)
1917                 return (error);
1918         NDFREE(&nd, NDF_ONLY_PNBUF);
1919         error = setfmode(nd.ni_vp, SCARG(uap, mode));
1920         vrele(nd.ni_vp);
1921         return error;
1922 }
1923
1924 /*
1925  * fchmod_args(int fd, int mode)
1926  *
1927  * Change mode of a file given a file descriptor.
1928  */
1929 /* ARGSUSED */
1930 int
1931 fchmod(struct fchmod_args *uap)
1932 {
1933         struct thread *td = curthread;
1934         struct proc *p = td->td_proc;
1935         struct file *fp;
1936         int error;
1937
1938         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
1939                 return (error);
1940         return setfmode((struct vnode *)fp->f_data, SCARG(uap, mode));
1941 }
1942
1943 static int
1944 setfown(struct vnode *vp, uid_t uid, gid_t gid)
1945 {
1946         struct thread *td = curthread;
1947         struct proc *p = td->td_proc;
1948         int error;
1949         struct vattr vattr;
1950
1951         VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE);
1952         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1953         VATTR_NULL(&vattr);
1954         vattr.va_uid = uid;
1955         vattr.va_gid = gid;
1956         error = VOP_SETATTR(vp, &vattr, p->p_ucred, td);
1957         VOP_UNLOCK(vp, 0, td);
1958         return error;
1959 }
1960
1961 /*
1962  * chown(char *path, int uid, int gid)
1963  *
1964  * Set ownership given a path name.
1965  */
1966 /* ARGSUSED */
1967 int
1968 chown(struct chown_args *uap)
1969 {
1970         struct thread *td = curthread;
1971         int error;
1972         struct nameidata nd;
1973
1974         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
1975         if ((error = namei(&nd)) != 0)
1976                 return (error);
1977         NDFREE(&nd, NDF_ONLY_PNBUF);
1978         error = setfown(nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid));
1979         vrele(nd.ni_vp);
1980         return (error);
1981 }
1982
1983 /*
1984  * lchown_args(char *path, int uid, int gid)
1985  *
1986  * Set ownership given a path name, do not cross symlinks.
1987  */
1988 /* ARGSUSED */
1989 int
1990 lchown(struct lchown_args *uap)
1991 {
1992         struct thread *td = curthread;
1993         int error;
1994         struct nameidata nd;
1995
1996         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
1997         if ((error = namei(&nd)) != 0)
1998                 return (error);
1999         NDFREE(&nd, NDF_ONLY_PNBUF);
2000         error = setfown(nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid));
2001         vrele(nd.ni_vp);
2002         return (error);
2003 }
2004
2005 /*
2006  * fchown_args(int fd, int uid, int gid)
2007  *
2008  * Set ownership given a file descriptor.
2009  */
2010 /* ARGSUSED */
2011 int
2012 fchown(struct fchown_args *uap)
2013 {
2014         struct thread *td = curthread;
2015         struct proc *p = td->td_proc;
2016         struct file *fp;
2017         int error;
2018
2019         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
2020                 return (error);
2021         return setfown((struct vnode *)fp->f_data,
2022                 SCARG(uap, uid), SCARG(uap, gid));
2023 }
2024
2025 static int
2026 getutimes(const struct timeval *usrtvp, struct timespec *tsp)
2027 {
2028         struct timeval tv[2];
2029         int error;
2030
2031         if (usrtvp == NULL) {
2032                 microtime(&tv[0]);
2033                 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]);
2034                 tsp[1] = tsp[0];
2035         } else {
2036                 if ((error = copyin(usrtvp, tv, sizeof (tv))) != 0)
2037                         return (error);
2038                 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]);
2039                 TIMEVAL_TO_TIMESPEC(&tv[1], &tsp[1]);
2040         }
2041         return 0;
2042 }
2043
2044 static int
2045 setutimes(struct vnode *vp, const struct timespec *ts, int nullflag)
2046 {
2047         struct thread *td = curthread;
2048         struct proc *p = td->td_proc;
2049         int error;
2050         struct vattr vattr;
2051
2052         VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE);
2053         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2054         VATTR_NULL(&vattr);
2055         vattr.va_atime = ts[0];
2056         vattr.va_mtime = ts[1];
2057         if (nullflag)
2058                 vattr.va_vaflags |= VA_UTIMES_NULL;
2059         error = VOP_SETATTR(vp, &vattr, p->p_ucred, td);
2060         VOP_UNLOCK(vp, 0, td);
2061         return error;
2062 }
2063
2064 /*
2065  * utimes_args(char *path, struct timeval *tptr)
2066  *
2067  * Set the access and modification times of a file.
2068  */
2069 /* ARGSUSED */
2070 int
2071 utimes(struct utimes_args *uap)
2072 {
2073         struct thread *td = curthread;
2074         struct timespec ts[2];
2075         struct timeval *usrtvp;
2076         int error;
2077         struct nameidata nd;
2078
2079         usrtvp = SCARG(uap, tptr);
2080         if ((error = getutimes(usrtvp, ts)) != 0)
2081                 return (error);
2082         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
2083         if ((error = namei(&nd)) != 0)
2084                 return (error);
2085         NDFREE(&nd, NDF_ONLY_PNBUF);
2086         error = setutimes(nd.ni_vp, ts, usrtvp == NULL);
2087         vrele(nd.ni_vp);
2088         return (error);
2089 }
2090
2091 /*
2092  * lutimes_args(char *path, struct timeval *tptr)
2093  *
2094  * Set the access and modification times of a file.
2095  */
2096 /* ARGSUSED */
2097 int
2098 lutimes(struct lutimes_args *uap)
2099 {
2100         struct thread *td = curthread;
2101         struct timespec ts[2];
2102         struct timeval *usrtvp;
2103         int error;
2104         struct nameidata nd;
2105
2106         usrtvp = SCARG(uap, tptr);
2107         if ((error = getutimes(usrtvp, ts)) != 0)
2108                 return (error);
2109         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
2110         if ((error = namei(&nd)) != 0)
2111                 return (error);
2112         NDFREE(&nd, NDF_ONLY_PNBUF);
2113         error = setutimes(nd.ni_vp, ts, usrtvp == NULL);
2114         vrele(nd.ni_vp);
2115         return (error);
2116 }
2117
2118 /*
2119  * futimes_args(int fd, struct timeval *tptr)
2120  *
2121  * Set the access and modification times of a file.
2122  */
2123 /* ARGSUSED */
2124 int
2125 futimes(struct futimes_args *uap)
2126 {
2127         struct thread *td = curthread;
2128         struct proc *p = td->td_proc;
2129         struct timespec ts[2];
2130         struct file *fp;
2131         struct timeval *usrtvp;
2132         int error;
2133
2134         usrtvp = SCARG(uap, tptr);
2135         if ((error = getutimes(usrtvp, ts)) != 0)
2136                 return (error);
2137         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
2138                 return (error);
2139         return setutimes((struct vnode *)fp->f_data, ts, usrtvp == NULL);
2140 }
2141
2142 /*
2143  * truncate(char *path, int pad, off_t length)
2144  *
2145  * Truncate a file given its path name.
2146  */
2147 /* ARGSUSED */
2148 int
2149 truncate(struct truncate_args *uap)
2150 {
2151         struct thread *td = curthread;
2152         struct proc *p = td->td_proc;
2153         struct vnode *vp;
2154         struct vattr vattr;
2155         int error;
2156         struct nameidata nd;
2157
2158         if (uap->length < 0)
2159                 return(EINVAL);
2160         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
2161         if ((error = namei(&nd)) != 0)
2162                 return (error);
2163         vp = nd.ni_vp;
2164         NDFREE(&nd, NDF_ONLY_PNBUF);
2165         VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE);
2166         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2167         if (vp->v_type == VDIR)
2168                 error = EISDIR;
2169         else if ((error = vn_writechk(vp)) == 0 &&
2170             (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, td)) == 0) {
2171                 VATTR_NULL(&vattr);
2172                 vattr.va_size = SCARG(uap, length);
2173                 error = VOP_SETATTR(vp, &vattr, p->p_ucred, td);
2174         }
2175         vput(vp);
2176         return (error);
2177 }
2178
2179 /*
2180  * ftruncate_args(int fd, int pad, off_t length)
2181  *
2182  * Truncate a file given a file descriptor.
2183  */
2184 /* ARGSUSED */
2185 int
2186 ftruncate(struct ftruncate_args *uap)
2187 {
2188         struct thread *td = curthread;
2189         struct proc *p = td->td_proc;
2190         struct vattr vattr;
2191         struct vnode *vp;
2192         struct file *fp;
2193         int error;
2194
2195         if (uap->length < 0)
2196                 return(EINVAL);
2197         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
2198                 return (error);
2199         if ((fp->f_flag & FWRITE) == 0)
2200                 return (EINVAL);
2201         vp = (struct vnode *)fp->f_data;
2202         VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE);
2203         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2204         if (vp->v_type == VDIR)
2205                 error = EISDIR;
2206         else if ((error = vn_writechk(vp)) == 0) {
2207                 VATTR_NULL(&vattr);
2208                 vattr.va_size = SCARG(uap, length);
2209                 error = VOP_SETATTR(vp, &vattr, fp->f_cred, td);
2210         }
2211         VOP_UNLOCK(vp, 0, td);
2212         return (error);
2213 }
2214
2215 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
2216 /*
2217  * otruncate_args(char *path, long length)
2218  *
2219  * Truncate a file given its path name.
2220  */
2221 /* ARGSUSED */
2222 int
2223 otruncate(struct otruncate_args *uap)
2224 {
2225         struct truncate_args /* {
2226                 syscallarg(char *) path;
2227                 syscallarg(int) pad;
2228                 syscallarg(off_t) length;
2229         } */ nuap;
2230
2231         SCARG(&nuap, path) = SCARG(uap, path);
2232         SCARG(&nuap, length) = SCARG(uap, length);
2233         return (truncate(&nuap));
2234 }
2235
2236 /*
2237  * oftruncate_args(int fd, long length)
2238  *
2239  * Truncate a file given a file descriptor.
2240  */
2241 /* ARGSUSED */
2242 int
2243 oftruncate(struct oftruncate_args *uap)
2244 {
2245         struct ftruncate_args /* {
2246                 syscallarg(int) fd;
2247                 syscallarg(int) pad;
2248                 syscallarg(off_t) length;
2249         } */ nuap;
2250
2251         SCARG(&nuap, fd) = SCARG(uap, fd);
2252         SCARG(&nuap, length) = SCARG(uap, length);
2253         return (ftruncate(&nuap));
2254 }
2255 #endif /* COMPAT_43 || COMPAT_SUNOS */
2256
2257 /*
2258  * fsync(int fd)
2259  *
2260  * Sync an open file.
2261  */
2262 /* ARGSUSED */
2263 int
2264 fsync(struct fsync_args *uap)
2265 {
2266         struct thread *td = curthread;
2267         struct proc *p = td->td_proc;
2268         struct vnode *vp;
2269         struct file *fp;
2270         vm_object_t obj;
2271         int error;
2272
2273         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
2274                 return (error);
2275         vp = (struct vnode *)fp->f_data;
2276         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2277         if (VOP_GETVOBJECT(vp, &obj) == 0)
2278                 vm_object_page_clean(obj, 0, 0, 0);
2279         if ((error = VOP_FSYNC(vp, MNT_WAIT, td)) == 0 &&
2280             vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP) &&
2281             bioops.io_fsync)
2282                 error = (*bioops.io_fsync)(vp);
2283         VOP_UNLOCK(vp, 0, td);
2284         return (error);
2285 }
2286
2287 /*
2288  * rename_args(char *from, char *to)
2289  *
2290  * Rename files.  Source and destination must either both be directories,
2291  * or both not be directories.  If target is a directory, it must be empty.
2292  */
2293 /* ARGSUSED */
2294 int
2295 rename(struct rename_args *uap)
2296 {
2297         struct thread *td = curthread;
2298         struct proc *p = td->td_proc;
2299         struct vnode *tvp, *fvp, *tdvp;
2300         struct nameidata fromnd, tond;
2301         int error;
2302
2303         bwillwrite();
2304         NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE,
2305             SCARG(uap, from), td);
2306         if ((error = namei(&fromnd)) != 0)
2307                 return (error);
2308         fvp = fromnd.ni_vp;
2309         NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | NOOBJ,
2310             UIO_USERSPACE, SCARG(uap, to), td);
2311         if (fromnd.ni_vp->v_type == VDIR)
2312                 tond.ni_cnd.cn_flags |= WILLBEDIR;
2313         if ((error = namei(&tond)) != 0) {
2314                 /* Translate error code for rename("dir1", "dir2/."). */
2315                 if (error == EISDIR && fvp->v_type == VDIR)
2316                         error = EINVAL;
2317                 NDFREE(&fromnd, NDF_ONLY_PNBUF);
2318                 vrele(fromnd.ni_dvp);
2319                 vrele(fvp);
2320                 goto out1;
2321         }
2322         tdvp = tond.ni_dvp;
2323         tvp = tond.ni_vp;
2324         if (tvp != NULL) {
2325                 if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
2326                         error = ENOTDIR;
2327                         goto out;
2328                 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
2329                         error = EISDIR;
2330                         goto out;
2331                 }
2332         }
2333         if (fvp == tdvp)
2334                 error = EINVAL;
2335         /*
2336          * If the source is the same as the destination (that is, if they
2337          * are links to the same vnode), then there is nothing to do.
2338          */
2339         if (fvp == tvp)
2340                 error = -1;
2341 out:
2342         if (!error) {
2343                 VOP_LEASE(tdvp, td, p->p_ucred, LEASE_WRITE);
2344                 if (fromnd.ni_dvp != tdvp) {
2345                         VOP_LEASE(fromnd.ni_dvp, td, p->p_ucred, LEASE_WRITE);
2346                 }
2347                 if (tvp) {
2348                         VOP_LEASE(tvp, td, p->p_ucred, LEASE_WRITE);
2349                 }
2350                 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
2351                                    tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
2352                 NDFREE(&fromnd, NDF_ONLY_PNBUF);
2353                 NDFREE(&tond, NDF_ONLY_PNBUF);
2354         } else {
2355                 NDFREE(&fromnd, NDF_ONLY_PNBUF);
2356                 NDFREE(&tond, NDF_ONLY_PNBUF);
2357                 if (tdvp == tvp)
2358                         vrele(tdvp);
2359                 else
2360                         vput(tdvp);
2361                 if (tvp)
2362                         vput(tvp);
2363                 vrele(fromnd.ni_dvp);
2364                 vrele(fvp);
2365         }
2366         vrele(tond.ni_startdir);
2367         ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename");
2368         ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename");
2369         ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename");
2370         ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename");
2371 out1:
2372         if (fromnd.ni_startdir)
2373                 vrele(fromnd.ni_startdir);
2374         if (error == -1)
2375                 return (0);
2376         return (error);
2377 }
2378
2379 /*
2380  * mkdir_args(char *path, int mode)
2381  *
2382  * Make a directory file.
2383  */
2384 /* ARGSUSED */
2385 int
2386 mkdir(struct mkdir_args *uap)
2387 {
2388         struct thread *td = curthread;
2389         struct proc *p = td->td_proc;
2390         struct vnode *vp;
2391         struct vattr vattr;
2392         int error;
2393         struct nameidata nd;
2394
2395         bwillwrite();
2396         NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), td);
2397         nd.ni_cnd.cn_flags |= WILLBEDIR;
2398         if ((error = namei(&nd)) != 0)
2399                 return (error);
2400         vp = nd.ni_vp;
2401         if (vp != NULL) {
2402                 NDFREE(&nd, NDF_ONLY_PNBUF);
2403                 if (nd.ni_dvp == vp)
2404                         vrele(nd.ni_dvp);
2405                 else
2406                         vput(nd.ni_dvp);
2407                 vrele(vp);
2408                 return (EEXIST);
2409         }
2410         VATTR_NULL(&vattr);
2411         vattr.va_type = VDIR;
2412         vattr.va_mode = (SCARG(uap, mode) & ACCESSPERMS) &~ p->p_fd->fd_cmask;
2413         VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE);
2414         error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
2415         NDFREE(&nd, NDF_ONLY_PNBUF);
2416         vput(nd.ni_dvp);
2417         if (!error)
2418                 vput(nd.ni_vp);
2419         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir");
2420         ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir");
2421         return (error);
2422 }
2423
2424 /*
2425  * rmdir_args(char *path)
2426  *
2427  * Remove a directory file.
2428  */
2429 /* ARGSUSED */
2430 int
2431 rmdir(struct rmdir_args *uap)
2432 {
2433         struct thread *td = curthread;
2434         struct proc *p = td->td_proc;
2435         struct vnode *vp;
2436         int error;
2437         struct nameidata nd;
2438
2439         bwillwrite();
2440         NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE,
2441             SCARG(uap, path), td);
2442         if ((error = namei(&nd)) != 0)
2443                 return (error);
2444         vp = nd.ni_vp;
2445         if (vp->v_type != VDIR) {
2446                 error = ENOTDIR;
2447                 goto out;
2448         }
2449         /*
2450          * No rmdir "." please.
2451          */
2452         if (nd.ni_dvp == vp) {
2453                 error = EINVAL;
2454                 goto out;
2455         }
2456         /*
2457          * The root of a mounted filesystem cannot be deleted.
2458          */
2459         if (vp->v_flag & VROOT)
2460                 error = EBUSY;
2461         else {
2462                 VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE);
2463                 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE);
2464                 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
2465         }
2466 out:
2467         NDFREE(&nd, NDF_ONLY_PNBUF);
2468         if (nd.ni_dvp == vp)
2469                 vrele(nd.ni_dvp);
2470         else
2471                 vput(nd.ni_dvp);
2472         if (vp != NULLVP)
2473                 vput(vp);
2474         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir");
2475         ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir");
2476         return (error);
2477 }
2478
2479 #ifdef COMPAT_43
2480 /*
2481  * ogetdirentries_args(int fd, char *buf, u_int count, long *basep)
2482  *
2483  * Read a block of directory entries in a file system independent format.
2484  */
2485 int
2486 ogetdirentries(struct ogetdirentries_args *uap)
2487 {
2488         struct thread *td = curthread;
2489         struct proc *p = td->td_proc;
2490         struct vnode *vp;
2491         struct file *fp;
2492         struct uio auio, kuio;
2493         struct iovec aiov, kiov;
2494         struct dirent *dp, *edp;
2495         caddr_t dirbuf;
2496         int error, eofflag, readcnt;
2497         long loff;
2498
2499         /* XXX arbitrary sanity limit on `count'. */
2500         if (SCARG(uap, count) > 64 * 1024)
2501                 return (EINVAL);
2502         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
2503                 return (error);
2504         if ((fp->f_flag & FREAD) == 0)
2505                 return (EBADF);
2506         vp = (struct vnode *)fp->f_data;
2507 unionread:
2508         if (vp->v_type != VDIR)
2509                 return (EINVAL);
2510         aiov.iov_base = SCARG(uap, buf);
2511         aiov.iov_len = SCARG(uap, count);
2512         auio.uio_iov = &aiov;
2513         auio.uio_iovcnt = 1;
2514         auio.uio_rw = UIO_READ;
2515         auio.uio_segflg = UIO_USERSPACE;
2516         auio.uio_td = td;
2517         auio.uio_resid = SCARG(uap, count);
2518         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2519         loff = auio.uio_offset = fp->f_offset;
2520 #       if (BYTE_ORDER != LITTLE_ENDIAN)
2521                 if (vp->v_mount->mnt_maxsymlinklen <= 0) {
2522                         error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
2523                             NULL, NULL);
2524                         fp->f_offset = auio.uio_offset;
2525                 } else
2526 #       endif
2527         {
2528                 kuio = auio;
2529                 kuio.uio_iov = &kiov;
2530                 kuio.uio_segflg = UIO_SYSSPACE;
2531                 kiov.iov_len = SCARG(uap, count);
2532                 MALLOC(dirbuf, caddr_t, SCARG(uap, count), M_TEMP, M_WAITOK);
2533                 kiov.iov_base = dirbuf;
2534                 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag,
2535                             NULL, NULL);
2536                 fp->f_offset = kuio.uio_offset;
2537                 if (error == 0) {
2538                         readcnt = SCARG(uap, count) - kuio.uio_resid;
2539                         edp = (struct dirent *)&dirbuf[readcnt];
2540                         for (dp = (struct dirent *)dirbuf; dp < edp; ) {
2541 #                               if (BYTE_ORDER == LITTLE_ENDIAN)
2542                                         /*
2543                                          * The expected low byte of
2544                                          * dp->d_namlen is our dp->d_type.
2545                                          * The high MBZ byte of dp->d_namlen
2546                                          * is our dp->d_namlen.
2547                                          */
2548                                         dp->d_type = dp->d_namlen;
2549                                         dp->d_namlen = 0;
2550 #                               else
2551                                         /*
2552                                          * The dp->d_type is the high byte
2553                                          * of the expected dp->d_namlen,
2554                                          * so must be zero'ed.
2555                                          */
2556                                         dp->d_type = 0;
2557 #                               endif
2558                                 if (dp->d_reclen > 0) {
2559                                         dp = (struct dirent *)
2560                                             ((char *)dp + dp->d_reclen);
2561                                 } else {
2562                                         error = EIO;
2563                                         break;
2564                                 }
2565                         }
2566                         if (dp >= edp)
2567                                 error = uiomove(dirbuf, readcnt, &auio);
2568                 }
2569                 FREE(dirbuf, M_TEMP);
2570         }
2571         VOP_UNLOCK(vp, 0, td);
2572         if (error)
2573                 return (error);
2574         if (SCARG(uap, count) == auio.uio_resid) {
2575                 if (union_dircheckp) {
2576                         error = union_dircheckp(td, &vp, fp);
2577                         if (error == -1)
2578                                 goto unionread;
2579                         if (error)
2580                                 return (error);
2581                 }
2582                 if ((vp->v_flag & VROOT) &&
2583                     (vp->v_mount->mnt_flag & MNT_UNION)) {
2584                         struct vnode *tvp = vp;
2585                         vp = vp->v_mount->mnt_vnodecovered;
2586                         VREF(vp);
2587                         fp->f_data = (caddr_t) vp;
2588                         fp->f_offset = 0;
2589                         vrele(tvp);
2590                         goto unionread;
2591                 }
2592         }
2593         error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
2594             sizeof(long));
2595         uap->sysmsg_result = SCARG(uap, count) - auio.uio_resid;
2596         return (error);
2597 }
2598 #endif /* COMPAT_43 */
2599
2600 /*
2601  * getdirentries_args(int fd, char *buf, u_int conut, long *basep)
2602  *
2603  * Read a block of directory entries in a file system independent format.
2604  */
2605 int
2606 getdirentries(struct getdirentries_args *uap)
2607 {
2608         struct thread *td = curthread;
2609         struct proc *p = td->td_proc;
2610         struct vnode *vp;
2611         struct file *fp;
2612         struct uio auio;
2613         struct iovec aiov;
2614         long loff;
2615         int error, eofflag;
2616
2617         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
2618                 return (error);
2619         if ((fp->f_flag & FREAD) == 0)
2620                 return (EBADF);
2621         vp = (struct vnode *)fp->f_data;
2622 unionread:
2623         if (vp->v_type != VDIR)
2624                 return (EINVAL);
2625         aiov.iov_base = SCARG(uap, buf);
2626         aiov.iov_len = SCARG(uap, count);
2627         auio.uio_iov = &aiov;
2628         auio.uio_iovcnt = 1;
2629         auio.uio_rw = UIO_READ;
2630         auio.uio_segflg = UIO_USERSPACE;
2631         auio.uio_td = td;
2632         auio.uio_resid = SCARG(uap, count);
2633         /* vn_lock(vp, LK_SHARED | LK_RETRY, td); */
2634         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2635         loff = auio.uio_offset = fp->f_offset;
2636         error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL);
2637         fp->f_offset = auio.uio_offset;
2638         VOP_UNLOCK(vp, 0, td);
2639         if (error)
2640                 return (error);
2641         if (SCARG(uap, count) == auio.uio_resid) {
2642                 if (union_dircheckp) {
2643                         error = union_dircheckp(td, &vp, fp);
2644                         if (error == -1)
2645                                 goto unionread;
2646                         if (error)
2647                                 return (error);
2648                 }
2649                 if ((vp->v_flag & VROOT) &&
2650                     (vp->v_mount->mnt_flag & MNT_UNION)) {
2651                         struct vnode *tvp = vp;
2652                         vp = vp->v_mount->mnt_vnodecovered;
2653                         VREF(vp);
2654                         fp->f_data = (caddr_t) vp;
2655                         fp->f_offset = 0;
2656                         vrele(tvp);
2657                         goto unionread;
2658                 }
2659         }
2660         if (SCARG(uap, basep) != NULL) {
2661                 error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
2662                     sizeof(long));
2663         }
2664         uap->sysmsg_result = SCARG(uap, count) - auio.uio_resid;
2665         return (error);
2666 }
2667
2668 /*
2669  * getdents_args(int fd, char *buf, size_t count)
2670  */
2671 int
2672 getdents(struct getdents_args *uap)
2673 {
2674         struct getdirentries_args ap;
2675
2676         ap.fd = uap->fd;
2677         ap.buf = uap->buf;
2678         ap.count = uap->count;
2679         ap.basep = NULL;
2680         return getdirentries(&ap);
2681 }
2682
2683 /*
2684  * umask(int newmask)
2685  *
2686  * Set the mode mask for creation of filesystem nodes.
2687  *
2688  * MP SAFE
2689  */
2690 int
2691 umask(struct umask_args *uap)
2692 {
2693         struct thread *td = curthread;
2694         struct proc *p = td->td_proc;
2695         struct filedesc *fdp;
2696
2697         fdp = p->p_fd;
2698         uap->sysmsg_result = fdp->fd_cmask;
2699         fdp->fd_cmask = SCARG(uap, newmask) & ALLPERMS;
2700         return (0);
2701 }
2702
2703 /*
2704  * revoke(char *path)
2705  *
2706  * Void all references to file by ripping underlying filesystem
2707  * away from vnode.
2708  */
2709 /* ARGSUSED */
2710 int
2711 revoke(struct revoke_args *uap)
2712 {
2713         struct thread *td = curthread;
2714         struct proc *p = td->td_proc;
2715         struct vnode *vp;
2716         struct vattr vattr;
2717         int error;
2718         struct nameidata nd;
2719
2720         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
2721         if ((error = namei(&nd)) != 0)
2722                 return (error);
2723         vp = nd.ni_vp;
2724         NDFREE(&nd, NDF_ONLY_PNBUF);
2725         if (vp->v_type != VCHR && vp->v_type != VBLK) {
2726                 error = EINVAL;
2727                 goto out;
2728         }
2729         if ((error = VOP_GETATTR(vp, &vattr, td)) != 0)
2730                 goto out;
2731         if (p->p_ucred->cr_uid != vattr.va_uid &&
2732             (error = suser_cred(p->p_ucred, PRISON_ROOT)))
2733                 goto out;
2734         if (vcount(vp) > 1)
2735                 VOP_REVOKE(vp, REVOKEALL);
2736 out:
2737         vrele(vp);
2738         return (error);
2739 }
2740
2741 /*
2742  * Convert a user file descriptor to a kernel file entry.
2743  */
2744 int
2745 getvnode(struct filedesc *fdp, int fd, struct file **fpp)
2746 {
2747         struct file *fp;
2748
2749         if ((u_int)fd >= fdp->fd_nfiles ||
2750             (fp = fdp->fd_ofiles[fd]) == NULL)
2751                 return (EBADF);
2752         if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO)
2753                 return (EINVAL);
2754         *fpp = fp;
2755         return (0);
2756 }
2757 /*
2758  * getfh_args(char *fname, fhandle_t *fhp)
2759  *
2760  * Get (NFS) file handle
2761  */
2762 int
2763 getfh(struct getfh_args *uap)
2764 {
2765         struct thread *td = curthread;
2766         struct nameidata nd;
2767         fhandle_t fh;
2768         struct vnode *vp;
2769         int error;
2770
2771         /*
2772          * Must be super user
2773          */
2774         error = suser(td);
2775         if (error)
2776                 return (error);
2777         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, td);
2778         error = namei(&nd);
2779         if (error)
2780                 return (error);
2781         NDFREE(&nd, NDF_ONLY_PNBUF);
2782         vp = nd.ni_vp;
2783         bzero(&fh, sizeof(fh));
2784         fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
2785         error = VFS_VPTOFH(vp, &fh.fh_fid);
2786         vput(vp);
2787         if (error)
2788                 return (error);
2789         error = copyout(&fh, uap->fhp, sizeof (fh));
2790         return (error);
2791 }
2792
2793 /*
2794  * fhopen_args(const struct fhandle *u_fhp, int flags)
2795  *
2796  * syscall for the rpc.lockd to use to translate a NFS file handle into
2797  * an open descriptor.
2798  *
2799  * warning: do not remove the suser() call or this becomes one giant
2800  * security hole.
2801  */
2802 int
2803 fhopen(struct fhopen_args *uap)
2804 {
2805         struct thread *td = curthread;
2806         struct proc *p = td->td_proc;
2807         struct mount *mp;
2808         struct vnode *vp;
2809         struct fhandle fhp;
2810         struct vattr vat;
2811         struct vattr *vap = &vat;
2812         struct flock lf;
2813         struct file *fp;
2814         struct filedesc *fdp = p->p_fd;
2815         int fmode, mode, error, type;
2816         struct file *nfp; 
2817         int indx;
2818
2819         /*
2820          * Must be super user
2821          */
2822         error = suser(td);
2823         if (error)
2824                 return (error);
2825
2826         fmode = FFLAGS(SCARG(uap, flags));
2827         /* why not allow a non-read/write open for our lockd? */
2828         if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT))
2829                 return (EINVAL);
2830         error = copyin(SCARG(uap,u_fhp), &fhp, sizeof(fhp));
2831         if (error)
2832                 return(error);
2833         /* find the mount point */
2834         mp = vfs_getvfs(&fhp.fh_fsid);
2835         if (mp == NULL)
2836                 return (ESTALE);
2837         /* now give me my vnode, it gets returned to me locked */
2838         error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp);
2839         if (error)
2840                 return (error);
2841         /*
2842          * from now on we have to make sure not
2843          * to forget about the vnode
2844          * any error that causes an abort must vput(vp) 
2845          * just set error = err and 'goto bad;'.
2846          */
2847
2848         /* 
2849          * from vn_open 
2850          */
2851         if (vp->v_type == VLNK) {
2852                 error = EMLINK;
2853                 goto bad;
2854         }
2855         if (vp->v_type == VSOCK) {
2856                 error = EOPNOTSUPP;
2857                 goto bad;
2858         }
2859         mode = 0;
2860         if (fmode & (FWRITE | O_TRUNC)) {
2861                 if (vp->v_type == VDIR) {
2862                         error = EISDIR;
2863                         goto bad;
2864                 }
2865                 error = vn_writechk(vp);
2866                 if (error)
2867                         goto bad;
2868                 mode |= VWRITE;
2869         }
2870         if (fmode & FREAD)
2871                 mode |= VREAD;
2872         if (mode) {
2873                 error = VOP_ACCESS(vp, mode, p->p_ucred, td);
2874                 if (error)
2875                         goto bad;
2876         }
2877         if (fmode & O_TRUNC) {
2878                 VOP_UNLOCK(vp, 0, td);                          /* XXX */
2879                 VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE);
2880                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);       /* XXX */
2881                 VATTR_NULL(vap);
2882                 vap->va_size = 0;
2883                 error = VOP_SETATTR(vp, vap, p->p_ucred, td);
2884                 if (error)
2885                         goto bad;
2886         }
2887         error = VOP_OPEN(vp, fmode, p->p_ucred, td);
2888         if (error)
2889                 goto bad;
2890         /*
2891          * Make sure that a VM object is created for VMIO support.
2892          */
2893         if (vn_canvmio(vp) == TRUE) {
2894                 if ((error = vfs_object_create(vp, td)) != 0)
2895                         goto bad;
2896         }
2897         if (fmode & FWRITE)
2898                 vp->v_writecount++;
2899
2900         /*
2901          * end of vn_open code 
2902          */
2903
2904         if ((error = falloc(p, &nfp, &indx)) != 0) {
2905                 if (fmode & FWRITE)
2906                         vp->v_writecount--;
2907                 goto bad;
2908         }
2909         fp = nfp;       
2910
2911         /*
2912          * hold an extra reference to avoid having fp ripped out
2913          * from under us while we block in the lock op.
2914          */
2915         fhold(fp);
2916         nfp->f_data = (caddr_t)vp;
2917         nfp->f_flag = fmode & FMASK;
2918         nfp->f_ops = &vnops;
2919         nfp->f_type = DTYPE_VNODE;
2920         if (fmode & (O_EXLOCK | O_SHLOCK)) {
2921                 lf.l_whence = SEEK_SET;
2922                 lf.l_start = 0;
2923                 lf.l_len = 0;
2924                 if (fmode & O_EXLOCK)
2925                         lf.l_type = F_WRLCK;
2926                 else
2927                         lf.l_type = F_RDLCK;
2928                 type = F_FLOCK;
2929                 if ((fmode & FNONBLOCK) == 0)
2930                         type |= F_WAIT;
2931                 VOP_UNLOCK(vp, 0, td);
2932                 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) {
2933                         /*
2934                          * lock request failed.  Normally close the descriptor
2935                          * but handle the case where someone might have dup()d
2936                          * or close()d it when we weren't looking.
2937                          */
2938                         if (fdp->fd_ofiles[indx] == fp) {
2939                                 fdp->fd_ofiles[indx] = NULL;
2940                                 fdrop(fp, td);
2941                         }
2942
2943                         /*
2944                          * release our private reference.
2945                          */
2946                         fdrop(fp, td);
2947                         return (error);
2948                 }
2949                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2950                 fp->f_flag |= FHASLOCK;
2951         }
2952         if ((vp->v_type == VREG) && (VOP_GETVOBJECT(vp, NULL) != 0))
2953                 vfs_object_create(vp, td);
2954
2955         VOP_UNLOCK(vp, 0, td);
2956         fdrop(fp, td);
2957         uap->sysmsg_result = indx;
2958         return (0);
2959
2960 bad:
2961         vput(vp);
2962         return (error);
2963 }
2964
2965 /*
2966  * fhstat_args(struct fhandle *u_fhp, struct stat *sb)
2967  */
2968 int
2969 fhstat(struct fhstat_args *uap)
2970 {
2971         struct thread *td = curthread;
2972         struct stat sb;
2973         fhandle_t fh;
2974         struct mount *mp;
2975         struct vnode *vp;
2976         int error;
2977
2978         /*
2979          * Must be super user
2980          */
2981         error = suser(td);
2982         if (error)
2983                 return (error);
2984         
2985         error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t));
2986         if (error)
2987                 return (error);
2988
2989         if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
2990                 return (ESTALE);
2991         if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
2992                 return (error);
2993         error = vn_stat(vp, &sb, td);
2994         vput(vp);
2995         if (error)
2996                 return (error);
2997         error = copyout(&sb, SCARG(uap, sb), sizeof(sb));
2998         return (error);
2999 }
3000
3001 /*
3002  * fhstatfs_args(struct fhandle *u_fhp, struct statfs *buf)
3003  */
3004 int
3005 fhstatfs(struct fhstatfs_args *uap)
3006 {
3007         struct thread *td = curthread;
3008         struct statfs *sp;
3009         struct mount *mp;
3010         struct vnode *vp;
3011         struct statfs sb;
3012         fhandle_t fh;
3013         int error;
3014
3015         /*
3016          * Must be super user
3017          */
3018         if ((error = suser(td)))
3019                 return (error);
3020
3021         if ((error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t))) != 0)
3022                 return (error);
3023
3024         if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
3025                 return (ESTALE);
3026         if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
3027                 return (error);
3028         mp = vp->v_mount;
3029         sp = &mp->mnt_stat;
3030         vput(vp);
3031         if ((error = VFS_STATFS(mp, sp, td)) != 0)
3032                 return (error);
3033         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
3034         if (suser(td)) {
3035                 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
3036                 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
3037                 sp = &sb;
3038         }
3039         return (copyout(sp, SCARG(uap, buf), sizeof(*sp)));
3040 }
3041
3042 /*
3043  * Syscall to push extended attribute configuration information into the
3044  * VFS.  Accepts a path, which it converts to a mountpoint, as well as
3045  * a command (int cmd), and attribute name and misc data.  For now, the
3046  * attribute name is left in userspace for consumption by the VFS_op.
3047  * It will probably be changed to be copied into sysspace by the
3048  * syscall in the future, once issues with various consumers of the
3049  * attribute code have raised their hands.
3050  *
3051  * Currently this is used only by UFS Extended Attributes.
3052  */
3053 int
3054 extattrctl(struct extattrctl_args *uap)
3055 {
3056         struct thread *td = curthread;
3057         struct nameidata nd;
3058         struct mount *mp;
3059         int error;
3060
3061         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td);
3062         if ((error = namei(&nd)) != 0)
3063                 return (error);
3064         mp = nd.ni_vp->v_mount;
3065         NDFREE(&nd, 0);
3066         return (VFS_EXTATTRCTL(mp, SCARG(uap, cmd), SCARG(uap, attrname),
3067             SCARG(uap, arg), td));
3068 }
3069
3070 /*
3071  * Syscall to set a named extended attribute on a file or directory.
3072  * Accepts attribute name, and a uio structure pointing to the data to set.
3073  * The uio is consumed in the style of writev().  The real work happens
3074  * in VOP_SETEXTATTR().
3075  */
3076 int
3077 extattr_set_file(struct extattr_set_file_args *uap)
3078 {
3079         struct thread *td = curthread;
3080         struct proc *p = td->td_proc;
3081         struct nameidata nd;
3082         struct uio auio;
3083         struct iovec *iov, *needfree = NULL, aiov[UIO_SMALLIOV];
3084         char attrname[EXTATTR_MAXNAMELEN];
3085         u_int iovlen, cnt;
3086         int error, i;
3087
3088         error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN);
3089         if (error)
3090                 return (error);
3091         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
3092             SCARG(uap, path), td);
3093         if ((error = namei(&nd)) != 0)
3094                 return(error);
3095         iovlen = uap->iovcnt * sizeof(struct iovec);
3096         if (uap->iovcnt > UIO_SMALLIOV) {
3097                 if (uap->iovcnt > UIO_MAXIOV) {
3098                         error = EINVAL;
3099                         goto done;
3100                 }
3101                 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
3102                 needfree = iov;
3103         } else
3104                 iov = aiov;
3105         auio.uio_iov = iov;
3106         auio.uio_iovcnt = uap->iovcnt;
3107         auio.uio_rw = UIO_WRITE;
3108         auio.uio_segflg = UIO_USERSPACE;
3109         auio.uio_td = td;
3110         auio.uio_offset = 0;
3111         if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen)))
3112                 goto done;
3113         auio.uio_resid = 0;
3114         for (i = 0; i < uap->iovcnt; i++) {
3115                 if (iov->iov_len > INT_MAX - auio.uio_resid) {
3116                         error = EINVAL;
3117                         goto done;
3118                 }
3119                 auio.uio_resid += iov->iov_len;
3120                 iov++;
3121         }
3122         cnt = auio.uio_resid;
3123         error = VOP_SETEXTATTR(nd.ni_vp, attrname, &auio, p->p_ucred, td);
3124         cnt -= auio.uio_resid;
3125         uap->sysmsg_result = cnt;
3126 done:
3127         if (needfree)
3128                 FREE(needfree, M_IOV);
3129         NDFREE(&nd, 0);
3130         return (error);
3131 }
3132
3133 /*
3134  * Syscall to get a named extended attribute on a file or directory.
3135  * Accepts attribute name, and a uio structure pointing to a buffer for the
3136  * data.  The uio is consumed in the style of readv().  The real work
3137  * happens in VOP_GETEXTATTR();
3138  */
3139 int
3140 extattr_get_file(struct extattr_get_file_args *uap)
3141 {
3142         struct thread *td = curthread;
3143         struct proc *p = td->td_proc;
3144         struct nameidata nd;
3145         struct uio auio;
3146         struct iovec *iov, *needfree, aiov[UIO_SMALLIOV];
3147         char attrname[EXTATTR_MAXNAMELEN];
3148         u_int iovlen, cnt;
3149         int error, i;
3150
3151         error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN);
3152         if (error)
3153                 return (error);
3154         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
3155             SCARG(uap, path), td);
3156         if ((error = namei(&nd)) != 0)
3157                 return (error);
3158         iovlen = uap->iovcnt * sizeof (struct iovec);
3159         if (uap->iovcnt > UIO_SMALLIOV) {
3160                 if (uap->iovcnt > UIO_MAXIOV) {
3161                         NDFREE(&nd, 0);
3162                         return (EINVAL);
3163                 }
3164                 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
3165                 needfree = iov;
3166         } else {
3167                 iov = aiov;
3168                 needfree = NULL;
3169         }
3170         auio.uio_iov = iov;
3171         auio.uio_iovcnt = uap->iovcnt;
3172         auio.uio_rw = UIO_READ;
3173         auio.uio_segflg = UIO_USERSPACE;
3174         auio.uio_td = td;
3175         auio.uio_offset = 0;
3176         if ((error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen)))
3177                 goto done;
3178         auio.uio_resid = 0;
3179         for (i = 0; i < uap->iovcnt; i++) {
3180                 if (iov->iov_len > INT_MAX - auio.uio_resid) {
3181                         error = EINVAL;
3182                         goto done;
3183                 }
3184                 auio.uio_resid += iov->iov_len;
3185                 iov++;
3186         }
3187         cnt = auio.uio_resid;
3188         error = VOP_GETEXTATTR(nd.ni_vp, attrname, &auio, p->p_ucred, td);
3189         cnt -= auio.uio_resid;
3190         uap->sysmsg_result = cnt;
3191 done:
3192         if (needfree)
3193                 FREE(needfree, M_IOV);
3194         NDFREE(&nd, 0);
3195         return(error);
3196 }
3197
3198 /*
3199  * Syscall to delete a named extended attribute from a file or directory.
3200  * Accepts attribute name.  The real work happens in VOP_SETEXTATTR().
3201  */
3202 int
3203 extattr_delete_file(struct extattr_delete_file_args *uap)
3204 {
3205         struct thread *td = curthread;
3206         struct proc *p = td->td_proc;
3207         struct nameidata nd;
3208         char attrname[EXTATTR_MAXNAMELEN];
3209         int     error;
3210
3211         error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN);
3212         if (error)
3213                 return(error);
3214         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
3215             SCARG(uap, path), td);
3216         if ((error = namei(&nd)) != 0)
3217                 return(error);
3218         error = VOP_SETEXTATTR(nd.ni_vp, attrname, NULL, p->p_ucred, td);
3219         NDFREE(&nd, 0);
3220         return(error);
3221 }