]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/vfs_syscalls.c
Avoid code duplication in serval places by introducing universal
[FreeBSD/FreeBSD.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  * 4. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *      @(#)vfs_syscalls.c      8.13 (Berkeley) 4/15/94
35  */
36
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD$");
39
40 #include "opt_compat.h"
41 #include "opt_mac.h"
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/bio.h>
46 #include <sys/buf.h>
47 #include <sys/sysent.h>
48 #include <sys/mac.h>
49 #include <sys/malloc.h>
50 #include <sys/mount.h>
51 #include <sys/mutex.h>
52 #include <sys/sysproto.h>
53 #include <sys/namei.h>
54 #include <sys/filedesc.h>
55 #include <sys/kernel.h>
56 #include <sys/fcntl.h>
57 #include <sys/file.h>
58 #include <sys/limits.h>
59 #include <sys/linker.h>
60 #include <sys/stat.h>
61 #include <sys/sx.h>
62 #include <sys/unistd.h>
63 #include <sys/vnode.h>
64 #include <sys/proc.h>
65 #include <sys/dirent.h>
66 #include <sys/extattr.h>
67 #include <sys/jail.h>
68 #include <sys/syscallsubr.h>
69 #include <sys/sysctl.h>
70
71 #include <machine/stdarg.h>
72
73 #include <vm/vm.h>
74 #include <vm/vm_object.h>
75 #include <vm/vm_page.h>
76 #include <vm/uma.h>
77
78 static int chroot_refuse_vdir_fds(struct filedesc *fdp);
79 static int getutimes(const struct timeval *, enum uio_seg, struct timespec *);
80 static int setfown(struct thread *td, struct vnode *, uid_t, gid_t);
81 static int setfmode(struct thread *td, struct vnode *, int);
82 static int setfflags(struct thread *td, struct vnode *, int);
83 static int setutimes(struct thread *td, struct vnode *,
84     const struct timespec *, int, int);
85 static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred,
86     struct thread *td);
87
88 static int extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
89     size_t nbytes, struct thread *td);
90
91 int (*union_dircheckp)(struct thread *td, struct vnode **, struct file *);
92
93 /*
94  * The module initialization routine for POSIX asynchronous I/O will
95  * set this to the version of AIO that it implements.  (Zero means
96  * that it is not implemented.)  This value is used here by pathconf()
97  * and in kern_descrip.c by fpathconf().
98  */
99 int async_io_version;
100
101 /*
102  * Sync each mounted filesystem.
103  */
104 #ifndef _SYS_SYSPROTO_H_
105 struct sync_args {
106         int     dummy;
107 };
108 #endif
109
110 #ifdef DEBUG
111 static int syncprt = 0;
112 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, "");
113 #endif
114
115 /* ARGSUSED */
116 int
117 sync(td, uap)
118         struct thread *td;
119         struct sync_args *uap;
120 {
121         struct mount *mp, *nmp;
122         int asyncflag;
123
124         mtx_lock(&Giant);
125         mtx_lock(&mountlist_mtx);
126         for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
127                 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
128                         nmp = TAILQ_NEXT(mp, mnt_list);
129                         continue;
130                 }
131                 if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
132                     vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
133                         asyncflag = mp->mnt_flag & MNT_ASYNC;
134                         mp->mnt_flag &= ~MNT_ASYNC;
135                         vfs_msync(mp, MNT_NOWAIT);
136                         VFS_SYNC(mp, MNT_NOWAIT, td);
137                         mp->mnt_flag |= asyncflag;
138                         vn_finished_write(mp);
139                 }
140                 mtx_lock(&mountlist_mtx);
141                 nmp = TAILQ_NEXT(mp, mnt_list);
142                 vfs_unbusy(mp, td);
143         }
144         mtx_unlock(&mountlist_mtx);
145 #if 0
146 /*
147  * XXX don't call vfs_bufstats() yet because that routine
148  * was not imported in the Lite2 merge.
149  */
150 #ifdef DIAGNOSTIC
151         if (syncprt)
152                 vfs_bufstats();
153 #endif /* DIAGNOSTIC */
154 #endif
155         mtx_unlock(&Giant);
156         return (0);
157 }
158
159 /* XXX PRISON: could be per prison flag */
160 static int prison_quotas;
161 #if 0
162 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, "");
163 #endif
164
165 /*
166  * Change filesystem quotas.
167  *
168  * MP SAFE
169  */
170 #ifndef _SYS_SYSPROTO_H_
171 struct quotactl_args {
172         char *path;
173         int cmd;
174         int uid;
175         caddr_t arg;
176 };
177 #endif
178 int
179 quotactl(td, uap)
180         struct thread *td;
181         register struct quotactl_args /* {
182                 char *path;
183                 int cmd;
184                 int uid;
185                 caddr_t arg;
186         } */ *uap;
187 {
188         struct mount *mp, *vmp;
189         int error;
190         struct nameidata nd;
191
192         if (jailed(td->td_ucred) && !prison_quotas)
193                 return (EPERM);
194         mtx_lock(&Giant);
195         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
196         if ((error = namei(&nd)) != 0) {
197                 mtx_unlock(&Giant);
198                 return (error);
199         }
200         NDFREE(&nd, NDF_ONLY_PNBUF);
201         error = vn_start_write(nd.ni_vp, &vmp, V_WAIT | PCATCH);
202         mp = nd.ni_vp->v_mount;
203         vrele(nd.ni_vp);
204         if (error) {
205                 mtx_unlock(&Giant);
206                 return (error);
207         }
208         error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg, td);
209         vn_finished_write(vmp);
210         mtx_unlock(&Giant);
211         return (error);
212 }
213
214 /*
215  * Get filesystem statistics.
216  */
217 #ifndef _SYS_SYSPROTO_H_
218 struct statfs_args {
219         char *path;
220         struct statfs *buf;
221 };
222 #endif
223 int
224 statfs(td, uap)
225         struct thread *td;
226         register struct statfs_args /* {
227                 char *path;
228                 struct statfs *buf;
229         } */ *uap;
230 {
231         struct statfs sf;
232         int error;
233
234         error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
235         if (error == 0)
236                 error = copyout(&sf, uap->buf, sizeof(sf));
237         return (error);
238 }
239
240 int
241 kern_statfs(struct thread *td, char *path, enum uio_seg pathseg,
242     struct statfs *buf)
243 {
244         struct mount *mp;
245         struct statfs *sp, sb;
246         int error;
247         struct nameidata nd;
248
249         mtx_lock(&Giant);
250         NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td);
251         error = namei(&nd);
252         if (error) {
253                 mtx_unlock(&Giant);
254                 return (error);
255         }
256         mp = nd.ni_vp->v_mount;
257         sp = &mp->mnt_stat;
258         NDFREE(&nd, NDF_ONLY_PNBUF);
259         vrele(nd.ni_vp);
260 #ifdef MAC
261         error = mac_check_mount_stat(td->td_ucred, mp);
262         if (error) {
263                 mtx_unlock(&Giant);
264                 return (error);
265         }
266 #endif
267         /*
268          * Set these in case the underlying filesystem fails to do so.
269          */
270         sp->f_version = STATFS_VERSION;
271         sp->f_namemax = NAME_MAX;
272         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
273         error = VFS_STATFS(mp, sp, td);
274         mtx_unlock(&Giant);
275         if (error)
276                 return (error);
277         if (suser(td)) {
278                 bcopy(sp, &sb, sizeof(sb));
279                 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
280                 sp = &sb;
281         }
282         *buf = *sp;
283         return (0);
284 }
285
286 /*
287  * Get filesystem statistics.
288  */
289 #ifndef _SYS_SYSPROTO_H_
290 struct fstatfs_args {
291         int fd;
292         struct statfs *buf;
293 };
294 #endif
295 int
296 fstatfs(td, uap)
297         struct thread *td;
298         register struct fstatfs_args /* {
299                 int fd;
300                 struct statfs *buf;
301         } */ *uap;
302 {
303         struct statfs sf;
304         int error;
305
306         error = kern_fstatfs(td, uap->fd, &sf);
307         if (error == 0)
308                 error = copyout(&sf, uap->buf, sizeof(sf));
309         return (error);
310 }
311
312 int
313 kern_fstatfs(struct thread *td, int fd, struct statfs *buf)
314 {
315         struct file *fp;
316         struct mount *mp;
317         struct statfs *sp, sb;
318         int error;
319
320         error = getvnode(td->td_proc->p_fd, fd, &fp);
321         if (error)
322                 return (error);
323         mtx_lock(&Giant);
324         mp = fp->f_vnode->v_mount;
325         fdrop(fp, td);
326         if (mp == NULL) {
327                 mtx_unlock(&Giant);
328                 return (EBADF);
329         }
330 #ifdef MAC
331         error = mac_check_mount_stat(td->td_ucred, mp);
332         if (error) {
333                 mtx_unlock(&Giant);
334                 return (error);
335         }
336 #endif
337         sp = &mp->mnt_stat;
338         /*
339          * Set these in case the underlying filesystem fails to do so.
340          */
341         sp->f_version = STATFS_VERSION;
342         sp->f_namemax = NAME_MAX;
343         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
344         error = VFS_STATFS(mp, sp, td);
345         mtx_unlock(&Giant);
346         if (error)
347                 return (error);
348         if (suser(td)) {
349                 bcopy(sp, &sb, sizeof(sb));
350                 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
351                 sp = &sb;
352         }
353         *buf = *sp;
354         return (0);
355 }
356
357 /*
358  * Get statistics on all filesystems.
359  */
360 #ifndef _SYS_SYSPROTO_H_
361 struct getfsstat_args {
362         struct statfs *buf;
363         long bufsize;
364         int flags;
365 };
366 #endif
367 int
368 getfsstat(td, uap)
369         struct thread *td;
370         register struct getfsstat_args /* {
371                 struct statfs *buf;
372                 long bufsize;
373                 int flags;
374         } */ *uap;
375 {
376
377         return (kern_getfsstat(td, uap->buf, uap->bufsize, UIO_USERSPACE,
378             uap->flags));
379 }
380
381 int
382 kern_getfsstat(struct thread *td, struct statfs *buf, size_t bufsize,
383     enum uio_seg bufseg, int flags)
384 {
385         struct mount *mp, *nmp;
386         struct statfs *sfsp, *sp, sb;
387         size_t count, maxcount;
388         int error;
389
390         maxcount = bufsize / sizeof(struct statfs);
391         sfsp = buf;
392         count = 0;
393         mtx_lock(&Giant);
394         mtx_lock(&mountlist_mtx);
395         for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
396                 if (!prison_check_mount(td->td_ucred, mp)) {
397                         nmp = TAILQ_NEXT(mp, mnt_list);
398                         continue;
399                 }
400 #ifdef MAC
401                 if (mac_check_mount_stat(td->td_ucred, mp) != 0) {
402                         nmp = TAILQ_NEXT(mp, mnt_list);
403                         continue;
404                 }
405 #endif
406                 if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
407                         nmp = TAILQ_NEXT(mp, mnt_list);
408                         continue;
409                 }
410                 if (sfsp && count < maxcount) {
411                         sp = &mp->mnt_stat;
412                         /*
413                          * Set these in case the underlying filesystem
414                          * fails to do so.
415                          */
416                         sp->f_version = STATFS_VERSION;
417                         sp->f_namemax = NAME_MAX;
418                         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
419                         /*
420                          * If MNT_NOWAIT or MNT_LAZY is specified, do not
421                          * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
422                          * overrides MNT_WAIT.
423                          */
424                         if (((flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
425                             (flags & MNT_WAIT)) &&
426                             (error = VFS_STATFS(mp, sp, td))) {
427                                 mtx_lock(&mountlist_mtx);
428                                 nmp = TAILQ_NEXT(mp, mnt_list);
429                                 vfs_unbusy(mp, td);
430                                 continue;
431                         }
432                         if (suser(td)) {
433                                 bcopy(sp, &sb, sizeof(sb));
434                                 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
435                                 sp = &sb;
436                         }
437                         if (bufseg == UIO_USERSPACE) {
438                                 error = copyout(sp, sfsp, sizeof(*sp));
439                                 if (error) {
440                                         vfs_unbusy(mp, td);
441                                         mtx_unlock(&Giant);
442                                         return (error);
443                                 }
444                         } else
445                                 bcopy(sp, sfsp, sizeof(*sp));
446                         sfsp++;
447                 }
448                 count++;
449                 mtx_lock(&mountlist_mtx);
450                 nmp = TAILQ_NEXT(mp, mnt_list);
451                 vfs_unbusy(mp, td);
452         }
453         mtx_unlock(&mountlist_mtx);
454         mtx_unlock(&Giant);
455         if (sfsp && count > maxcount)
456                 td->td_retval[0] = maxcount;
457         else
458                 td->td_retval[0] = count;
459         return (0);
460 }
461
462 #ifdef COMPAT_FREEBSD4
463 /*
464  * Get old format filesystem statistics.
465  */
466 static void cvtstatfs(struct statfs *, struct ostatfs *);
467
468 #ifndef _SYS_SYSPROTO_H_
469 struct freebsd4_statfs_args {
470         char *path;
471         struct ostatfs *buf;
472 };
473 #endif
474 int
475 freebsd4_statfs(td, uap)
476         struct thread *td;
477         struct freebsd4_statfs_args /* {
478                 char *path;
479                 struct ostatfs *buf;
480         } */ *uap;
481 {
482         struct ostatfs osb;
483         struct statfs sf;
484         int error;
485
486         error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
487         if (error)
488                 return (error);
489         cvtstatfs(&sf, &osb);
490         return (copyout(&osb, uap->buf, sizeof(osb)));
491 }
492
493 /*
494  * Get filesystem statistics.
495  */
496 #ifndef _SYS_SYSPROTO_H_
497 struct freebsd4_fstatfs_args {
498         int fd;
499         struct ostatfs *buf;
500 };
501 #endif
502 int
503 freebsd4_fstatfs(td, uap)
504         struct thread *td;
505         struct freebsd4_fstatfs_args /* {
506                 int fd;
507                 struct ostatfs *buf;
508         } */ *uap;
509 {
510         struct ostatfs osb;
511         struct statfs sf;
512         int error;
513
514         error = kern_fstatfs(td, uap->fd, &sf);
515         if (error)
516                 return (error);
517         cvtstatfs(&sf, &osb);
518         return (copyout(&osb, uap->buf, sizeof(osb)));
519 }
520
521 /*
522  * Get statistics on all filesystems.
523  */
524 #ifndef _SYS_SYSPROTO_H_
525 struct freebsd4_getfsstat_args {
526         struct ostatfs *buf;
527         long bufsize;
528         int flags;
529 };
530 #endif
531 int
532 freebsd4_getfsstat(td, uap)
533         struct thread *td;
534         register struct freebsd4_getfsstat_args /* {
535                 struct ostatfs *buf;
536                 long bufsize;
537                 int flags;
538         } */ *uap;
539 {
540         struct statfs *buf, *sp;
541         struct ostatfs osb;
542         size_t count, size;
543         int error;
544
545         count = uap->bufsize / sizeof(struct ostatfs);
546         size = count * sizeof(struct statfs);
547         if (size > 0)
548                 buf = malloc(size, M_TEMP, M_WAITOK);
549         else
550                 buf = NULL;
551         error = kern_getfsstat(td, buf, size, UIO_SYSSPACE, uap->flags);
552         if (buf != NULL) {
553                 count = td->td_retval[0];
554                 sp = buf;
555                 while (count > 0 && error == 0) {
556                         cvtstatfs(sp, &osb);
557                         error = copyout(&osb, uap->buf, sizeof(osb));
558                         sp++;
559                         uap->buf++;
560                         count--;
561                 }
562                 free(buf, M_TEMP);
563         }
564         return (error);
565 }
566
567 /*
568  * Implement fstatfs() for (NFS) file handles.
569  */
570 #ifndef _SYS_SYSPROTO_H_
571 struct freebsd4_fhstatfs_args {
572         struct fhandle *u_fhp;
573         struct ostatfs *buf;
574 };
575 #endif
576 int
577 freebsd4_fhstatfs(td, uap)
578         struct thread *td;
579         struct freebsd4_fhstatfs_args /* {
580                 struct fhandle *u_fhp;
581                 struct ostatfs *buf;
582         } */ *uap;
583 {
584         struct ostatfs osb;
585         struct statfs sf;
586         fhandle_t fh;
587         int error;
588
589         error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
590         if (error)
591                 return (error);
592         error = kern_fhstatfs(td, fh, &sf);
593         if (error)
594                 return (error);
595         cvtstatfs(&sf, &osb);
596         return (copyout(&osb, uap->buf, sizeof(osb)));
597 }
598
599 /*
600  * Convert a new format statfs structure to an old format statfs structure.
601  */
602 static void
603 cvtstatfs(nsp, osp)
604         struct statfs *nsp;
605         struct ostatfs *osp;
606 {
607
608         bzero(osp, sizeof(*osp));
609         osp->f_bsize = MIN(nsp->f_bsize, LONG_MAX);
610         osp->f_iosize = MIN(nsp->f_iosize, LONG_MAX);
611         osp->f_blocks = MIN(nsp->f_blocks, LONG_MAX);
612         osp->f_bfree = MIN(nsp->f_bfree, LONG_MAX);
613         osp->f_bavail = MIN(nsp->f_bavail, LONG_MAX);
614         osp->f_files = MIN(nsp->f_files, LONG_MAX);
615         osp->f_ffree = MIN(nsp->f_ffree, LONG_MAX);
616         osp->f_owner = nsp->f_owner;
617         osp->f_type = nsp->f_type;
618         osp->f_flags = nsp->f_flags;
619         osp->f_syncwrites = MIN(nsp->f_syncwrites, LONG_MAX);
620         osp->f_asyncwrites = MIN(nsp->f_asyncwrites, LONG_MAX);
621         osp->f_syncreads = MIN(nsp->f_syncreads, LONG_MAX);
622         osp->f_asyncreads = MIN(nsp->f_asyncreads, LONG_MAX);
623         bcopy(nsp->f_fstypename, osp->f_fstypename,
624             MIN(MFSNAMELEN, OMNAMELEN));
625         bcopy(nsp->f_mntonname, osp->f_mntonname,
626             MIN(MFSNAMELEN, OMNAMELEN));
627         bcopy(nsp->f_mntfromname, osp->f_mntfromname,
628             MIN(MFSNAMELEN, OMNAMELEN));
629         osp->f_fsid = nsp->f_fsid;
630 }
631 #endif /* COMPAT_FREEBSD4 */
632
633 /*
634  * Change current working directory to a given file descriptor.
635  */
636 #ifndef _SYS_SYSPROTO_H_
637 struct fchdir_args {
638         int     fd;
639 };
640 #endif
641 int
642 fchdir(td, uap)
643         struct thread *td;
644         struct fchdir_args /* {
645                 int fd;
646         } */ *uap;
647 {
648         register struct filedesc *fdp = td->td_proc->p_fd;
649         struct vnode *vp, *tdp, *vpold;
650         struct mount *mp;
651         struct file *fp;
652         int vfslocked;
653         int error;
654
655         if ((error = getvnode(fdp, uap->fd, &fp)) != 0)
656                 return (error);
657         vp = fp->f_vnode;
658         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
659         VREF(vp);
660         fdrop(fp, td);
661         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
662         if (vp->v_type != VDIR)
663                 error = ENOTDIR;
664 #ifdef MAC
665         else if ((error = mac_check_vnode_chdir(td->td_ucred, vp)) != 0) {
666         }
667 #endif
668         else
669                 error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td);
670         while (!error && (mp = vp->v_mountedhere) != NULL) {
671                 int tvfslocked;
672                 if (vfs_busy(mp, 0, 0, td))
673                         continue;
674                 tvfslocked = VFS_LOCK_GIANT(mp);
675                 error = VFS_ROOT(mp, LK_EXCLUSIVE, &tdp, td);
676                 vfs_unbusy(mp, td);
677                 if (error) {
678                         VFS_UNLOCK_GIANT(tvfslocked);
679                         break;
680                 }
681                 vput(vp);
682                 VFS_UNLOCK_GIANT(vfslocked);
683                 vp = tdp;
684                 vfslocked = tvfslocked;
685         }
686         if (error) {
687                 vput(vp);
688                 VFS_UNLOCK_GIANT(vfslocked);
689                 return (error);
690         }
691         VOP_UNLOCK(vp, 0, td);
692         FILEDESC_LOCK_FAST(fdp);
693         vpold = fdp->fd_cdir;
694         fdp->fd_cdir = vp;
695         FILEDESC_UNLOCK_FAST(fdp);
696         vrele(vpold);
697         VFS_UNLOCK_GIANT(vfslocked);
698         return (0);
699 }
700
701 /*
702  * Change current working directory (``.'').
703  */
704 #ifndef _SYS_SYSPROTO_H_
705 struct chdir_args {
706         char    *path;
707 };
708 #endif
709 int
710 chdir(td, uap)
711         struct thread *td;
712         struct chdir_args /* {
713                 char *path;
714         } */ *uap;
715 {
716
717         return (kern_chdir(td, uap->path, UIO_USERSPACE));
718 }
719
720 int
721 kern_chdir(struct thread *td, char *path, enum uio_seg pathseg)
722 {
723         register struct filedesc *fdp = td->td_proc->p_fd;
724         int error;
725         struct nameidata nd;
726         struct vnode *vp;
727         int vfslocked;
728
729         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE, pathseg, path, td);
730         if ((error = namei(&nd)) != 0)
731                 return (error);
732         vfslocked = NDHASGIANT(&nd);
733         if ((error = change_dir(nd.ni_vp, td)) != 0) {
734                 vput(nd.ni_vp);
735                 VFS_UNLOCK_GIANT(vfslocked);
736                 NDFREE(&nd, NDF_ONLY_PNBUF);
737                 return (error);
738         }
739         VOP_UNLOCK(nd.ni_vp, 0, td);
740         NDFREE(&nd, NDF_ONLY_PNBUF);
741         FILEDESC_LOCK_FAST(fdp);
742         vp = fdp->fd_cdir;
743         fdp->fd_cdir = nd.ni_vp;
744         FILEDESC_UNLOCK_FAST(fdp);
745         vrele(vp);
746         VFS_UNLOCK_GIANT(vfslocked);
747         return (0);
748 }
749
750 /*
751  * Helper function for raised chroot(2) security function:  Refuse if
752  * any filedescriptors are open directories.
753  */
754 static int
755 chroot_refuse_vdir_fds(fdp)
756         struct filedesc *fdp;
757 {
758         struct vnode *vp;
759         struct file *fp;
760         int fd;
761
762         FILEDESC_LOCK_ASSERT(fdp, MA_OWNED);
763         for (fd = 0; fd < fdp->fd_nfiles ; fd++) {
764                 fp = fget_locked(fdp, fd);
765                 if (fp == NULL)
766                         continue;
767                 if (fp->f_type == DTYPE_VNODE) {
768                         vp = fp->f_vnode;
769                         if (vp->v_type == VDIR)
770                                 return (EPERM);
771                 }
772         }
773         return (0);
774 }
775
776 /*
777  * This sysctl determines if we will allow a process to chroot(2) if it
778  * has a directory open:
779  *      0: disallowed for all processes.
780  *      1: allowed for processes that were not already chroot(2)'ed.
781  *      2: allowed for all processes.
782  */
783
784 static int chroot_allow_open_directories = 1;
785
786 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW,
787      &chroot_allow_open_directories, 0, "");
788
789 /*
790  * Change notion of root (``/'') directory.
791  */
792 #ifndef _SYS_SYSPROTO_H_
793 struct chroot_args {
794         char    *path;
795 };
796 #endif
797 int
798 chroot(td, uap)
799         struct thread *td;
800         struct chroot_args /* {
801                 char *path;
802         } */ *uap;
803 {
804         int error;
805         struct nameidata nd;
806         int vfslocked;
807
808         error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
809         if (error)
810                 return (error);
811         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE,
812             UIO_USERSPACE, uap->path, td);
813         error = namei(&nd);
814         if (error)
815                 goto error;
816         vfslocked = NDHASGIANT(&nd);
817         if ((error = change_dir(nd.ni_vp, td)) != 0)
818                 goto e_vunlock;
819 #ifdef MAC
820         if ((error = mac_check_vnode_chroot(td->td_ucred, nd.ni_vp)))
821                 goto e_vunlock;
822 #endif
823         VOP_UNLOCK(nd.ni_vp, 0, td);
824         error = change_root(nd.ni_vp, td);
825         vrele(nd.ni_vp);
826         VFS_UNLOCK_GIANT(vfslocked);
827         NDFREE(&nd, NDF_ONLY_PNBUF);
828         return (error);
829 e_vunlock:
830         vput(nd.ni_vp);
831         VFS_UNLOCK_GIANT(vfslocked);
832 error:
833         NDFREE(&nd, NDF_ONLY_PNBUF);
834         return (error);
835 }
836
837 /*
838  * Common routine for chroot and chdir.  Callers must provide a locked vnode
839  * instance.
840  */
841 int
842 change_dir(vp, td)
843         struct vnode *vp;
844         struct thread *td;
845 {
846         int error;
847
848         ASSERT_VOP_LOCKED(vp, "change_dir(): vp not locked");
849         if (vp->v_type != VDIR)
850                 return (ENOTDIR);
851 #ifdef MAC
852         error = mac_check_vnode_chdir(td->td_ucred, vp);
853         if (error)
854                 return (error);
855 #endif
856         error = VOP_ACCESS(vp, VEXEC, td->td_ucred, td);
857         return (error);
858 }
859
860 /*
861  * Common routine for kern_chroot() and jail_attach().  The caller is
862  * responsible for invoking suser() and mac_check_chroot() to authorize this
863  * operation.
864  */
865 int
866 change_root(vp, td)
867         struct vnode *vp;
868         struct thread *td;
869 {
870         struct filedesc *fdp;
871         struct vnode *oldvp;
872         int error;
873
874         VFS_ASSERT_GIANT(vp->v_mount);
875         fdp = td->td_proc->p_fd;
876         FILEDESC_LOCK(fdp);
877         if (chroot_allow_open_directories == 0 ||
878             (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) {
879                 error = chroot_refuse_vdir_fds(fdp);
880                 if (error) {
881                         FILEDESC_UNLOCK(fdp);
882                         return (error);
883                 }
884         }
885         oldvp = fdp->fd_rdir;
886         fdp->fd_rdir = vp;
887         VREF(fdp->fd_rdir);
888         if (!fdp->fd_jdir) {
889                 fdp->fd_jdir = vp;
890                 VREF(fdp->fd_jdir);
891         }
892         FILEDESC_UNLOCK(fdp);
893         vrele(oldvp);
894         return (0);
895 }
896
897 /*
898  * Check permissions, allocate an open file structure,
899  * and call the device open routine if any.
900  *
901  * MP SAFE
902  */
903 #ifndef _SYS_SYSPROTO_H_
904 struct open_args {
905         char    *path;
906         int     flags;
907         int     mode;
908 };
909 #endif
910 int
911 open(td, uap)
912         struct thread *td;
913         register struct open_args /* {
914                 char *path;
915                 int flags;
916                 int mode;
917         } */ *uap;
918 {
919         int error;
920
921         error = kern_open(td, uap->path, UIO_USERSPACE, uap->flags, uap->mode);
922         if (mtx_owned(&Giant))
923                 printf("open: %s: %d\n", uap->path, error);
924         return (error);
925 }
926
927 int
928 kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags,
929     int mode)
930 {
931         struct proc *p = td->td_proc;
932         struct filedesc *fdp = p->p_fd;
933         struct file *fp;
934         struct vnode *vp;
935         struct vattr vat;
936         struct mount *mp;
937         int cmode;
938         struct file *nfp;
939         int type, indx, error;
940         struct flock lf;
941         struct nameidata nd;
942         int vfslocked;
943
944         if ((flags & O_ACCMODE) == O_ACCMODE)
945                 return (EINVAL);
946         flags = FFLAGS(flags);
947         error = falloc(td, &nfp, &indx);
948         if (error)
949                 return (error);
950         /* An extra reference on `nfp' has been held for us by falloc(). */
951         fp = nfp;
952         cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
953         NDINIT(&nd, LOOKUP, FOLLOW, pathseg, path, td);
954         td->td_dupfd = -1;              /* XXX check for fdopen */
955         error = vn_open(&nd, &flags, cmode, indx);
956         if (error) {
957                 /*
958                  * If the vn_open replaced the method vector, something
959                  * wonderous happened deep below and we just pass it up
960                  * pretending we know what we do.
961                  */
962                 if (error == ENXIO && fp->f_ops != &badfileops) {
963                         fdrop(fp, td);
964                         td->td_retval[0] = indx;
965                         return (0);
966                 }
967
968                 /*
969                  * release our own reference
970                  */
971                 fdrop(fp, td);
972
973                 /*
974                  * handle special fdopen() case.  bleh.  dupfdopen() is
975                  * responsible for dropping the old contents of ofiles[indx]
976                  * if it succeeds.
977                  */
978                 if ((error == ENODEV || error == ENXIO) &&
979                     td->td_dupfd >= 0 &&                /* XXX from fdopen */
980                     (error =
981                         dupfdopen(td, fdp, indx, td->td_dupfd, flags, error)) == 0) {
982                         td->td_retval[0] = indx;
983                         return (0);
984                 }
985                 /*
986                  * Clean up the descriptor, but only if another thread hadn't
987                  * replaced or closed it.
988                  */
989                 fdclose(fdp, fp, indx, td);
990
991                 if (error == ERESTART)
992                         error = EINTR;
993                 return (error);
994         }
995         td->td_dupfd = 0;
996         vfslocked = NDHASGIANT(&nd);
997         NDFREE(&nd, NDF_ONLY_PNBUF);
998         vp = nd.ni_vp;
999
1000         /*
1001          * There should be 2 references on the file, one from the descriptor
1002          * table, and one for us.
1003          *
1004          * Handle the case where someone closed the file (via its file
1005          * descriptor) while we were blocked.  The end result should look
1006          * like opening the file succeeded but it was immediately closed.
1007          * We call vn_close() manually because we haven't yet hooked up
1008          * the various 'struct file' fields.
1009          */
1010         FILEDESC_LOCK(fdp);
1011         FILE_LOCK(fp);
1012         if (fp->f_count == 1) {
1013                 mp = vp->v_mount;
1014                 KASSERT(fdp->fd_ofiles[indx] != fp,
1015                     ("Open file descriptor lost all refs"));
1016                 FILE_UNLOCK(fp);
1017                 FILEDESC_UNLOCK(fdp);
1018                 VOP_UNLOCK(vp, 0, td);
1019                 vn_close(vp, flags & FMASK, fp->f_cred, td);
1020                 VFS_UNLOCK_GIANT(vfslocked);
1021                 fdrop(fp, td);
1022                 td->td_retval[0] = indx;
1023                 return (0);
1024         }
1025         fp->f_vnode = vp;
1026         if (fp->f_data == NULL)
1027                 fp->f_data = vp;
1028         fp->f_flag = flags & FMASK;
1029         if (fp->f_ops == &badfileops)
1030                 fp->f_ops = &vnops;
1031         fp->f_seqcount = 1;
1032         fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE);
1033         FILE_UNLOCK(fp);
1034         FILEDESC_UNLOCK(fdp);
1035
1036         VOP_UNLOCK(vp, 0, td);
1037         if (flags & (O_EXLOCK | O_SHLOCK)) {
1038                 lf.l_whence = SEEK_SET;
1039                 lf.l_start = 0;
1040                 lf.l_len = 0;
1041                 if (flags & O_EXLOCK)
1042                         lf.l_type = F_WRLCK;
1043                 else
1044                         lf.l_type = F_RDLCK;
1045                 type = F_FLOCK;
1046                 if ((flags & FNONBLOCK) == 0)
1047                         type |= F_WAIT;
1048                 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf,
1049                             type)) != 0)
1050                         goto bad;
1051                 fp->f_flag |= FHASLOCK;
1052         }
1053         if (flags & O_TRUNC) {
1054                 if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
1055                         goto bad;
1056                 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
1057                 VATTR_NULL(&vat);
1058                 vat.va_size = 0;
1059                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1060 #ifdef MAC
1061                 error = mac_check_vnode_write(td->td_ucred, fp->f_cred, vp);
1062                 if (error == 0)
1063 #endif
1064                         error = VOP_SETATTR(vp, &vat, td->td_ucred, td);
1065                 VOP_UNLOCK(vp, 0, td);
1066                 vn_finished_write(mp);
1067                 if (error)
1068                         goto bad;
1069         }
1070         VFS_UNLOCK_GIANT(vfslocked);
1071         /*
1072          * Release our private reference, leaving the one associated with
1073          * the descriptor table intact.
1074          */
1075         fdrop(fp, td);
1076         td->td_retval[0] = indx;
1077         return (0);
1078 bad:
1079         VFS_UNLOCK_GIANT(vfslocked);
1080         fdclose(fdp, fp, indx, td);
1081         fdrop(fp, td);
1082         return (error);
1083 }
1084
1085 #ifdef COMPAT_43
1086 /*
1087  * Create a file.
1088  *
1089  * MP SAFE
1090  */
1091 #ifndef _SYS_SYSPROTO_H_
1092 struct ocreat_args {
1093         char    *path;
1094         int     mode;
1095 };
1096 #endif
1097 int
1098 ocreat(td, uap)
1099         struct thread *td;
1100         register struct ocreat_args /* {
1101                 char *path;
1102                 int mode;
1103         } */ *uap;
1104 {
1105
1106         return (kern_open(td, uap->path, UIO_USERSPACE,
1107             O_WRONLY | O_CREAT | O_TRUNC, uap->mode));
1108 }
1109 #endif /* COMPAT_43 */
1110
1111 /*
1112  * Create a special file.
1113  */
1114 #ifndef _SYS_SYSPROTO_H_
1115 struct mknod_args {
1116         char    *path;
1117         int     mode;
1118         int     dev;
1119 };
1120 #endif
1121 int
1122 mknod(td, uap)
1123         struct thread *td;
1124         register struct mknod_args /* {
1125                 char *path;
1126                 int mode;
1127                 int dev;
1128         } */ *uap;
1129 {
1130
1131         return (kern_mknod(td, uap->path, UIO_USERSPACE, uap->mode, uap->dev));
1132 }
1133
1134 int
1135 kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode,
1136     int dev)
1137 {
1138         struct vnode *vp;
1139         struct mount *mp;
1140         struct vattr vattr;
1141         int error;
1142         int whiteout = 0;
1143         struct nameidata nd;
1144         int vfslocked;
1145
1146         switch (mode & S_IFMT) {
1147         case S_IFCHR:
1148         case S_IFBLK:
1149                 error = suser(td);
1150                 break;
1151         default:
1152                 error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
1153                 break;
1154         }
1155         if (error)
1156                 return (error);
1157 restart:
1158         bwillwrite();
1159         NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE, pathseg, path, td);
1160         if ((error = namei(&nd)) != 0)
1161                 return (error);
1162         vfslocked = NDHASGIANT(&nd);
1163         vp = nd.ni_vp;
1164         if (vp != NULL) {
1165                 NDFREE(&nd, NDF_ONLY_PNBUF);
1166                 vrele(vp);
1167                 if (vp == nd.ni_dvp)
1168                         vrele(nd.ni_dvp);
1169                 else
1170                         vput(nd.ni_dvp);
1171                 VFS_UNLOCK_GIANT(vfslocked);
1172                 return (EEXIST);
1173         } else {
1174                 VATTR_NULL(&vattr);
1175                 FILEDESC_LOCK_FAST(td->td_proc->p_fd);
1176                 vattr.va_mode = (mode & ALLPERMS) &
1177                     ~td->td_proc->p_fd->fd_cmask;
1178                 FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
1179                 vattr.va_rdev = dev;
1180                 whiteout = 0;
1181
1182                 switch (mode & S_IFMT) {
1183                 case S_IFMT:    /* used by badsect to flag bad sectors */
1184                         vattr.va_type = VBAD;
1185                         break;
1186                 case S_IFCHR:
1187                         vattr.va_type = VCHR;
1188                         break;
1189                 case S_IFBLK:
1190                         vattr.va_type = VBLK;
1191                         break;
1192                 case S_IFWHT:
1193                         whiteout = 1;
1194                         break;
1195                 default:
1196                         error = EINVAL;
1197                         break;
1198                 }
1199         }
1200         if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1201                 NDFREE(&nd, NDF_ONLY_PNBUF);
1202                 vput(nd.ni_dvp);
1203                 VFS_UNLOCK_GIANT(vfslocked);
1204                 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1205                         return (error);
1206                 goto restart;
1207         }
1208 #ifdef MAC
1209         if (error == 0 && !whiteout)
1210                 error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp,
1211                     &nd.ni_cnd, &vattr);
1212 #endif
1213         if (!error) {
1214                 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1215                 if (whiteout)
1216                         error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE);
1217                 else {
1218                         error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp,
1219                                                 &nd.ni_cnd, &vattr);
1220                         if (error == 0)
1221                                 vput(nd.ni_vp);
1222                 }
1223         }
1224         NDFREE(&nd, NDF_ONLY_PNBUF);
1225         vput(nd.ni_dvp);
1226         vn_finished_write(mp);
1227         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod");
1228         ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod");
1229         VFS_UNLOCK_GIANT(vfslocked);
1230         return (error);
1231 }
1232
1233 /*
1234  * Create a named pipe.
1235  */
1236 #ifndef _SYS_SYSPROTO_H_
1237 struct mkfifo_args {
1238         char    *path;
1239         int     mode;
1240 };
1241 #endif
1242 int
1243 mkfifo(td, uap)
1244         struct thread *td;
1245         register struct mkfifo_args /* {
1246                 char *path;
1247                 int mode;
1248         } */ *uap;
1249 {
1250
1251         return (kern_mkfifo(td, uap->path, UIO_USERSPACE, uap->mode));
1252 }
1253
1254 int
1255 kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode)
1256 {
1257         struct mount *mp;
1258         struct vattr vattr;
1259         int error;
1260         struct nameidata nd;
1261         int vfslocked;
1262
1263 restart:
1264         bwillwrite();
1265         NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE, pathseg, path, td);
1266         if ((error = namei(&nd)) != 0)
1267                 return (error);
1268         vfslocked = NDHASGIANT(&nd);
1269         if (nd.ni_vp != NULL) {
1270                 NDFREE(&nd, NDF_ONLY_PNBUF);
1271                 vrele(nd.ni_vp);
1272                 if (nd.ni_vp == nd.ni_dvp)
1273                         vrele(nd.ni_dvp);
1274                 else
1275                         vput(nd.ni_dvp);
1276                 VFS_UNLOCK_GIANT(vfslocked);
1277                 return (EEXIST);
1278         }
1279         if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1280                 NDFREE(&nd, NDF_ONLY_PNBUF);
1281                 vput(nd.ni_dvp);
1282                 VFS_UNLOCK_GIANT(vfslocked);
1283                 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1284                         return (error);
1285                 goto restart;
1286         }
1287         VATTR_NULL(&vattr);
1288         vattr.va_type = VFIFO;
1289         FILEDESC_LOCK_FAST(td->td_proc->p_fd);
1290         vattr.va_mode = (mode & ALLPERMS) & ~td->td_proc->p_fd->fd_cmask;
1291         FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
1292 #ifdef MAC
1293         error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
1294             &vattr);
1295         if (error)
1296                 goto out;
1297 #endif
1298         VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1299         error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
1300         if (error == 0)
1301                 vput(nd.ni_vp);
1302 #ifdef MAC
1303 out:
1304 #endif
1305         vput(nd.ni_dvp);
1306         vn_finished_write(mp);
1307         VFS_UNLOCK_GIANT(vfslocked);
1308         NDFREE(&nd, NDF_ONLY_PNBUF);
1309         return (error);
1310 }
1311
1312 /*
1313  * Make a hard file link.
1314  */
1315 #ifndef _SYS_SYSPROTO_H_
1316 struct link_args {
1317         char    *path;
1318         char    *link;
1319 };
1320 #endif
1321 int
1322 link(td, uap)
1323         struct thread *td;
1324         register struct link_args /* {
1325                 char *path;
1326                 char *link;
1327         } */ *uap;
1328 {
1329         int error;
1330
1331         error = kern_link(td, uap->path, uap->link, UIO_USERSPACE);
1332         return (error);
1333 }
1334
1335 SYSCTL_DECL(_security_bsd);
1336
1337 static int hardlink_check_uid = 0;
1338 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_uid, CTLFLAG_RW,
1339     &hardlink_check_uid, 0,
1340     "Unprivileged processes cannot create hard links to files owned by other "
1341     "users");
1342 static int hardlink_check_gid = 0;
1343 SYSCTL_INT(_security_bsd, OID_AUTO, hardlink_check_gid, CTLFLAG_RW,
1344     &hardlink_check_gid, 0,
1345     "Unprivileged processes cannot create hard links to files owned by other "
1346     "groups");
1347
1348 static int
1349 can_hardlink(struct vnode *vp, struct thread *td, struct ucred *cred)
1350 {
1351         struct vattr va;
1352         int error;
1353
1354         if (suser_cred(cred, SUSER_ALLOWJAIL) == 0)
1355                 return (0);
1356
1357         if (!hardlink_check_uid && !hardlink_check_gid)
1358                 return (0);
1359
1360         error = VOP_GETATTR(vp, &va, cred, td);
1361         if (error != 0)
1362                 return (error);
1363
1364         if (hardlink_check_uid) {
1365                 if (cred->cr_uid != va.va_uid)
1366                         return (EPERM);
1367         }
1368
1369         if (hardlink_check_gid) {
1370                 if (!groupmember(va.va_gid, cred))
1371                         return (EPERM);
1372         }
1373
1374         return (0);
1375 }
1376
1377 int
1378 kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg)
1379 {
1380         struct vnode *vp;
1381         struct mount *mp;
1382         struct nameidata nd;
1383         int vfslocked;
1384         int lvfslocked;
1385         int error;
1386
1387         bwillwrite();
1388         NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, segflg, path, td);
1389         if ((error = namei(&nd)) != 0)
1390                 return (error);
1391         vfslocked = NDHASGIANT(&nd);
1392         NDFREE(&nd, NDF_ONLY_PNBUF);
1393         vp = nd.ni_vp;
1394         if (vp->v_type == VDIR) {
1395                 vrele(vp);
1396                 VFS_UNLOCK_GIANT(vfslocked);
1397                 return (EPERM);         /* POSIX */
1398         }
1399         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
1400                 vrele(vp);
1401                 VFS_UNLOCK_GIANT(vfslocked);
1402                 return (error);
1403         }
1404         NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME, segflg, link, td);
1405         if ((error = namei(&nd)) == 0) {
1406                 lvfslocked = NDHASGIANT(&nd);
1407                 if (nd.ni_vp != NULL) {
1408                         vrele(nd.ni_vp);
1409                         if (nd.ni_dvp == nd.ni_vp)
1410                                 vrele(nd.ni_dvp);
1411                         else
1412                                 vput(nd.ni_dvp);
1413                         error = EEXIST;
1414                 } else if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td))
1415                     == 0) {
1416                         VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1417                         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
1418                         error = can_hardlink(vp, td, td->td_ucred);
1419                         if (error == 0)
1420 #ifdef MAC
1421                                 error = mac_check_vnode_link(td->td_ucred,
1422                                     nd.ni_dvp, vp, &nd.ni_cnd);
1423                         if (error == 0)
1424 #endif
1425                                 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
1426                         VOP_UNLOCK(vp, 0, td);
1427                         vput(nd.ni_dvp);
1428                 }
1429                 NDFREE(&nd, NDF_ONLY_PNBUF);
1430                 VFS_UNLOCK_GIANT(lvfslocked);
1431         }
1432         vrele(vp);
1433         vn_finished_write(mp);
1434         VFS_UNLOCK_GIANT(vfslocked);
1435         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link");
1436         ASSERT_VOP_UNLOCKED(nd.ni_vp, "link");
1437         return (error);
1438 }
1439
1440 /*
1441  * Make a symbolic link.
1442  */
1443 #ifndef _SYS_SYSPROTO_H_
1444 struct symlink_args {
1445         char    *path;
1446         char    *link;
1447 };
1448 #endif
1449 int
1450 symlink(td, uap)
1451         struct thread *td;
1452         register struct symlink_args /* {
1453                 char *path;
1454                 char *link;
1455         } */ *uap;
1456 {
1457
1458         return (kern_symlink(td, uap->path, uap->link, UIO_USERSPACE));
1459 }
1460
1461 int
1462 kern_symlink(struct thread *td, char *path, char *link, enum uio_seg segflg)
1463 {
1464         struct mount *mp;
1465         struct vattr vattr;
1466         char *syspath;
1467         int error;
1468         struct nameidata nd;
1469         int vfslocked;
1470
1471         if (segflg == UIO_SYSSPACE) {
1472                 syspath = path;
1473         } else {
1474                 syspath = uma_zalloc(namei_zone, M_WAITOK);
1475                 if ((error = copyinstr(path, syspath, MAXPATHLEN, NULL)) != 0)
1476                         goto out;
1477         }
1478 restart:
1479         bwillwrite();
1480         NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE,
1481             segflg, link, td);
1482         if ((error = namei(&nd)) != 0)
1483                 goto out;
1484         vfslocked = NDHASGIANT(&nd);
1485         if (nd.ni_vp) {
1486                 NDFREE(&nd, NDF_ONLY_PNBUF);
1487                 vrele(nd.ni_vp);
1488                 if (nd.ni_vp == nd.ni_dvp)
1489                         vrele(nd.ni_dvp);
1490                 else
1491                         vput(nd.ni_dvp);
1492                 VFS_UNLOCK_GIANT(vfslocked);
1493                 error = EEXIST;
1494                 goto out;
1495         }
1496         if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1497                 NDFREE(&nd, NDF_ONLY_PNBUF);
1498                 vput(nd.ni_dvp);
1499                 VFS_UNLOCK_GIANT(vfslocked);
1500                 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1501                         goto out;
1502                 goto restart;
1503         }
1504         VATTR_NULL(&vattr);
1505         FILEDESC_LOCK_FAST(td->td_proc->p_fd);
1506         vattr.va_mode = ACCESSPERMS &~ td->td_proc->p_fd->fd_cmask;
1507         FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
1508 #ifdef MAC
1509         vattr.va_type = VLNK;
1510         error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
1511             &vattr);
1512         if (error)
1513                 goto out2;
1514 #endif
1515         VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1516         error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, syspath);
1517         if (error == 0)
1518                 vput(nd.ni_vp);
1519 #ifdef MAC
1520 out2:
1521 #endif
1522         NDFREE(&nd, NDF_ONLY_PNBUF);
1523         vput(nd.ni_dvp);
1524         vn_finished_write(mp);
1525         VFS_UNLOCK_GIANT(vfslocked);
1526         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink");
1527         ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink");
1528 out:
1529         if (segflg != UIO_SYSSPACE)
1530                 uma_zfree(namei_zone, syspath);
1531         return (error);
1532 }
1533
1534 /*
1535  * Delete a whiteout from the filesystem.
1536  */
1537 int
1538 undelete(td, uap)
1539         struct thread *td;
1540         register struct undelete_args /* {
1541                 char *path;
1542         } */ *uap;
1543 {
1544         int error;
1545         struct mount *mp;
1546         struct nameidata nd;
1547         int vfslocked;
1548
1549 restart:
1550         bwillwrite();
1551         NDINIT(&nd, DELETE, LOCKPARENT | DOWHITEOUT | MPSAFE, UIO_USERSPACE,
1552             uap->path, td);
1553         error = namei(&nd);
1554         if (error)
1555                 return (error);
1556         vfslocked = NDHASGIANT(&nd);
1557
1558         if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) {
1559                 NDFREE(&nd, NDF_ONLY_PNBUF);
1560                 if (nd.ni_vp)
1561                         vrele(nd.ni_vp);
1562                 if (nd.ni_vp == nd.ni_dvp)
1563                         vrele(nd.ni_dvp);
1564                 else
1565                         vput(nd.ni_dvp);
1566                 VFS_UNLOCK_GIANT(vfslocked);
1567                 return (EEXIST);
1568         }
1569         if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1570                 NDFREE(&nd, NDF_ONLY_PNBUF);
1571                 vput(nd.ni_dvp);
1572                 VFS_UNLOCK_GIANT(vfslocked);
1573                 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
1574                         return (error);
1575                 goto restart;
1576         }
1577         VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1578         error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE);
1579         NDFREE(&nd, NDF_ONLY_PNBUF);
1580         vput(nd.ni_dvp);
1581         vn_finished_write(mp);
1582         VFS_UNLOCK_GIANT(vfslocked);
1583         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "undelete");
1584         ASSERT_VOP_UNLOCKED(nd.ni_vp, "undelete");
1585         return (error);
1586 }
1587
1588 /*
1589  * Delete a name from the filesystem.
1590  */
1591 #ifndef _SYS_SYSPROTO_H_
1592 struct unlink_args {
1593         char    *path;
1594 };
1595 #endif
1596 int
1597 unlink(td, uap)
1598         struct thread *td;
1599         struct unlink_args /* {
1600                 char *path;
1601         } */ *uap;
1602 {
1603         int error;
1604
1605         error = kern_unlink(td, uap->path, UIO_USERSPACE);
1606         return (error);
1607 }
1608
1609 int
1610 kern_unlink(struct thread *td, char *path, enum uio_seg pathseg)
1611 {
1612         struct mount *mp;
1613         struct vnode *vp;
1614         int error;
1615         struct nameidata nd;
1616         int vfslocked;
1617
1618 restart:
1619         bwillwrite();
1620         NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE, pathseg, path, td);
1621         if ((error = namei(&nd)) != 0)
1622                 return (error);
1623         vfslocked = NDHASGIANT(&nd);
1624         vp = nd.ni_vp;
1625         if (vp->v_type == VDIR)
1626                 error = EPERM;          /* POSIX */
1627         else {
1628                 /*
1629                  * The root of a mounted filesystem cannot be deleted.
1630                  *
1631                  * XXX: can this only be a VDIR case?
1632                  */
1633                 if (vp->v_vflag & VV_ROOT)
1634                         error = EBUSY;
1635         }
1636         if (error == 0) {
1637                 if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
1638                         NDFREE(&nd, NDF_ONLY_PNBUF);
1639                         if (vp == nd.ni_dvp)
1640                                 vrele(vp);
1641                         else
1642                                 vput(vp);
1643                         vput(nd.ni_dvp);
1644                         VFS_UNLOCK_GIANT(vfslocked);
1645                         if ((error = vn_start_write(NULL, &mp,
1646                             V_XSLEEP | PCATCH)) != 0)
1647                                 return (error);
1648                         goto restart;
1649                 }
1650 #ifdef MAC
1651                 error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp,
1652                     &nd.ni_cnd);
1653                 if (error)
1654                         goto out;
1655 #endif
1656                 VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
1657                 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd);
1658 #ifdef MAC
1659 out:
1660 #endif
1661                 vn_finished_write(mp);
1662         }
1663         NDFREE(&nd, NDF_ONLY_PNBUF);
1664         if (vp == nd.ni_dvp)
1665                 vrele(vp);
1666         else
1667                 vput(vp);
1668         vput(nd.ni_dvp);
1669         VFS_UNLOCK_GIANT(vfslocked);
1670         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink");
1671         ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink");
1672         return (error);
1673 }
1674
1675 /*
1676  * Reposition read/write file offset.
1677  */
1678 #ifndef _SYS_SYSPROTO_H_
1679 struct lseek_args {
1680         int     fd;
1681         int     pad;
1682         off_t   offset;
1683         int     whence;
1684 };
1685 #endif
1686 int
1687 lseek(td, uap)
1688         struct thread *td;
1689         register struct lseek_args /* {
1690                 int fd;
1691                 int pad;
1692                 off_t offset;
1693                 int whence;
1694         } */ *uap;
1695 {
1696         struct ucred *cred = td->td_ucred;
1697         struct file *fp;
1698         struct vnode *vp;
1699         struct vattr vattr;
1700         off_t offset;
1701         int error, noneg;
1702         int vfslocked;
1703
1704         if ((error = fget(td, uap->fd, &fp)) != 0)
1705                 return (error);
1706         if (!(fp->f_ops->fo_flags & DFLAG_SEEKABLE)) {
1707                 fdrop(fp, td);
1708                 return (ESPIPE);
1709         }
1710         vp = fp->f_vnode;
1711         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1712         noneg = (vp->v_type != VCHR);
1713         offset = uap->offset;
1714         switch (uap->whence) {
1715         case L_INCR:
1716                 if (noneg &&
1717                     (fp->f_offset < 0 ||
1718                     (offset > 0 && fp->f_offset > OFF_MAX - offset))) {
1719                         error = EOVERFLOW;
1720                         break;
1721                 }
1722                 offset += fp->f_offset;
1723                 break;
1724         case L_XTND:
1725                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1726                 error = VOP_GETATTR(vp, &vattr, cred, td);
1727                 VOP_UNLOCK(vp, 0, td);
1728                 if (error)
1729                         break;
1730                 if (noneg &&
1731                     (vattr.va_size > OFF_MAX ||
1732                     (offset > 0 && vattr.va_size > OFF_MAX - offset))) {
1733                         error = EOVERFLOW;
1734                         break;
1735                 }
1736                 offset += vattr.va_size;
1737                 break;
1738         case L_SET:
1739                 break;
1740         default:
1741                 error = EINVAL;
1742         }
1743         if (error == 0 && noneg && offset < 0)
1744                 error = EINVAL;
1745         if (error != 0)
1746                 goto drop;
1747         fp->f_offset = offset;
1748         *(off_t *)(td->td_retval) = fp->f_offset;
1749 drop:
1750         fdrop(fp, td);
1751         VFS_UNLOCK_GIANT(vfslocked);
1752         return (error);
1753 }
1754
1755 #if defined(COMPAT_43)
1756 /*
1757  * Reposition read/write file offset.
1758  */
1759 #ifndef _SYS_SYSPROTO_H_
1760 struct olseek_args {
1761         int     fd;
1762         long    offset;
1763         int     whence;
1764 };
1765 #endif
1766 int
1767 olseek(td, uap)
1768         struct thread *td;
1769         register struct olseek_args /* {
1770                 int fd;
1771                 long offset;
1772                 int whence;
1773         } */ *uap;
1774 {
1775         struct lseek_args /* {
1776                 int fd;
1777                 int pad;
1778                 off_t offset;
1779                 int whence;
1780         } */ nuap;
1781         int error;
1782
1783         nuap.fd = uap->fd;
1784         nuap.offset = uap->offset;
1785         nuap.whence = uap->whence;
1786         error = lseek(td, &nuap);
1787         return (error);
1788 }
1789 #endif /* COMPAT_43 */
1790
1791 /*
1792  * Check access permissions using passed credentials.
1793  */
1794 static int
1795 vn_access(vp, user_flags, cred, td)
1796         struct vnode    *vp;
1797         int             user_flags;
1798         struct ucred    *cred;
1799         struct thread   *td;
1800 {
1801         int error, flags;
1802
1803         /* Flags == 0 means only check for existence. */
1804         error = 0;
1805         if (user_flags) {
1806                 flags = 0;
1807                 if (user_flags & R_OK)
1808                         flags |= VREAD;
1809                 if (user_flags & W_OK)
1810                         flags |= VWRITE;
1811                 if (user_flags & X_OK)
1812                         flags |= VEXEC;
1813 #ifdef MAC
1814                 error = mac_check_vnode_access(cred, vp, flags);
1815                 if (error)
1816                         return (error);
1817 #endif
1818                 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
1819                         error = VOP_ACCESS(vp, flags, cred, td);
1820         }
1821         return (error);
1822 }
1823
1824 /*
1825  * Check access permissions using "real" credentials.
1826  */
1827 #ifndef _SYS_SYSPROTO_H_
1828 struct access_args {
1829         char    *path;
1830         int     flags;
1831 };
1832 #endif
1833 int
1834 access(td, uap)
1835         struct thread *td;
1836         register struct access_args /* {
1837                 char *path;
1838                 int flags;
1839         } */ *uap;
1840 {
1841
1842         return (kern_access(td, uap->path, UIO_USERSPACE, uap->flags));
1843 }
1844
1845 int
1846 kern_access(struct thread *td, char *path, enum uio_seg pathseg, int flags)
1847 {
1848         struct ucred *cred, *tmpcred;
1849         register struct vnode *vp;
1850         struct nameidata nd;
1851         int vfslocked;
1852         int error;
1853
1854         /*
1855          * Create and modify a temporary credential instead of one that
1856          * is potentially shared.  This could also mess up socket
1857          * buffer accounting which can run in an interrupt context.
1858          */
1859         cred = td->td_ucred;
1860         tmpcred = crdup(cred);
1861         tmpcred->cr_uid = cred->cr_ruid;
1862         tmpcred->cr_groups[0] = cred->cr_rgid;
1863         td->td_ucred = tmpcred;
1864         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE, pathseg, path, td);
1865         if ((error = namei(&nd)) != 0)
1866                 goto out1;
1867         vfslocked = NDHASGIANT(&nd);
1868         vp = nd.ni_vp;
1869
1870         error = vn_access(vp, flags, tmpcred, td);
1871         NDFREE(&nd, NDF_ONLY_PNBUF);
1872         vput(vp);
1873         VFS_UNLOCK_GIANT(vfslocked);
1874 out1:
1875         td->td_ucred = cred;
1876         crfree(tmpcred);
1877         return (error);
1878 }
1879
1880 /*
1881  * Check access permissions using "effective" credentials.
1882  */
1883 #ifndef _SYS_SYSPROTO_H_
1884 struct eaccess_args {
1885         char    *path;
1886         int     flags;
1887 };
1888 #endif
1889 int
1890 eaccess(td, uap)
1891         struct thread *td;
1892         register struct eaccess_args /* {
1893                 char *path;
1894                 int flags;
1895         } */ *uap;
1896 {
1897         struct nameidata nd;
1898         struct vnode *vp;
1899         int vfslocked;
1900         int error;
1901
1902         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE, UIO_USERSPACE,
1903             uap->path, td);
1904         if ((error = namei(&nd)) != 0)
1905                 return (error);
1906         vp = nd.ni_vp;
1907         vfslocked = NDHASGIANT(&nd);
1908         error = vn_access(vp, uap->flags, td->td_ucred, td);
1909         NDFREE(&nd, NDF_ONLY_PNBUF);
1910         vput(vp);
1911         VFS_UNLOCK_GIANT(vfslocked);
1912         return (error);
1913 }
1914
1915 #if defined(COMPAT_43)
1916 /*
1917  * Get file status; this version follows links.
1918  */
1919 #ifndef _SYS_SYSPROTO_H_
1920 struct ostat_args {
1921         char    *path;
1922         struct ostat *ub;
1923 };
1924 #endif
1925 int
1926 ostat(td, uap)
1927         struct thread *td;
1928         register struct ostat_args /* {
1929                 char *path;
1930                 struct ostat *ub;
1931         } */ *uap;
1932 {
1933         struct stat sb;
1934         struct ostat osb;
1935         int error;
1936
1937         error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
1938         if (error)
1939                 return (error);
1940         cvtstat(&sb, &osb);
1941         error = copyout(&osb, uap->ub, sizeof (osb));
1942         return (error);
1943 }
1944
1945 /*
1946  * Get file status; this version does not follow links.
1947  */
1948 #ifndef _SYS_SYSPROTO_H_
1949 struct olstat_args {
1950         char    *path;
1951         struct ostat *ub;
1952 };
1953 #endif
1954 int
1955 olstat(td, uap)
1956         struct thread *td;
1957         register struct olstat_args /* {
1958                 char *path;
1959                 struct ostat *ub;
1960         } */ *uap;
1961 {
1962         struct stat sb;
1963         struct ostat osb;
1964         int error;
1965
1966         error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
1967         if (error)
1968                 return (error);
1969         cvtstat(&sb, &osb);
1970         error = copyout(&osb, uap->ub, sizeof (osb));
1971         return (error);
1972 }
1973
1974 /*
1975  * Convert from an old to a new stat structure.
1976  */
1977 void
1978 cvtstat(st, ost)
1979         struct stat *st;
1980         struct ostat *ost;
1981 {
1982
1983         ost->st_dev = st->st_dev;
1984         ost->st_ino = st->st_ino;
1985         ost->st_mode = st->st_mode;
1986         ost->st_nlink = st->st_nlink;
1987         ost->st_uid = st->st_uid;
1988         ost->st_gid = st->st_gid;
1989         ost->st_rdev = st->st_rdev;
1990         if (st->st_size < (quad_t)1 << 32)
1991                 ost->st_size = st->st_size;
1992         else
1993                 ost->st_size = -2;
1994         ost->st_atime = st->st_atime;
1995         ost->st_mtime = st->st_mtime;
1996         ost->st_ctime = st->st_ctime;
1997         ost->st_blksize = st->st_blksize;
1998         ost->st_blocks = st->st_blocks;
1999         ost->st_flags = st->st_flags;
2000         ost->st_gen = st->st_gen;
2001 }
2002 #endif /* COMPAT_43 */
2003
2004 /*
2005  * Get file status; this version follows links.
2006  */
2007 #ifndef _SYS_SYSPROTO_H_
2008 struct stat_args {
2009         char    *path;
2010         struct stat *ub;
2011 };
2012 #endif
2013 int
2014 stat(td, uap)
2015         struct thread *td;
2016         register struct stat_args /* {
2017                 char *path;
2018                 struct stat *ub;
2019         } */ *uap;
2020 {
2021         struct stat sb;
2022         int error;
2023
2024         error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
2025         if (error == 0)
2026                 error = copyout(&sb, uap->ub, sizeof (sb));
2027         return (error);
2028 }
2029
2030 int
2031 kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
2032 {
2033         struct nameidata nd;
2034         struct stat sb;
2035         int error, vfslocked;
2036
2037         NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE,
2038             pathseg, path, td);
2039         if ((error = namei(&nd)) != 0)
2040                 return (error);
2041         vfslocked = NDHASGIANT(&nd);
2042         error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td);
2043         NDFREE(&nd, NDF_ONLY_PNBUF);
2044         vput(nd.ni_vp);
2045         VFS_UNLOCK_GIANT(vfslocked);
2046         if (error)
2047                 return (error);
2048         *sbp = sb;
2049         return (0);
2050 }
2051
2052 /*
2053  * Get file status; this version does not follow links.
2054  */
2055 #ifndef _SYS_SYSPROTO_H_
2056 struct lstat_args {
2057         char    *path;
2058         struct stat *ub;
2059 };
2060 #endif
2061 int
2062 lstat(td, uap)
2063         struct thread *td;
2064         register struct lstat_args /* {
2065                 char *path;
2066                 struct stat *ub;
2067         } */ *uap;
2068 {
2069         struct stat sb;
2070         int error;
2071
2072         error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
2073         if (error == 0)
2074                 error = copyout(&sb, uap->ub, sizeof (sb));
2075         return (error);
2076 }
2077
2078 int
2079 kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
2080 {
2081         struct vnode *vp;
2082         struct stat sb;
2083         struct nameidata nd;
2084         int error, vfslocked;
2085
2086         NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKSHARED | MPSAFE,
2087             pathseg, path, td);
2088         if ((error = namei(&nd)) != 0)
2089                 return (error);
2090         vfslocked = NDHASGIANT(&nd);
2091         vp = nd.ni_vp;
2092         error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
2093         NDFREE(&nd, NDF_ONLY_PNBUF);
2094         vput(vp);
2095         VFS_UNLOCK_GIANT(vfslocked);
2096         if (error)
2097                 return (error);
2098         *sbp = sb;
2099         return (0);
2100 }
2101
2102 /*
2103  * Implementation of the NetBSD [l]stat() functions.
2104  */
2105 void
2106 cvtnstat(sb, nsb)
2107         struct stat *sb;
2108         struct nstat *nsb;
2109 {
2110         bzero(nsb, sizeof *nsb);
2111         nsb->st_dev = sb->st_dev;
2112         nsb->st_ino = sb->st_ino;
2113         nsb->st_mode = sb->st_mode;
2114         nsb->st_nlink = sb->st_nlink;
2115         nsb->st_uid = sb->st_uid;
2116         nsb->st_gid = sb->st_gid;
2117         nsb->st_rdev = sb->st_rdev;
2118         nsb->st_atimespec = sb->st_atimespec;
2119         nsb->st_mtimespec = sb->st_mtimespec;
2120         nsb->st_ctimespec = sb->st_ctimespec;
2121         nsb->st_size = sb->st_size;
2122         nsb->st_blocks = sb->st_blocks;
2123         nsb->st_blksize = sb->st_blksize;
2124         nsb->st_flags = sb->st_flags;
2125         nsb->st_gen = sb->st_gen;
2126         nsb->st_birthtimespec = sb->st_birthtimespec;
2127 }
2128
2129 #ifndef _SYS_SYSPROTO_H_
2130 struct nstat_args {
2131         char    *path;
2132         struct nstat *ub;
2133 };
2134 #endif
2135 int
2136 nstat(td, uap)
2137         struct thread *td;
2138         register struct nstat_args /* {
2139                 char *path;
2140                 struct nstat *ub;
2141         } */ *uap;
2142 {
2143         struct stat sb;
2144         struct nstat nsb;
2145         int error;
2146
2147         error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
2148         if (error)
2149                 return (error);
2150         cvtnstat(&sb, &nsb);
2151         error = copyout(&nsb, uap->ub, sizeof (nsb));
2152         return (error);
2153 }
2154
2155 /*
2156  * NetBSD lstat.  Get file status; this version does not follow links.
2157  */
2158 #ifndef _SYS_SYSPROTO_H_
2159 struct lstat_args {
2160         char    *path;
2161         struct stat *ub;
2162 };
2163 #endif
2164 int
2165 nlstat(td, uap)
2166         struct thread *td;
2167         register struct nlstat_args /* {
2168                 char *path;
2169                 struct nstat *ub;
2170         } */ *uap;
2171 {
2172         struct stat sb;
2173         struct nstat nsb;
2174         int error;
2175
2176         error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
2177         if (error)
2178                 return (error);
2179         cvtnstat(&sb, &nsb);
2180         error = copyout(&nsb, uap->ub, sizeof (nsb));
2181         return (error);
2182 }
2183
2184 /*
2185  * Get configurable pathname variables.
2186  */
2187 #ifndef _SYS_SYSPROTO_H_
2188 struct pathconf_args {
2189         char    *path;
2190         int     name;
2191 };
2192 #endif
2193 int
2194 pathconf(td, uap)
2195         struct thread *td;
2196         register struct pathconf_args /* {
2197                 char *path;
2198                 int name;
2199         } */ *uap;
2200 {
2201
2202         return (kern_pathconf(td, uap->path, UIO_USERSPACE, uap->name));
2203 }
2204
2205 int
2206 kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name)
2207 {
2208         struct nameidata nd;
2209         int error, vfslocked;
2210
2211         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE, pathseg, path, td);
2212         if ((error = namei(&nd)) != 0)
2213                 return (error);
2214         vfslocked = NDHASGIANT(&nd);
2215         NDFREE(&nd, NDF_ONLY_PNBUF);
2216
2217         /* If asynchronous I/O is available, it works for all files. */
2218         if (name == _PC_ASYNC_IO)
2219                 td->td_retval[0] = async_io_version;
2220         else
2221                 error = VOP_PATHCONF(nd.ni_vp, name, td->td_retval);
2222         vput(nd.ni_vp);
2223         VFS_UNLOCK_GIANT(vfslocked);
2224         return (error);
2225 }
2226
2227 /*
2228  * Return target name of a symbolic link.
2229  */
2230 #ifndef _SYS_SYSPROTO_H_
2231 struct readlink_args {
2232         char    *path;
2233         char    *buf;
2234         int     count;
2235 };
2236 #endif
2237 int
2238 readlink(td, uap)
2239         struct thread *td;
2240         register struct readlink_args /* {
2241                 char *path;
2242                 char *buf;
2243                 int count;
2244         } */ *uap;
2245 {
2246
2247         return (kern_readlink(td, uap->path, UIO_USERSPACE, uap->buf,
2248             UIO_USERSPACE, uap->count));
2249 }
2250
2251 int
2252 kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf,
2253     enum uio_seg bufseg, int count)
2254 {
2255         register struct vnode *vp;
2256         struct iovec aiov;
2257         struct uio auio;
2258         int error;
2259         struct nameidata nd;
2260         int vfslocked;
2261
2262         NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE, pathseg, path, td);
2263         if ((error = namei(&nd)) != 0)
2264                 return (error);
2265         NDFREE(&nd, NDF_ONLY_PNBUF);
2266         vfslocked = NDHASGIANT(&nd);
2267         vp = nd.ni_vp;
2268 #ifdef MAC
2269         error = mac_check_vnode_readlink(td->td_ucred, vp);
2270         if (error) {
2271                 vput(vp);
2272                 VFS_UNLOCK_GIANT(vfslocked);
2273                 return (error);
2274         }
2275 #endif
2276         if (vp->v_type != VLNK)
2277                 error = EINVAL;
2278         else {
2279                 aiov.iov_base = buf;
2280                 aiov.iov_len = count;
2281                 auio.uio_iov = &aiov;
2282                 auio.uio_iovcnt = 1;
2283                 auio.uio_offset = 0;
2284                 auio.uio_rw = UIO_READ;
2285                 auio.uio_segflg = bufseg;
2286                 auio.uio_td = td;
2287                 auio.uio_resid = count;
2288                 error = VOP_READLINK(vp, &auio, td->td_ucred);
2289         }
2290         vput(vp);
2291         VFS_UNLOCK_GIANT(vfslocked);
2292         td->td_retval[0] = count - auio.uio_resid;
2293         return (error);
2294 }
2295
2296 /*
2297  * Common implementation code for chflags() and fchflags().
2298  */
2299 static int
2300 setfflags(td, vp, flags)
2301         struct thread *td;
2302         struct vnode *vp;
2303         int flags;
2304 {
2305         int error;
2306         struct mount *mp;
2307         struct vattr vattr;
2308
2309         /*
2310          * Prevent non-root users from setting flags on devices.  When
2311          * a device is reused, users can retain ownership of the device
2312          * if they are allowed to set flags and programs assume that
2313          * chown can't fail when done as root.
2314          */
2315         if (vp->v_type == VCHR || vp->v_type == VBLK) {
2316                 error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
2317                 if (error)
2318                         return (error);
2319         }
2320
2321         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2322                 return (error);
2323         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2324         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2325         VATTR_NULL(&vattr);
2326         vattr.va_flags = flags;
2327 #ifdef MAC
2328         error = mac_check_vnode_setflags(td->td_ucred, vp, vattr.va_flags);
2329         if (error == 0)
2330 #endif
2331                 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2332         VOP_UNLOCK(vp, 0, td);
2333         vn_finished_write(mp);
2334         return (error);
2335 }
2336
2337 /*
2338  * Change flags of a file given a path name.
2339  */
2340 #ifndef _SYS_SYSPROTO_H_
2341 struct chflags_args {
2342         char    *path;
2343         int     flags;
2344 };
2345 #endif
2346 int
2347 chflags(td, uap)
2348         struct thread *td;
2349         register struct chflags_args /* {
2350                 char *path;
2351                 int flags;
2352         } */ *uap;
2353 {
2354         int error;
2355         struct nameidata nd;
2356         int vfslocked;
2357
2358         NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_USERSPACE, uap->path, td);
2359         if ((error = namei(&nd)) != 0)
2360                 return (error);
2361         NDFREE(&nd, NDF_ONLY_PNBUF);
2362         vfslocked = NDHASGIANT(&nd);
2363         error = setfflags(td, nd.ni_vp, uap->flags);
2364         vrele(nd.ni_vp);
2365         VFS_UNLOCK_GIANT(vfslocked);
2366         return (error);
2367 }
2368
2369 /*
2370  * Same as chflags() but doesn't follow symlinks.
2371  */
2372 int
2373 lchflags(td, uap)
2374         struct thread *td;
2375         register struct lchflags_args /* {
2376                 char *path;
2377                 int flags;
2378         } */ *uap;
2379 {
2380         int error;
2381         struct nameidata nd;
2382         int vfslocked;
2383
2384         NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_USERSPACE, uap->path, td);
2385         if ((error = namei(&nd)) != 0)
2386                 return (error);
2387         vfslocked = NDHASGIANT(&nd);
2388         NDFREE(&nd, NDF_ONLY_PNBUF);
2389         error = setfflags(td, nd.ni_vp, uap->flags);
2390         vrele(nd.ni_vp);
2391         VFS_UNLOCK_GIANT(vfslocked);
2392         return (error);
2393 }
2394
2395 /*
2396  * Change flags of a file given a file descriptor.
2397  */
2398 #ifndef _SYS_SYSPROTO_H_
2399 struct fchflags_args {
2400         int     fd;
2401         int     flags;
2402 };
2403 #endif
2404 int
2405 fchflags(td, uap)
2406         struct thread *td;
2407         register struct fchflags_args /* {
2408                 int fd;
2409                 int flags;
2410         } */ *uap;
2411 {
2412         struct file *fp;
2413         int vfslocked;
2414         int error;
2415
2416         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
2417                 return (error);
2418         vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2419         error = setfflags(td, fp->f_vnode, uap->flags);
2420         fdrop(fp, td);
2421         VFS_UNLOCK_GIANT(vfslocked);
2422         return (error);
2423 }
2424
2425 /*
2426  * Common implementation code for chmod(), lchmod() and fchmod().
2427  */
2428 static int
2429 setfmode(td, vp, mode)
2430         struct thread *td;
2431         struct vnode *vp;
2432         int mode;
2433 {
2434         int error;
2435         struct mount *mp;
2436         struct vattr vattr;
2437
2438         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2439                 return (error);
2440         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2441         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2442         VATTR_NULL(&vattr);
2443         vattr.va_mode = mode & ALLPERMS;
2444 #ifdef MAC
2445         error = mac_check_vnode_setmode(td->td_ucred, vp, vattr.va_mode);
2446         if (error == 0)
2447 #endif
2448                 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2449         VOP_UNLOCK(vp, 0, td);
2450         vn_finished_write(mp);
2451         return (error);
2452 }
2453
2454 /*
2455  * Change mode of a file given path name.
2456  */
2457 #ifndef _SYS_SYSPROTO_H_
2458 struct chmod_args {
2459         char    *path;
2460         int     mode;
2461 };
2462 #endif
2463 int
2464 chmod(td, uap)
2465         struct thread *td;
2466         register struct chmod_args /* {
2467                 char *path;
2468                 int mode;
2469         } */ *uap;
2470 {
2471
2472         return (kern_chmod(td, uap->path, UIO_USERSPACE, uap->mode));
2473 }
2474
2475 int
2476 kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode)
2477 {
2478         int error;
2479         struct nameidata nd;
2480         int vfslocked;
2481
2482         NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, pathseg, path, td);
2483         if ((error = namei(&nd)) != 0)
2484                 return (error);
2485         vfslocked = NDHASGIANT(&nd);
2486         NDFREE(&nd, NDF_ONLY_PNBUF);
2487         error = setfmode(td, nd.ni_vp, mode);
2488         vrele(nd.ni_vp);
2489         VFS_UNLOCK_GIANT(vfslocked);
2490         return (error);
2491 }
2492
2493 /*
2494  * Change mode of a file given path name (don't follow links.)
2495  */
2496 #ifndef _SYS_SYSPROTO_H_
2497 struct lchmod_args {
2498         char    *path;
2499         int     mode;
2500 };
2501 #endif
2502 int
2503 lchmod(td, uap)
2504         struct thread *td;
2505         register struct lchmod_args /* {
2506                 char *path;
2507                 int mode;
2508         } */ *uap;
2509 {
2510         int error;
2511         struct nameidata nd;
2512         int vfslocked;
2513
2514         NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_USERSPACE, uap->path, td);
2515         if ((error = namei(&nd)) != 0)
2516                 return (error);
2517         vfslocked = NDHASGIANT(&nd);
2518         NDFREE(&nd, NDF_ONLY_PNBUF);
2519         error = setfmode(td, nd.ni_vp, uap->mode);
2520         vrele(nd.ni_vp);
2521         VFS_UNLOCK_GIANT(vfslocked);
2522         return (error);
2523 }
2524
2525 /*
2526  * Change mode of a file given a file descriptor.
2527  */
2528 #ifndef _SYS_SYSPROTO_H_
2529 struct fchmod_args {
2530         int     fd;
2531         int     mode;
2532 };
2533 #endif
2534 int
2535 fchmod(td, uap)
2536         struct thread *td;
2537         register struct fchmod_args /* {
2538                 int fd;
2539                 int mode;
2540         } */ *uap;
2541 {
2542         struct file *fp;
2543         int vfslocked;
2544         int error;
2545
2546         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
2547                 return (error);
2548         vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2549         error = setfmode(td, fp->f_vnode, uap->mode);
2550         fdrop(fp, td);
2551         VFS_UNLOCK_GIANT(vfslocked);
2552         return (error);
2553 }
2554
2555 /*
2556  * Common implementation for chown(), lchown(), and fchown()
2557  */
2558 static int
2559 setfown(td, vp, uid, gid)
2560         struct thread *td;
2561         struct vnode *vp;
2562         uid_t uid;
2563         gid_t gid;
2564 {
2565         int error;
2566         struct mount *mp;
2567         struct vattr vattr;
2568
2569         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2570                 return (error);
2571         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2572         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2573         VATTR_NULL(&vattr);
2574         vattr.va_uid = uid;
2575         vattr.va_gid = gid;
2576 #ifdef MAC
2577         error = mac_check_vnode_setowner(td->td_ucred, vp, vattr.va_uid,
2578             vattr.va_gid);
2579         if (error == 0)
2580 #endif
2581                 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2582         VOP_UNLOCK(vp, 0, td);
2583         vn_finished_write(mp);
2584         return (error);
2585 }
2586
2587 /*
2588  * Set ownership given a path name.
2589  */
2590 #ifndef _SYS_SYSPROTO_H_
2591 struct chown_args {
2592         char    *path;
2593         int     uid;
2594         int     gid;
2595 };
2596 #endif
2597 int
2598 chown(td, uap)
2599         struct thread *td;
2600         register struct chown_args /* {
2601                 char *path;
2602                 int uid;
2603                 int gid;
2604         } */ *uap;
2605 {
2606
2607         return (kern_chown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid));
2608 }
2609
2610 int
2611 kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid,
2612     int gid)
2613 {
2614         int error;
2615         struct nameidata nd;
2616         int vfslocked;
2617
2618         NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, pathseg, path, td);
2619         if ((error = namei(&nd)) != 0)
2620                 return (error);
2621         vfslocked = NDHASGIANT(&nd);
2622         NDFREE(&nd, NDF_ONLY_PNBUF);
2623         error = setfown(td, nd.ni_vp, uid, gid);
2624         vrele(nd.ni_vp);
2625         VFS_UNLOCK_GIANT(vfslocked);
2626         return (error);
2627 }
2628
2629 /*
2630  * Set ownership given a path name, do not cross symlinks.
2631  */
2632 #ifndef _SYS_SYSPROTO_H_
2633 struct lchown_args {
2634         char    *path;
2635         int     uid;
2636         int     gid;
2637 };
2638 #endif
2639 int
2640 lchown(td, uap)
2641         struct thread *td;
2642         register struct lchown_args /* {
2643                 char *path;
2644                 int uid;
2645                 int gid;
2646         } */ *uap;
2647 {
2648
2649         return (kern_lchown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid));
2650 }
2651
2652 int
2653 kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid,
2654     int gid)
2655 {
2656         int error;
2657         struct nameidata nd;
2658         int vfslocked;
2659
2660         NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, pathseg, path, td);
2661         if ((error = namei(&nd)) != 0)
2662                 return (error);
2663         vfslocked = NDHASGIANT(&nd);
2664         NDFREE(&nd, NDF_ONLY_PNBUF);
2665         error = setfown(td, nd.ni_vp, uid, gid);
2666         vrele(nd.ni_vp);
2667         VFS_UNLOCK_GIANT(vfslocked);
2668         return (error);
2669 }
2670
2671 /*
2672  * Set ownership given a file descriptor.
2673  */
2674 #ifndef _SYS_SYSPROTO_H_
2675 struct fchown_args {
2676         int     fd;
2677         int     uid;
2678         int     gid;
2679 };
2680 #endif
2681 int
2682 fchown(td, uap)
2683         struct thread *td;
2684         register struct fchown_args /* {
2685                 int fd;
2686                 int uid;
2687                 int gid;
2688         } */ *uap;
2689 {
2690         struct file *fp;
2691         int vfslocked;
2692         int error;
2693
2694         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
2695                 return (error);
2696         vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2697         error = setfown(td, fp->f_vnode, uap->uid, uap->gid);
2698         fdrop(fp, td);
2699         VFS_UNLOCK_GIANT(vfslocked);
2700         return (error);
2701 }
2702
2703 /*
2704  * Common implementation code for utimes(), lutimes(), and futimes().
2705  */
2706 static int
2707 getutimes(usrtvp, tvpseg, tsp)
2708         const struct timeval *usrtvp;
2709         enum uio_seg tvpseg;
2710         struct timespec *tsp;
2711 {
2712         struct timeval tv[2];
2713         const struct timeval *tvp;
2714         int error;
2715
2716         if (usrtvp == NULL) {
2717                 microtime(&tv[0]);
2718                 TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]);
2719                 tsp[1] = tsp[0];
2720         } else {
2721                 if (tvpseg == UIO_SYSSPACE) {
2722                         tvp = usrtvp;
2723                 } else {
2724                         if ((error = copyin(usrtvp, tv, sizeof(tv))) != 0)
2725                                 return (error);
2726                         tvp = tv;
2727                 }
2728
2729                 TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]);
2730                 TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]);
2731         }
2732         return (0);
2733 }
2734
2735 /*
2736  * Common implementation code for utimes(), lutimes(), and futimes().
2737  */
2738 static int
2739 setutimes(td, vp, ts, numtimes, nullflag)
2740         struct thread *td;
2741         struct vnode *vp;
2742         const struct timespec *ts;
2743         int numtimes;
2744         int nullflag;
2745 {
2746         int error, setbirthtime;
2747         struct mount *mp;
2748         struct vattr vattr;
2749
2750         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
2751                 return (error);
2752         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2753         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2754         setbirthtime = 0;
2755         if (numtimes < 3 && VOP_GETATTR(vp, &vattr, td->td_ucred, td) == 0 &&
2756             timespeccmp(&ts[1], &vattr.va_birthtime, < ))
2757                 setbirthtime = 1;
2758         VATTR_NULL(&vattr);
2759         vattr.va_atime = ts[0];
2760         vattr.va_mtime = ts[1];
2761         if (setbirthtime)
2762                 vattr.va_birthtime = ts[1];
2763         if (numtimes > 2)
2764                 vattr.va_birthtime = ts[2];
2765         if (nullflag)
2766                 vattr.va_vaflags |= VA_UTIMES_NULL;
2767 #ifdef MAC
2768         error = mac_check_vnode_setutimes(td->td_ucred, vp, vattr.va_atime,
2769             vattr.va_mtime);
2770 #endif
2771         if (error == 0)
2772                 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2773         VOP_UNLOCK(vp, 0, td);
2774         vn_finished_write(mp);
2775         return (error);
2776 }
2777
2778 /*
2779  * Set the access and modification times of a file.
2780  */
2781 #ifndef _SYS_SYSPROTO_H_
2782 struct utimes_args {
2783         char    *path;
2784         struct  timeval *tptr;
2785 };
2786 #endif
2787 int
2788 utimes(td, uap)
2789         struct thread *td;
2790         register struct utimes_args /* {
2791                 char *path;
2792                 struct timeval *tptr;
2793         } */ *uap;
2794 {
2795
2796         return (kern_utimes(td, uap->path, UIO_USERSPACE, uap->tptr,
2797             UIO_USERSPACE));
2798 }
2799
2800 int
2801 kern_utimes(struct thread *td, char *path, enum uio_seg pathseg,
2802     struct timeval *tptr, enum uio_seg tptrseg)
2803 {
2804         struct timespec ts[2];
2805         int error;
2806         struct nameidata nd;
2807         int vfslocked;
2808
2809         if ((error = getutimes(tptr, tptrseg, ts)) != 0)
2810                 return (error);
2811         NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, pathseg, path, td);
2812         if ((error = namei(&nd)) != 0)
2813                 return (error);
2814         vfslocked = NDHASGIANT(&nd);
2815         NDFREE(&nd, NDF_ONLY_PNBUF);
2816         error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL);
2817         vrele(nd.ni_vp);
2818         VFS_UNLOCK_GIANT(vfslocked);
2819         return (error);
2820 }
2821
2822 /*
2823  * Set the access and modification times of a file.
2824  */
2825 #ifndef _SYS_SYSPROTO_H_
2826 struct lutimes_args {
2827         char    *path;
2828         struct  timeval *tptr;
2829 };
2830 #endif
2831 int
2832 lutimes(td, uap)
2833         struct thread *td;
2834         register struct lutimes_args /* {
2835                 char *path;
2836                 struct timeval *tptr;
2837         } */ *uap;
2838 {
2839
2840         return (kern_lutimes(td, uap->path, UIO_USERSPACE, uap->tptr,
2841             UIO_USERSPACE));
2842 }
2843
2844 int
2845 kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg,
2846     struct timeval *tptr, enum uio_seg tptrseg)
2847 {
2848         struct timespec ts[2];
2849         int error;
2850         struct nameidata nd;
2851         int vfslocked;
2852
2853         if ((error = getutimes(tptr, tptrseg, ts)) != 0)
2854                 return (error);
2855         NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, pathseg, path, td);
2856         if ((error = namei(&nd)) != 0)
2857                 return (error);
2858         vfslocked = NDHASGIANT(&nd);
2859         NDFREE(&nd, NDF_ONLY_PNBUF);
2860         error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL);
2861         vrele(nd.ni_vp);
2862         VFS_UNLOCK_GIANT(vfslocked);
2863         return (error);
2864 }
2865
2866 /*
2867  * Set the access and modification times of a file.
2868  */
2869 #ifndef _SYS_SYSPROTO_H_
2870 struct futimes_args {
2871         int     fd;
2872         struct  timeval *tptr;
2873 };
2874 #endif
2875 int
2876 futimes(td, uap)
2877         struct thread *td;
2878         register struct futimes_args /* {
2879                 int  fd;
2880                 struct timeval *tptr;
2881         } */ *uap;
2882 {
2883
2884         return (kern_futimes(td, uap->fd, uap->tptr, UIO_USERSPACE));
2885 }
2886
2887 int
2888 kern_futimes(struct thread *td, int fd, struct timeval *tptr,
2889     enum uio_seg tptrseg)
2890 {
2891         struct timespec ts[2];
2892         struct file *fp;
2893         int vfslocked;
2894         int error;
2895
2896         if ((error = getutimes(tptr, tptrseg, ts)) != 0)
2897                 return (error);
2898         if ((error = getvnode(td->td_proc->p_fd, fd, &fp)) != 0)
2899                 return (error);
2900         vfslocked = VFS_LOCK_GIANT(fp->f_vnode->v_mount);
2901         error = setutimes(td, fp->f_vnode, ts, 2, tptr == NULL);
2902         fdrop(fp, td);
2903         VFS_UNLOCK_GIANT(vfslocked);
2904         return (error);
2905 }
2906
2907 /*
2908  * Truncate a file given its path name.
2909  */
2910 #ifndef _SYS_SYSPROTO_H_
2911 struct truncate_args {
2912         char    *path;
2913         int     pad;
2914         off_t   length;
2915 };
2916 #endif
2917 int
2918 truncate(td, uap)
2919         struct thread *td;
2920         register struct truncate_args /* {
2921                 char *path;
2922                 int pad;
2923                 off_t length;
2924         } */ *uap;
2925 {
2926
2927         return (kern_truncate(td, uap->path, UIO_USERSPACE, uap->length));
2928 }
2929
2930 int
2931 kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length)
2932 {
2933         struct mount *mp;
2934         struct vnode *vp;
2935         struct vattr vattr;
2936         int error;
2937         struct nameidata nd;
2938         int vfslocked;
2939
2940         if (length < 0)
2941                 return(EINVAL);
2942         NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, pathseg, path, td);
2943         if ((error = namei(&nd)) != 0)
2944                 return (error);
2945         vfslocked = NDHASGIANT(&nd);
2946         vp = nd.ni_vp;
2947         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
2948                 vrele(vp);
2949                 VFS_UNLOCK_GIANT(vfslocked);
2950                 return (error);
2951         }
2952         NDFREE(&nd, NDF_ONLY_PNBUF);
2953         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
2954         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2955         if (vp->v_type == VDIR)
2956                 error = EISDIR;
2957 #ifdef MAC
2958         else if ((error = mac_check_vnode_write(td->td_ucred, NOCRED, vp))) {
2959         }
2960 #endif
2961         else if ((error = vn_writechk(vp)) == 0 &&
2962             (error = VOP_ACCESS(vp, VWRITE, td->td_ucred, td)) == 0) {
2963                 VATTR_NULL(&vattr);
2964                 vattr.va_size = length;
2965                 error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
2966         }
2967         vput(vp);
2968         vn_finished_write(mp);
2969         VFS_UNLOCK_GIANT(vfslocked);
2970         return (error);
2971 }
2972
2973 /*
2974  * Truncate a file given a file descriptor.
2975  */
2976 #ifndef _SYS_SYSPROTO_H_
2977 struct ftruncate_args {
2978         int     fd;
2979         int     pad;
2980         off_t   length;
2981 };
2982 #endif
2983 int
2984 ftruncate(td, uap)
2985         struct thread *td;
2986         register struct ftruncate_args /* {
2987                 int fd;
2988                 int pad;
2989                 off_t length;
2990         } */ *uap;
2991 {
2992         struct mount *mp;
2993         struct vattr vattr;
2994         struct vnode *vp;
2995         struct file *fp;
2996         int vfslocked;
2997         int error;
2998
2999         if (uap->length < 0)
3000                 return(EINVAL);
3001         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3002                 return (error);
3003         if ((fp->f_flag & FWRITE) == 0) {
3004                 fdrop(fp, td);
3005                 return (EINVAL);
3006         }
3007         vp = fp->f_vnode;
3008         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
3009         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
3010                 goto drop;
3011         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3012         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3013         if (vp->v_type == VDIR)
3014                 error = EISDIR;
3015 #ifdef MAC
3016         else if ((error = mac_check_vnode_write(td->td_ucred, fp->f_cred,
3017             vp))) {
3018         }
3019 #endif
3020         else if ((error = vn_writechk(vp)) == 0) {
3021                 VATTR_NULL(&vattr);
3022                 vattr.va_size = uap->length;
3023                 error = VOP_SETATTR(vp, &vattr, fp->f_cred, td);
3024         }
3025         VOP_UNLOCK(vp, 0, td);
3026         vn_finished_write(mp);
3027 drop:
3028         VFS_UNLOCK_GIANT(vfslocked);
3029         fdrop(fp, td);
3030         return (error);
3031 }
3032
3033 #if defined(COMPAT_43)
3034 /*
3035  * Truncate a file given its path name.
3036  */
3037 #ifndef _SYS_SYSPROTO_H_
3038 struct otruncate_args {
3039         char    *path;
3040         long    length;
3041 };
3042 #endif
3043 int
3044 otruncate(td, uap)
3045         struct thread *td;
3046         register struct otruncate_args /* {
3047                 char *path;
3048                 long length;
3049         } */ *uap;
3050 {
3051         struct truncate_args /* {
3052                 char *path;
3053                 int pad;
3054                 off_t length;
3055         } */ nuap;
3056
3057         nuap.path = uap->path;
3058         nuap.length = uap->length;
3059         return (truncate(td, &nuap));
3060 }
3061
3062 /*
3063  * Truncate a file given a file descriptor.
3064  */
3065 #ifndef _SYS_SYSPROTO_H_
3066 struct oftruncate_args {
3067         int     fd;
3068         long    length;
3069 };
3070 #endif
3071 int
3072 oftruncate(td, uap)
3073         struct thread *td;
3074         register struct oftruncate_args /* {
3075                 int fd;
3076                 long length;
3077         } */ *uap;
3078 {
3079         struct ftruncate_args /* {
3080                 int fd;
3081                 int pad;
3082                 off_t length;
3083         } */ nuap;
3084
3085         nuap.fd = uap->fd;
3086         nuap.length = uap->length;
3087         return (ftruncate(td, &nuap));
3088 }
3089 #endif /* COMPAT_43 */
3090
3091 /*
3092  * Sync an open file.
3093  */
3094 #ifndef _SYS_SYSPROTO_H_
3095 struct fsync_args {
3096         int     fd;
3097 };
3098 #endif
3099 int
3100 fsync(td, uap)
3101         struct thread *td;
3102         struct fsync_args /* {
3103                 int fd;
3104         } */ *uap;
3105 {
3106         struct vnode *vp;
3107         struct mount *mp;
3108         struct file *fp;
3109         int vfslocked;
3110         int error;
3111
3112         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3113                 return (error);
3114         vp = fp->f_vnode;
3115         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
3116         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
3117                 goto drop;
3118         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3119         if (vp->v_object != NULL) {
3120                 VM_OBJECT_LOCK(vp->v_object);
3121                 vm_object_page_clean(vp->v_object, 0, 0, 0);
3122                 VM_OBJECT_UNLOCK(vp->v_object);
3123         }
3124         error = VOP_FSYNC(vp, MNT_WAIT, td);
3125
3126         VOP_UNLOCK(vp, 0, td);
3127         vn_finished_write(mp);
3128 drop:
3129         VFS_UNLOCK_GIANT(vfslocked);
3130         fdrop(fp, td);
3131         return (error);
3132 }
3133
3134 /*
3135  * Rename files.  Source and destination must either both be directories,
3136  * or both not be directories.  If target is a directory, it must be empty.
3137  */
3138 #ifndef _SYS_SYSPROTO_H_
3139 struct rename_args {
3140         char    *from;
3141         char    *to;
3142 };
3143 #endif
3144 int
3145 rename(td, uap)
3146         struct thread *td;
3147         register struct rename_args /* {
3148                 char *from;
3149                 char *to;
3150         } */ *uap;
3151 {
3152
3153         return (kern_rename(td, uap->from, uap->to, UIO_USERSPACE));
3154 }
3155
3156 int
3157 kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg)
3158 {
3159         struct mount *mp = NULL;
3160         struct vnode *tvp, *fvp, *tdvp;
3161         struct nameidata fromnd, tond;
3162         int tvfslocked;
3163         int fvfslocked;
3164         int error;
3165
3166         bwillwrite();
3167 #ifdef MAC
3168         NDINIT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE,
3169             pathseg, from, td);
3170 #else
3171         NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE,
3172             pathseg, from, td);
3173 #endif
3174         if ((error = namei(&fromnd)) != 0)
3175                 return (error);
3176         fvfslocked = NDHASGIANT(&fromnd);
3177         tvfslocked = 0;
3178 #ifdef MAC
3179         error = mac_check_vnode_rename_from(td->td_ucred, fromnd.ni_dvp,
3180             fromnd.ni_vp, &fromnd.ni_cnd);
3181         VOP_UNLOCK(fromnd.ni_dvp, 0, td);
3182         VOP_UNLOCK(fromnd.ni_vp, 0, td);
3183 #endif
3184         fvp = fromnd.ni_vp;
3185         if (error == 0)
3186                 error = vn_start_write(fvp, &mp, V_WAIT | PCATCH);
3187         if (error != 0) {
3188                 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3189                 vrele(fromnd.ni_dvp);
3190                 vrele(fvp);
3191                 goto out1;
3192         }
3193         NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART |
3194             MPSAFE, pathseg, to, td);
3195         if (fromnd.ni_vp->v_type == VDIR)
3196                 tond.ni_cnd.cn_flags |= WILLBEDIR;
3197         if ((error = namei(&tond)) != 0) {
3198                 /* Translate error code for rename("dir1", "dir2/."). */
3199                 if (error == EISDIR && fvp->v_type == VDIR)
3200                         error = EINVAL;
3201                 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3202                 vrele(fromnd.ni_dvp);
3203                 vrele(fvp);
3204                 goto out1;
3205         }
3206         tvfslocked = NDHASGIANT(&tond);
3207         tdvp = tond.ni_dvp;
3208         tvp = tond.ni_vp;
3209         if (tvp != NULL) {
3210                 if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
3211                         error = ENOTDIR;
3212                         goto out;
3213                 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
3214                         error = EISDIR;
3215                         goto out;
3216                 }
3217         }
3218         if (fvp == tdvp)
3219                 error = EINVAL;
3220         /*
3221          * If the source is the same as the destination (that is, if they
3222          * are links to the same vnode), then there is nothing to do.
3223          */
3224         if (fvp == tvp)
3225                 error = -1;
3226 #ifdef MAC
3227         else
3228                 error = mac_check_vnode_rename_to(td->td_ucred, tdvp,
3229                     tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd);
3230 #endif
3231 out:
3232         if (!error) {
3233                 VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE);
3234                 if (fromnd.ni_dvp != tdvp) {
3235                         VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3236                 }
3237                 if (tvp) {
3238                         VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE);
3239                 }
3240                 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
3241                                    tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
3242                 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3243                 NDFREE(&tond, NDF_ONLY_PNBUF);
3244         } else {
3245                 NDFREE(&fromnd, NDF_ONLY_PNBUF);
3246                 NDFREE(&tond, NDF_ONLY_PNBUF);
3247                 if (tvp)
3248                         vput(tvp);
3249                 if (tdvp == tvp)
3250                         vrele(tdvp);
3251                 else
3252                         vput(tdvp);
3253                 vrele(fromnd.ni_dvp);
3254                 vrele(fvp);
3255         }
3256         vrele(tond.ni_startdir);
3257         ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename");
3258         ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename");
3259         ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename");
3260         ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename");
3261 out1:
3262         vn_finished_write(mp);
3263         if (fromnd.ni_startdir)
3264                 vrele(fromnd.ni_startdir);
3265         VFS_UNLOCK_GIANT(fvfslocked);
3266         VFS_UNLOCK_GIANT(tvfslocked);
3267         if (error == -1)
3268                 return (0);
3269         return (error);
3270 }
3271
3272 /*
3273  * Make a directory file.
3274  */
3275 #ifndef _SYS_SYSPROTO_H_
3276 struct mkdir_args {
3277         char    *path;
3278         int     mode;
3279 };
3280 #endif
3281 int
3282 mkdir(td, uap)
3283         struct thread *td;
3284         register struct mkdir_args /* {
3285                 char *path;
3286                 int mode;
3287         } */ *uap;
3288 {
3289
3290         return (kern_mkdir(td, uap->path, UIO_USERSPACE, uap->mode));
3291 }
3292
3293 int
3294 kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode)
3295 {
3296         struct mount *mp;
3297         struct vnode *vp;
3298         struct vattr vattr;
3299         int error;
3300         struct nameidata nd;
3301         int vfslocked;
3302
3303 restart:
3304         bwillwrite();
3305         NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE, segflg, path, td);
3306         nd.ni_cnd.cn_flags |= WILLBEDIR;
3307         if ((error = namei(&nd)) != 0)
3308                 return (error);
3309         vfslocked = NDHASGIANT(&nd);
3310         vp = nd.ni_vp;
3311         if (vp != NULL) {
3312                 NDFREE(&nd, NDF_ONLY_PNBUF);
3313                 vrele(vp);
3314                 /*
3315                  * XXX namei called with LOCKPARENT but not LOCKLEAF has
3316                  * the strange behaviour of leaving the vnode unlocked
3317                  * if the target is the same vnode as the parent.
3318                  */
3319                 if (vp == nd.ni_dvp)
3320                         vrele(nd.ni_dvp);
3321                 else
3322                         vput(nd.ni_dvp);
3323                 VFS_UNLOCK_GIANT(vfslocked);
3324                 return (EEXIST);
3325         }
3326         if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
3327                 NDFREE(&nd, NDF_ONLY_PNBUF);
3328                 vput(nd.ni_dvp);
3329                 VFS_UNLOCK_GIANT(vfslocked);
3330                 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
3331                         return (error);
3332                 goto restart;
3333         }
3334         VATTR_NULL(&vattr);
3335         vattr.va_type = VDIR;
3336         FILEDESC_LOCK_FAST(td->td_proc->p_fd);
3337         vattr.va_mode = (mode & ACCESSPERMS) &~ td->td_proc->p_fd->fd_cmask;
3338         FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
3339 #ifdef MAC
3340         error = mac_check_vnode_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
3341             &vattr);
3342         if (error)
3343                 goto out;
3344 #endif
3345         VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3346         error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
3347 #ifdef MAC
3348 out:
3349 #endif
3350         NDFREE(&nd, NDF_ONLY_PNBUF);
3351         vput(nd.ni_dvp);
3352         if (!error)
3353                 vput(nd.ni_vp);
3354         vn_finished_write(mp);
3355         VFS_UNLOCK_GIANT(vfslocked);
3356         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir");
3357         ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir");
3358         return (error);
3359 }
3360
3361 /*
3362  * Remove a directory file.
3363  */
3364 #ifndef _SYS_SYSPROTO_H_
3365 struct rmdir_args {
3366         char    *path;
3367 };
3368 #endif
3369 int
3370 rmdir(td, uap)
3371         struct thread *td;
3372         struct rmdir_args /* {
3373                 char *path;
3374         } */ *uap;
3375 {
3376
3377         return (kern_rmdir(td, uap->path, UIO_USERSPACE));
3378 }
3379
3380 int
3381 kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg)
3382 {
3383         struct mount *mp;
3384         struct vnode *vp;
3385         int error;
3386         struct nameidata nd;
3387         int vfslocked;
3388
3389 restart:
3390         bwillwrite();
3391         NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF | MPSAFE, pathseg, path, td);
3392         if ((error = namei(&nd)) != 0)
3393                 return (error);
3394         vfslocked = NDHASGIANT(&nd);
3395         vp = nd.ni_vp;
3396         if (vp->v_type != VDIR) {
3397                 error = ENOTDIR;
3398                 goto out;
3399         }
3400         /*
3401          * No rmdir "." please.
3402          */
3403         if (nd.ni_dvp == vp) {
3404                 error = EINVAL;
3405                 goto out;
3406         }
3407         /*
3408          * The root of a mounted filesystem cannot be deleted.
3409          */
3410         if (vp->v_vflag & VV_ROOT) {
3411                 error = EBUSY;
3412                 goto out;
3413         }
3414 #ifdef MAC
3415         error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp,
3416             &nd.ni_cnd);
3417         if (error)
3418                 goto out;
3419 #endif
3420         if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
3421                 NDFREE(&nd, NDF_ONLY_PNBUF);
3422                 if (nd.ni_dvp == vp)
3423                         vrele(nd.ni_dvp);
3424                 else
3425                         vput(nd.ni_dvp);
3426                 vput(vp);
3427                 VFS_UNLOCK_GIANT(vfslocked);
3428                 if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
3429                         return (error);
3430                 goto restart;
3431         }
3432         VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE);
3433         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
3434         error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
3435         vn_finished_write(mp);
3436 out:
3437         NDFREE(&nd, NDF_ONLY_PNBUF);
3438         if (nd.ni_dvp == vp)
3439                 vrele(nd.ni_dvp);
3440         else
3441                 vput(nd.ni_dvp);
3442         vput(vp);
3443         VFS_UNLOCK_GIANT(vfslocked);
3444         ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir");
3445         ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir");
3446         return (error);
3447 }
3448
3449 #ifdef COMPAT_43
3450 /*
3451  * Read a block of directory entries in a filesystem independent format.
3452  */
3453 #ifndef _SYS_SYSPROTO_H_
3454 struct ogetdirentries_args {
3455         int     fd;
3456         char    *buf;
3457         u_int   count;
3458         long    *basep;
3459 };
3460 #endif
3461 int
3462 ogetdirentries(td, uap)
3463         struct thread *td;
3464         register struct ogetdirentries_args /* {
3465                 int fd;
3466                 char *buf;
3467                 u_int count;
3468                 long *basep;
3469         } */ *uap;
3470 {
3471         struct vnode *vp;
3472         struct file *fp;
3473         struct uio auio, kuio;
3474         struct iovec aiov, kiov;
3475         struct dirent *dp, *edp;
3476         caddr_t dirbuf;
3477         int error, eofflag, readcnt;
3478         long loff;
3479
3480         /* XXX arbitrary sanity limit on `count'. */
3481         if (uap->count > 64 * 1024)
3482                 return (EINVAL);
3483         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3484                 return (error);
3485         if ((fp->f_flag & FREAD) == 0) {
3486                 fdrop(fp, td);
3487                 return (EBADF);
3488         }
3489         vp = fp->f_vnode;
3490 unionread:
3491         if (vp->v_type != VDIR) {
3492                 fdrop(fp, td);
3493                 return (EINVAL);
3494         }
3495         aiov.iov_base = uap->buf;
3496         aiov.iov_len = uap->count;
3497         auio.uio_iov = &aiov;
3498         auio.uio_iovcnt = 1;
3499         auio.uio_rw = UIO_READ;
3500         auio.uio_segflg = UIO_USERSPACE;
3501         auio.uio_td = td;
3502         auio.uio_resid = uap->count;
3503         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3504         loff = auio.uio_offset = fp->f_offset;
3505 #ifdef MAC
3506         error = mac_check_vnode_readdir(td->td_ucred, vp);
3507         if (error) {
3508                 VOP_UNLOCK(vp, 0, td);
3509                 fdrop(fp, td);
3510                 return (error);
3511         }
3512 #endif
3513 #       if (BYTE_ORDER != LITTLE_ENDIAN)
3514                 if (vp->v_mount->mnt_maxsymlinklen <= 0) {
3515                         error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
3516                             NULL, NULL);
3517                         fp->f_offset = auio.uio_offset;
3518                 } else
3519 #       endif
3520         {
3521                 kuio = auio;
3522                 kuio.uio_iov = &kiov;
3523                 kuio.uio_segflg = UIO_SYSSPACE;
3524                 kiov.iov_len = uap->count;
3525                 MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK);
3526                 kiov.iov_base = dirbuf;
3527                 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag,
3528                             NULL, NULL);
3529                 fp->f_offset = kuio.uio_offset;
3530                 if (error == 0) {
3531                         readcnt = uap->count - kuio.uio_resid;
3532                         edp = (struct dirent *)&dirbuf[readcnt];
3533                         for (dp = (struct dirent *)dirbuf; dp < edp; ) {
3534 #                               if (BYTE_ORDER == LITTLE_ENDIAN)
3535                                         /*
3536                                          * The expected low byte of
3537                                          * dp->d_namlen is our dp->d_type.
3538                                          * The high MBZ byte of dp->d_namlen
3539                                          * is our dp->d_namlen.
3540                                          */
3541                                         dp->d_type = dp->d_namlen;
3542                                         dp->d_namlen = 0;
3543 #                               else
3544                                         /*
3545                                          * The dp->d_type is the high byte
3546                                          * of the expected dp->d_namlen,
3547                                          * so must be zero'ed.
3548                                          */
3549                                         dp->d_type = 0;
3550 #                               endif
3551                                 if (dp->d_reclen > 0) {
3552                                         dp = (struct dirent *)
3553                                             ((char *)dp + dp->d_reclen);
3554                                 } else {
3555                                         error = EIO;
3556                                         break;
3557                                 }
3558                         }
3559                         if (dp >= edp)
3560                                 error = uiomove(dirbuf, readcnt, &auio);
3561                 }
3562                 FREE(dirbuf, M_TEMP);
3563         }
3564         VOP_UNLOCK(vp, 0, td);
3565         if (error) {
3566                 fdrop(fp, td);
3567                 return (error);
3568         }
3569         if (uap->count == auio.uio_resid) {
3570                 if (union_dircheckp) {
3571                         error = union_dircheckp(td, &vp, fp);
3572                         if (error == -1)
3573                                 goto unionread;
3574                         if (error) {
3575                                 fdrop(fp, td);
3576                                 return (error);
3577                         }
3578                 }
3579                 /*
3580                  * XXX We could delay dropping the lock above but
3581                  * union_dircheckp complicates things.
3582                  */
3583                 vn_lock(vp, LK_EXCLUSIVE|LK_RETRY, td);
3584                 if ((vp->v_vflag & VV_ROOT) &&
3585                     (vp->v_mount->mnt_flag & MNT_UNION)) {
3586                         struct vnode *tvp = vp;
3587                         vp = vp->v_mount->mnt_vnodecovered;
3588                         VREF(vp);
3589                         fp->f_vnode = vp;
3590                         fp->f_data = vp;
3591                         fp->f_offset = 0;
3592                         vput(tvp);
3593                         goto unionread;
3594                 }
3595                 VOP_UNLOCK(vp, 0, td);
3596         }
3597         error = copyout(&loff, uap->basep, sizeof(long));
3598         fdrop(fp, td);
3599         td->td_retval[0] = uap->count - auio.uio_resid;
3600         return (error);
3601 }
3602 #endif /* COMPAT_43 */
3603
3604 /*
3605  * Read a block of directory entries in a filesystem independent format.
3606  */
3607 #ifndef _SYS_SYSPROTO_H_
3608 struct getdirentries_args {
3609         int     fd;
3610         char    *buf;
3611         u_int   count;
3612         long    *basep;
3613 };
3614 #endif
3615 int
3616 getdirentries(td, uap)
3617         struct thread *td;
3618         register struct getdirentries_args /* {
3619                 int fd;
3620                 char *buf;
3621                 u_int count;
3622                 long *basep;
3623         } */ *uap;
3624 {
3625         struct vnode *vp;
3626         struct file *fp;
3627         struct uio auio;
3628         struct iovec aiov;
3629         int vfslocked;
3630         long loff;
3631         int error, eofflag;
3632
3633         if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
3634                 return (error);
3635         if ((fp->f_flag & FREAD) == 0) {
3636                 fdrop(fp, td);
3637                 return (EBADF);
3638         }
3639         vp = fp->f_vnode;
3640 unionread:
3641         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
3642         if (vp->v_type != VDIR) {
3643                 error = EINVAL;
3644                 goto fail;
3645         }
3646         aiov.iov_base = uap->buf;
3647         aiov.iov_len = uap->count;
3648         auio.uio_iov = &aiov;
3649         auio.uio_iovcnt = 1;
3650         auio.uio_rw = UIO_READ;
3651         auio.uio_segflg = UIO_USERSPACE;
3652         auio.uio_td = td;
3653         auio.uio_resid = uap->count;
3654         /* vn_lock(vp, LK_SHARED | LK_RETRY, td); */
3655         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3656         loff = auio.uio_offset = fp->f_offset;
3657 #ifdef MAC
3658         error = mac_check_vnode_readdir(td->td_ucred, vp);
3659         if (error == 0)
3660 #endif
3661                 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL,
3662                     NULL);
3663         fp->f_offset = auio.uio_offset;
3664         VOP_UNLOCK(vp, 0, td);
3665         if (error)
3666                 goto fail;
3667         if (uap->count == auio.uio_resid) {
3668                 if (union_dircheckp) {
3669                         error = union_dircheckp(td, &vp, fp);
3670                         if (error == -1) {
3671                                 VFS_UNLOCK_GIANT(vfslocked);
3672                                 goto unionread;
3673                         }
3674                         if (error)
3675                                 goto fail;
3676                 }
3677                 /*
3678                  * XXX We could delay dropping the lock above but
3679                  * union_dircheckp complicates things.
3680                  */
3681                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3682                 if ((vp->v_vflag & VV_ROOT) &&
3683                     (vp->v_mount->mnt_flag & MNT_UNION)) {
3684                         struct vnode *tvp = vp;
3685                         vp = vp->v_mount->mnt_vnodecovered;
3686                         VREF(vp);
3687                         fp->f_vnode = vp;
3688                         fp->f_data = vp;
3689                         fp->f_offset = 0;
3690                         vput(tvp);
3691                         VFS_UNLOCK_GIANT(vfslocked);
3692                         goto unionread;
3693                 }
3694                 VOP_UNLOCK(vp, 0, td);
3695         }
3696         if (uap->basep != NULL) {
3697                 error = copyout(&loff, uap->basep, sizeof(long));
3698         }
3699         td->td_retval[0] = uap->count - auio.uio_resid;
3700 fail:
3701         VFS_UNLOCK_GIANT(vfslocked);
3702         fdrop(fp, td);
3703         return (error);
3704 }
3705 #ifndef _SYS_SYSPROTO_H_
3706 struct getdents_args {
3707         int fd;
3708         char *buf;
3709         size_t count;
3710 };
3711 #endif
3712 int
3713 getdents(td, uap)
3714         struct thread *td;
3715         register struct getdents_args /* {
3716                 int fd;
3717                 char *buf;
3718                 u_int count;
3719         } */ *uap;
3720 {
3721         struct getdirentries_args ap;
3722         ap.fd = uap->fd;
3723         ap.buf = uap->buf;
3724         ap.count = uap->count;
3725         ap.basep = NULL;
3726         return (getdirentries(td, &ap));
3727 }
3728
3729 /*
3730  * Set the mode mask for creation of filesystem nodes.
3731  *
3732  * MP SAFE
3733  */
3734 #ifndef _SYS_SYSPROTO_H_
3735 struct umask_args {
3736         int     newmask;
3737 };
3738 #endif
3739 int
3740 umask(td, uap)
3741         struct thread *td;
3742         struct umask_args /* {
3743                 int newmask;
3744         } */ *uap;
3745 {
3746         register struct filedesc *fdp;
3747
3748         FILEDESC_LOCK_FAST(td->td_proc->p_fd);
3749         fdp = td->td_proc->p_fd;
3750         td->td_retval[0] = fdp->fd_cmask;
3751         fdp->fd_cmask = uap->newmask & ALLPERMS;
3752         FILEDESC_UNLOCK_FAST(td->td_proc->p_fd);
3753         return (0);
3754 }
3755
3756 /*
3757  * Void all references to file by ripping underlying filesystem
3758  * away from vnode.
3759  */
3760 #ifndef _SYS_SYSPROTO_H_
3761 struct revoke_args {
3762         char    *path;
3763 };
3764 #endif
3765 int
3766 revoke(td, uap)
3767         struct thread *td;
3768         register struct revoke_args /* {
3769                 char *path;
3770         } */ *uap;
3771 {
3772         struct vnode *vp;
3773         struct vattr vattr;
3774         int error;
3775         struct nameidata nd;
3776         int vfslocked;
3777
3778         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE, UIO_USERSPACE,
3779             uap->path, td);
3780         if ((error = namei(&nd)) != 0)
3781                 return (error);
3782         vfslocked = NDHASGIANT(&nd);
3783         vp = nd.ni_vp;
3784         NDFREE(&nd, NDF_ONLY_PNBUF);
3785         if (vp->v_type != VCHR) {
3786                 error = EINVAL;
3787                 goto out;
3788         }
3789 #ifdef MAC
3790         error = mac_check_vnode_revoke(td->td_ucred, vp);
3791         if (error)
3792                 goto out;
3793 #endif
3794         error = VOP_GETATTR(vp, &vattr, td->td_ucred, td);
3795         if (error)
3796                 goto out;
3797         if (td->td_ucred->cr_uid != vattr.va_uid) {
3798                 error = suser_cred(td->td_ucred, SUSER_ALLOWJAIL);
3799                 if (error)
3800                         goto out;
3801         }
3802         if (vcount(vp) > 1)
3803                 VOP_REVOKE(vp, REVOKEALL);
3804 out:
3805         vput(vp);
3806         VFS_UNLOCK_GIANT(vfslocked);
3807         return (error);
3808 }
3809
3810 /*
3811  * Convert a user file descriptor to a kernel file entry.
3812  * A reference on the file entry is held upon returning.
3813  */
3814 int
3815 getvnode(fdp, fd, fpp)
3816         struct filedesc *fdp;
3817         int fd;
3818         struct file **fpp;
3819 {
3820         int error;
3821         struct file *fp;
3822
3823         fp = NULL;
3824         if (fdp == NULL)
3825                 error = EBADF;
3826         else {
3827                 FILEDESC_LOCK(fdp);
3828                 if ((u_int)fd >= fdp->fd_nfiles ||
3829                     (fp = fdp->fd_ofiles[fd]) == NULL)
3830                         error = EBADF;
3831                 else if (fp->f_vnode == NULL) {
3832                         fp = NULL;
3833                         error = EINVAL;
3834                 } else {
3835                         fhold(fp);
3836                         error = 0;
3837                 }
3838                 FILEDESC_UNLOCK(fdp);
3839         }
3840         *fpp = fp;
3841         return (error);
3842 }
3843
3844 /*
3845  * Get (NFS) file handle
3846  */
3847 #ifndef _SYS_SYSPROTO_H_
3848 struct lgetfh_args {
3849         char    *fname;
3850         fhandle_t *fhp;
3851 };
3852 #endif
3853 int
3854 lgetfh(td, uap)
3855         struct thread *td;
3856         register struct lgetfh_args *uap;
3857 {
3858         struct nameidata nd;
3859         fhandle_t fh;
3860         register struct vnode *vp;
3861         int vfslocked;
3862         int error;
3863
3864         error = suser(td);
3865         if (error)
3866                 return (error);
3867         NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE,
3868             UIO_USERSPACE, uap->fname, td);
3869         error = namei(&nd);
3870         if (error)
3871                 return (error);
3872         vfslocked = NDHASGIANT(&nd);
3873         NDFREE(&nd, NDF_ONLY_PNBUF);
3874         vp = nd.ni_vp;
3875         bzero(&fh, sizeof(fh));
3876         fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
3877         error = VFS_VPTOFH(vp, &fh.fh_fid);
3878         vput(vp);
3879         VFS_UNLOCK_GIANT(vfslocked);
3880         if (error)
3881                 return (error);
3882         error = copyout(&fh, uap->fhp, sizeof (fh));
3883         return (error);
3884 }
3885
3886 #ifndef _SYS_SYSPROTO_H_
3887 struct getfh_args {
3888         char    *fname;
3889         fhandle_t *fhp;
3890 };
3891 #endif
3892 int
3893 getfh(td, uap)
3894         struct thread *td;
3895         register struct getfh_args *uap;
3896 {
3897         struct nameidata nd;
3898         fhandle_t fh;
3899         register struct vnode *vp;
3900         int vfslocked;
3901         int error;
3902
3903         error = suser(td);
3904         if (error)
3905                 return (error);
3906         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE,
3907             UIO_USERSPACE, uap->fname, td);
3908         error = namei(&nd);
3909         if (error)
3910                 return (error);
3911         vfslocked = NDHASGIANT(&nd);
3912         NDFREE(&nd, NDF_ONLY_PNBUF);
3913         vp = nd.ni_vp;
3914         bzero(&fh, sizeof(fh));
3915         fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
3916         error = VFS_VPTOFH(vp, &fh.fh_fid);
3917         vput(vp);
3918         VFS_UNLOCK_GIANT(vfslocked);
3919         if (error)
3920                 return (error);
3921         error = copyout(&fh, uap->fhp, sizeof (fh));
3922         return (error);
3923 }
3924
3925 /*
3926  * syscall for the rpc.lockd to use to translate a NFS file handle into
3927  * an open descriptor.
3928  *
3929  * warning: do not remove the suser() call or this becomes one giant
3930  * security hole.
3931  *
3932  * MP SAFE
3933  */
3934 #ifndef _SYS_SYSPROTO_H_
3935 struct fhopen_args {
3936         const struct fhandle *u_fhp;
3937         int flags;
3938 };
3939 #endif
3940 int
3941 fhopen(td, uap)
3942         struct thread *td;
3943         struct fhopen_args /* {
3944                 const struct fhandle *u_fhp;
3945                 int flags;
3946         } */ *uap;
3947 {
3948         struct proc *p = td->td_proc;
3949         struct mount *mp;
3950         struct vnode *vp;
3951         struct fhandle fhp;
3952         struct vattr vat;
3953         struct vattr *vap = &vat;
3954         struct flock lf;
3955         struct file *fp;
3956         register struct filedesc *fdp = p->p_fd;
3957         int fmode, mode, error, type;
3958         struct file *nfp;
3959         int indx;
3960
3961         error = suser(td);
3962         if (error)
3963                 return (error);
3964         fmode = FFLAGS(uap->flags);
3965         /* why not allow a non-read/write open for our lockd? */
3966         if (((fmode & (FREAD | FWRITE)) == 0) || (fmode & O_CREAT))
3967                 return (EINVAL);
3968         error = copyin(uap->u_fhp, &fhp, sizeof(fhp));
3969         if (error)
3970                 return(error);
3971         /* find the mount point */
3972         mtx_lock(&Giant);
3973         mp = vfs_getvfs(&fhp.fh_fsid);
3974         if (mp == NULL) {
3975                 error = ESTALE;
3976                 goto out;
3977         }
3978         /* now give me my vnode, it gets returned to me locked */
3979         error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp);
3980         if (error)
3981                 goto out;
3982         /*
3983          * from now on we have to make sure not
3984          * to forget about the vnode
3985          * any error that causes an abort must vput(vp)
3986          * just set error = err and 'goto bad;'.
3987          */
3988
3989         /*
3990          * from vn_open
3991          */
3992         if (vp->v_type == VLNK) {
3993                 error = EMLINK;
3994                 goto bad;
3995         }
3996         if (vp->v_type == VSOCK) {
3997                 error = EOPNOTSUPP;
3998                 goto bad;
3999         }
4000         mode = 0;
4001         if (fmode & (FWRITE | O_TRUNC)) {
4002                 if (vp->v_type == VDIR) {
4003                         error = EISDIR;
4004                         goto bad;
4005                 }
4006                 error = vn_writechk(vp);
4007                 if (error)
4008                         goto bad;
4009                 mode |= VWRITE;
4010         }
4011         if (fmode & FREAD)
4012                 mode |= VREAD;
4013         if (fmode & O_APPEND)
4014                 mode |= VAPPEND;
4015 #ifdef MAC
4016         error = mac_check_vnode_open(td->td_ucred, vp, mode);
4017         if (error)
4018                 goto bad;
4019 #endif
4020         if (mode) {
4021                 error = VOP_ACCESS(vp, mode, td->td_ucred, td);
4022                 if (error)
4023                         goto bad;
4024         }
4025         if (fmode & O_TRUNC) {
4026                 VOP_UNLOCK(vp, 0, td);                          /* XXX */
4027                 if ((error = vn_start_write(NULL, &mp, V_WAIT | PCATCH)) != 0) {
4028                         vrele(vp);
4029                         goto out;
4030                 }
4031                 VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4032                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);       /* XXX */
4033 #ifdef MAC
4034                 /*
4035                  * We don't yet have fp->f_cred, so use td->td_ucred, which
4036                  * should be right.
4037                  */
4038                 error = mac_check_vnode_write(td->td_ucred, td->td_ucred, vp);
4039                 if (error == 0) {
4040 #endif
4041                         VATTR_NULL(vap);
4042                         vap->va_size = 0;
4043                         error = VOP_SETATTR(vp, vap, td->td_ucred, td);
4044 #ifdef MAC
4045                 }
4046 #endif
4047                 vn_finished_write(mp);
4048                 if (error)
4049                         goto bad;
4050         }
4051         error = VOP_OPEN(vp, fmode, td->td_ucred, td, -1);
4052         if (error)
4053                 goto bad;
4054
4055         if (fmode & FWRITE)
4056                 vp->v_writecount++;
4057
4058         /*
4059          * end of vn_open code
4060          */
4061
4062         if ((error = falloc(td, &nfp, &indx)) != 0) {
4063                 if (fmode & FWRITE)
4064                         vp->v_writecount--;
4065                 goto bad;
4066         }
4067         /* An extra reference on `nfp' has been held for us by falloc(). */
4068         fp = nfp;
4069
4070         nfp->f_vnode = vp;
4071         nfp->f_data = vp;
4072         nfp->f_flag = fmode & FMASK;
4073         nfp->f_ops = &vnops;
4074         nfp->f_type = DTYPE_VNODE;
4075         if (fmode & (O_EXLOCK | O_SHLOCK)) {
4076                 lf.l_whence = SEEK_SET;
4077                 lf.l_start = 0;
4078                 lf.l_len = 0;
4079                 if (fmode & O_EXLOCK)
4080                         lf.l_type = F_WRLCK;
4081                 else
4082                         lf.l_type = F_RDLCK;
4083                 type = F_FLOCK;
4084                 if ((fmode & FNONBLOCK) == 0)
4085                         type |= F_WAIT;
4086                 VOP_UNLOCK(vp, 0, td);
4087                 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf,
4088                             type)) != 0) {
4089                         /*
4090                          * The lock request failed.  Normally close the
4091                          * descriptor but handle the case where someone might
4092                          * have dup()d or close()d it when we weren't looking.
4093                          */
4094                         fdclose(fdp, fp, indx, td);
4095
4096                         /*
4097                          * release our private reference
4098                          */
4099                         fdrop(fp, td);
4100                         goto out;
4101                 }
4102                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4103                 fp->f_flag |= FHASLOCK;
4104         }
4105
4106         VOP_UNLOCK(vp, 0, td);
4107         fdrop(fp, td);
4108         mtx_unlock(&Giant);
4109         td->td_retval[0] = indx;
4110         return (0);
4111
4112 bad:
4113         vput(vp);
4114 out:
4115         mtx_unlock(&Giant);
4116         return (error);
4117 }
4118
4119 /*
4120  * Stat an (NFS) file handle.
4121  *
4122  * MP SAFE
4123  */
4124 #ifndef _SYS_SYSPROTO_H_
4125 struct fhstat_args {
4126         struct fhandle *u_fhp;
4127         struct stat *sb;
4128 };
4129 #endif
4130 int
4131 fhstat(td, uap)
4132         struct thread *td;
4133         register struct fhstat_args /* {
4134                 struct fhandle *u_fhp;
4135                 struct stat *sb;
4136         } */ *uap;
4137 {
4138         struct stat sb;
4139         fhandle_t fh;
4140         struct mount *mp;
4141         struct vnode *vp;
4142         int error;
4143
4144         error = suser(td);
4145         if (error)
4146                 return (error);
4147         error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
4148         if (error)
4149                 return (error);
4150         mtx_lock(&Giant);
4151         if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) {
4152                 mtx_unlock(&Giant);
4153                 return (ESTALE);
4154         }
4155         if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp))) {
4156                 mtx_unlock(&Giant);
4157                 return (error);
4158         }
4159         error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
4160         vput(vp);
4161         mtx_unlock(&Giant);
4162         if (error)
4163                 return (error);
4164         error = copyout(&sb, uap->sb, sizeof(sb));
4165         return (error);
4166 }
4167
4168 /*
4169  * Implement fstatfs() for (NFS) file handles.
4170  *
4171  * MP SAFE
4172  */
4173 #ifndef _SYS_SYSPROTO_H_
4174 struct fhstatfs_args {
4175         struct fhandle *u_fhp;
4176         struct statfs *buf;
4177 };
4178 #endif
4179 int
4180 fhstatfs(td, uap)
4181         struct thread *td;
4182         struct fhstatfs_args /* {
4183                 struct fhandle *u_fhp;
4184                 struct statfs *buf;
4185         } */ *uap;
4186 {
4187         struct statfs sf;
4188         fhandle_t fh;
4189         int error;
4190
4191         error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
4192         if (error)
4193                 return (error);
4194         error = kern_fhstatfs(td, fh, &sf);
4195         if (error)
4196                 return (error);
4197         return (copyout(&sf, uap->buf, sizeof(sf)));
4198 }
4199
4200 int
4201 kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf)
4202 {
4203         struct statfs *sp;
4204         struct mount *mp;
4205         struct vnode *vp;
4206         int error;
4207
4208         error = suser(td);
4209         if (error)
4210                 return (error);
4211         mtx_lock(&Giant);
4212         if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL) {
4213                 mtx_unlock(&Giant);
4214                 return (ESTALE);
4215         }
4216         error = VFS_FHTOVP(mp, &fh.fh_fid, &vp);
4217         if (error) {
4218                 mtx_unlock(&Giant);
4219                 return (error);
4220         }
4221         mp = vp->v_mount;
4222         sp = &mp->mnt_stat;
4223         vput(vp);
4224 #ifdef MAC
4225         error = mac_check_mount_stat(td->td_ucred, mp);
4226         if (error) {
4227                 mtx_unlock(&Giant);
4228                 return (error);
4229         }
4230 #endif
4231         /*
4232          * Set these in case the underlying filesystem fails to do so.
4233          */
4234         sp->f_version = STATFS_VERSION;
4235         sp->f_namemax = NAME_MAX;
4236         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
4237         error = VFS_STATFS(mp, sp, td);
4238         mtx_unlock(&Giant);
4239         if (error)
4240                 return (error);
4241         *buf = *sp;
4242         return (0);
4243 }
4244
4245 /*
4246  * Syscall to push extended attribute configuration information into the
4247  * VFS.  Accepts a path, which it converts to a mountpoint, as well as
4248  * a command (int cmd), and attribute name and misc data.  For now, the
4249  * attribute name is left in userspace for consumption by the VFS_op.
4250  * It will probably be changed to be copied into sysspace by the
4251  * syscall in the future, once issues with various consumers of the
4252  * attribute code have raised their hands.
4253  *
4254  * Currently this is used only by UFS Extended Attributes.
4255  */
4256 int
4257 extattrctl(td, uap)
4258         struct thread *td;
4259         struct extattrctl_args /* {
4260                 const char *path;
4261                 int cmd;
4262                 const char *filename;
4263                 int attrnamespace;
4264                 const char *attrname;
4265         } */ *uap;
4266 {
4267         struct vnode *filename_vp;
4268         struct nameidata nd;
4269         struct mount *mp, *mp_writable;
4270         char attrname[EXTATTR_MAXNAMELEN];
4271         int error;
4272
4273         /*
4274          * uap->attrname is not always defined.  We check again later when we
4275          * invoke the VFS call so as to pass in NULL there if needed.
4276          */
4277         if (uap->attrname != NULL) {
4278                 error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN,
4279                     NULL);
4280                 if (error)
4281                         return (error);
4282         }
4283
4284         /*
4285          * uap->filename is not always defined.  If it is, grab a vnode lock,
4286          * which VFS_EXTATTRCTL() will later release.
4287          */
4288         filename_vp = NULL;
4289         if (uap->filename != NULL) {
4290                 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
4291                     uap->filename, td);
4292                 error = namei(&nd);
4293                 if (error)
4294                         return (error);
4295                 filename_vp = nd.ni_vp;
4296                 NDFREE(&nd, NDF_NO_VP_RELE | NDF_NO_VP_UNLOCK);
4297         }
4298
4299         /* uap->path is always defined. */
4300         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
4301         error = namei(&nd);
4302         if (error) {
4303                 if (filename_vp != NULL)
4304                         vput(filename_vp);
4305                 return (error);
4306         }
4307         mp = nd.ni_vp->v_mount;
4308         error = vn_start_write(nd.ni_vp, &mp_writable, V_WAIT | PCATCH);
4309         NDFREE(&nd, 0);
4310         if (error) {
4311                 if (filename_vp != NULL)
4312                         vput(filename_vp);
4313                 return (error);
4314         }
4315
4316         error = VFS_EXTATTRCTL(mp, uap->cmd, filename_vp, uap->attrnamespace,
4317             uap->attrname != NULL ? attrname : NULL, td);
4318
4319         vn_finished_write(mp_writable);
4320         /*
4321          * VFS_EXTATTRCTL will have unlocked, but not de-ref'd,
4322          * filename_vp, so vrele it if it is defined.
4323          */
4324         if (filename_vp != NULL)
4325                 vrele(filename_vp);
4326         return (error);
4327 }
4328
4329 /*-
4330  * Set a named extended attribute on a file or directory
4331  *
4332  * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4333  *            kernelspace string pointer "attrname", userspace buffer
4334  *            pointer "data", buffer length "nbytes", thread "td".
4335  * Returns: 0 on success, an error number otherwise
4336  * Locks: none
4337  * References: vp must be a valid reference for the duration of the call
4338  */
4339 static int
4340 extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4341     void *data, size_t nbytes, struct thread *td)
4342 {
4343         struct mount *mp;
4344         struct uio auio;
4345         struct iovec aiov;
4346         ssize_t cnt;
4347         int error;
4348
4349         error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
4350         if (error)
4351                 return (error);
4352         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4353         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4354
4355         aiov.iov_base = data;
4356         aiov.iov_len = nbytes;
4357         auio.uio_iov = &aiov;
4358         auio.uio_iovcnt = 1;
4359         auio.uio_offset = 0;
4360         if (nbytes > INT_MAX) {
4361                 error = EINVAL;
4362                 goto done;
4363         }
4364         auio.uio_resid = nbytes;
4365         auio.uio_rw = UIO_WRITE;
4366         auio.uio_segflg = UIO_USERSPACE;
4367         auio.uio_td = td;
4368         cnt = nbytes;
4369
4370 #ifdef MAC
4371         error = mac_check_vnode_setextattr(td->td_ucred, vp, attrnamespace,
4372             attrname, &auio);
4373         if (error)
4374                 goto done;
4375 #endif
4376
4377         error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio,
4378             td->td_ucred, td);
4379         cnt -= auio.uio_resid;
4380         td->td_retval[0] = cnt;
4381
4382 done:
4383         VOP_UNLOCK(vp, 0, td);
4384         vn_finished_write(mp);
4385         return (error);
4386 }
4387
4388 int
4389 extattr_set_fd(td, uap)
4390         struct thread *td;
4391         struct extattr_set_fd_args /* {
4392                 int fd;
4393                 int attrnamespace;
4394                 const char *attrname;
4395                 void *data;
4396                 size_t nbytes;
4397         } */ *uap;
4398 {
4399         struct file *fp;
4400         char attrname[EXTATTR_MAXNAMELEN];
4401         int error;
4402
4403         error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4404         if (error)
4405                 return (error);
4406
4407         error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
4408         if (error)
4409                 return (error);
4410
4411         error = extattr_set_vp(fp->f_vnode, uap->attrnamespace,
4412             attrname, uap->data, uap->nbytes, td);
4413         fdrop(fp, td);
4414
4415         return (error);
4416 }
4417
4418 int
4419 extattr_set_file(td, uap)
4420         struct thread *td;
4421         struct extattr_set_file_args /* {
4422                 const char *path;
4423                 int attrnamespace;
4424                 const char *attrname;
4425                 void *data;
4426                 size_t nbytes;
4427         } */ *uap;
4428 {
4429         struct nameidata nd;
4430         char attrname[EXTATTR_MAXNAMELEN];
4431         int error;
4432
4433         error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4434         if (error)
4435                 return (error);
4436
4437         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
4438         error = namei(&nd);
4439         if (error)
4440                 return (error);
4441         NDFREE(&nd, NDF_ONLY_PNBUF);
4442
4443         error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname,
4444             uap->data, uap->nbytes, td);
4445
4446         vrele(nd.ni_vp);
4447         return (error);
4448 }
4449
4450 int
4451 extattr_set_link(td, uap)
4452         struct thread *td;
4453         struct extattr_set_link_args /* {
4454                 const char *path;
4455                 int attrnamespace;
4456                 const char *attrname;
4457                 void *data;
4458                 size_t nbytes;
4459         } */ *uap;
4460 {
4461         struct nameidata nd;
4462         char attrname[EXTATTR_MAXNAMELEN];
4463         int error;
4464
4465         error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4466         if (error)
4467                 return (error);
4468
4469         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
4470         error = namei(&nd);
4471         if (error)
4472                 return (error);
4473         NDFREE(&nd, NDF_ONLY_PNBUF);
4474
4475         error = extattr_set_vp(nd.ni_vp, uap->attrnamespace, attrname,
4476             uap->data, uap->nbytes, td);
4477
4478         vrele(nd.ni_vp);
4479         return (error);
4480 }
4481
4482 /*-
4483  * Get a named extended attribute on a file or directory
4484  *
4485  * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4486  *            kernelspace string pointer "attrname", userspace buffer
4487  *            pointer "data", buffer length "nbytes", thread "td".
4488  * Returns: 0 on success, an error number otherwise
4489  * Locks: none
4490  * References: vp must be a valid reference for the duration of the call
4491  */
4492 static int
4493 extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4494     void *data, size_t nbytes, struct thread *td)
4495 {
4496         struct uio auio, *auiop;
4497         struct iovec aiov;
4498         ssize_t cnt;
4499         size_t size, *sizep;
4500         int error;
4501
4502         VOP_LEASE(vp, td, td->td_ucred, LEASE_READ);
4503         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4504
4505         /*
4506          * Slightly unusual semantics: if the user provides a NULL data
4507          * pointer, they don't want to receive the data, just the
4508          * maximum read length.
4509          */
4510         auiop = NULL;
4511         sizep = NULL;
4512         cnt = 0;
4513         if (data != NULL) {
4514                 aiov.iov_base = data;
4515                 aiov.iov_len = nbytes;
4516                 auio.uio_iov = &aiov;
4517                 auio.uio_iovcnt = 1;
4518                 auio.uio_offset = 0;
4519                 if (nbytes > INT_MAX) {
4520                         error = EINVAL;
4521                         goto done;
4522                 }
4523                 auio.uio_resid = nbytes;
4524                 auio.uio_rw = UIO_READ;
4525                 auio.uio_segflg = UIO_USERSPACE;
4526                 auio.uio_td = td;
4527                 auiop = &auio;
4528                 cnt = nbytes;
4529         } else
4530                 sizep = &size;
4531
4532 #ifdef MAC
4533         error = mac_check_vnode_getextattr(td->td_ucred, vp, attrnamespace,
4534             attrname, &auio);
4535         if (error)
4536                 goto done;
4537 #endif
4538
4539         error = VOP_GETEXTATTR(vp, attrnamespace, attrname, auiop, sizep,
4540             td->td_ucred, td);
4541
4542         if (auiop != NULL) {
4543                 cnt -= auio.uio_resid;
4544                 td->td_retval[0] = cnt;
4545         } else
4546                 td->td_retval[0] = size;
4547
4548 done:
4549         VOP_UNLOCK(vp, 0, td);
4550         return (error);
4551 }
4552
4553 int
4554 extattr_get_fd(td, uap)
4555         struct thread *td;
4556         struct extattr_get_fd_args /* {
4557                 int fd;
4558                 int attrnamespace;
4559                 const char *attrname;
4560                 void *data;
4561                 size_t nbytes;
4562         } */ *uap;
4563 {
4564         struct file *fp;
4565         char attrname[EXTATTR_MAXNAMELEN];
4566         int error;
4567
4568         error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4569         if (error)
4570                 return (error);
4571
4572         error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
4573         if (error)
4574                 return (error);
4575
4576         error = extattr_get_vp(fp->f_vnode, uap->attrnamespace,
4577             attrname, uap->data, uap->nbytes, td);
4578
4579         fdrop(fp, td);
4580         return (error);
4581 }
4582
4583 int
4584 extattr_get_file(td, uap)
4585         struct thread *td;
4586         struct extattr_get_file_args /* {
4587                 const char *path;
4588                 int attrnamespace;
4589                 const char *attrname;
4590                 void *data;
4591                 size_t nbytes;
4592         } */ *uap;
4593 {
4594         struct nameidata nd;
4595         char attrname[EXTATTR_MAXNAMELEN];
4596         int error;
4597
4598         error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4599         if (error)
4600                 return (error);
4601
4602         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
4603         error = namei(&nd);
4604         if (error)
4605                 return (error);
4606         NDFREE(&nd, NDF_ONLY_PNBUF);
4607
4608         error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname,
4609             uap->data, uap->nbytes, td);
4610
4611         vrele(nd.ni_vp);
4612         return (error);
4613 }
4614
4615 int
4616 extattr_get_link(td, uap)
4617         struct thread *td;
4618         struct extattr_get_link_args /* {
4619                 const char *path;
4620                 int attrnamespace;
4621                 const char *attrname;
4622                 void *data;
4623                 size_t nbytes;
4624         } */ *uap;
4625 {
4626         struct nameidata nd;
4627         char attrname[EXTATTR_MAXNAMELEN];
4628         int error;
4629
4630         error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4631         if (error)
4632                 return (error);
4633
4634         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
4635         error = namei(&nd);
4636         if (error)
4637                 return (error);
4638         NDFREE(&nd, NDF_ONLY_PNBUF);
4639
4640         error = extattr_get_vp(nd.ni_vp, uap->attrnamespace, attrname,
4641             uap->data, uap->nbytes, td);
4642
4643         vrele(nd.ni_vp);
4644         return (error);
4645 }
4646
4647 /*
4648  * extattr_delete_vp(): Delete a named extended attribute on a file or
4649  *                      directory
4650  *
4651  * Arguments: unlocked vnode "vp", attribute namespace "attrnamespace",
4652  *            kernelspace string pointer "attrname", proc "p"
4653  * Returns: 0 on success, an error number otherwise
4654  * Locks: none
4655  * References: vp must be a valid reference for the duration of the call
4656  */
4657 static int
4658 extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname,
4659     struct thread *td)
4660 {
4661         struct mount *mp;
4662         int error;
4663
4664         error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
4665         if (error)
4666                 return (error);
4667         VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
4668         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4669
4670 #ifdef MAC
4671         error = mac_check_vnode_deleteextattr(td->td_ucred, vp, attrnamespace,
4672             attrname);
4673         if (error)
4674                 goto done;
4675 #endif
4676
4677         error = VOP_DELETEEXTATTR(vp, attrnamespace, attrname, td->td_ucred,
4678             td);
4679         if (error == EOPNOTSUPP)
4680                 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL,
4681                     td->td_ucred, td);
4682 #ifdef MAC
4683 done:
4684 #endif
4685         VOP_UNLOCK(vp, 0, td);
4686         vn_finished_write(mp);
4687         return (error);
4688 }
4689
4690 int
4691 extattr_delete_fd(td, uap)
4692         struct thread *td;
4693         struct extattr_delete_fd_args /* {
4694                 int fd;
4695                 int attrnamespace;
4696                 const char *attrname;
4697         } */ *uap;
4698 {
4699         struct file *fp;
4700         struct vnode *vp;
4701         char attrname[EXTATTR_MAXNAMELEN];
4702         int error;
4703
4704         error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4705         if (error)
4706                 return (error);
4707
4708         error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
4709         if (error)
4710                 return (error);
4711         vp = fp->f_vnode;
4712
4713         error = extattr_delete_vp(vp, uap->attrnamespace, attrname, td);
4714         fdrop(fp, td);
4715         return (error);
4716 }
4717
4718 int
4719 extattr_delete_file(td, uap)
4720         struct thread *td;
4721         struct extattr_delete_file_args /* {
4722                 const char *path;
4723                 int attrnamespace;
4724                 const char *attrname;
4725         } */ *uap;
4726 {
4727         struct nameidata nd;
4728         char attrname[EXTATTR_MAXNAMELEN];
4729         int error;
4730
4731         error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4732         if (error)
4733                 return(error);
4734
4735         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
4736         error = namei(&nd);
4737         if (error)
4738                 return(error);
4739         NDFREE(&nd, NDF_ONLY_PNBUF);
4740
4741         error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td);
4742         vrele(nd.ni_vp);
4743         return(error);
4744 }
4745
4746 int
4747 extattr_delete_link(td, uap)
4748         struct thread *td;
4749         struct extattr_delete_link_args /* {
4750                 const char *path;
4751                 int attrnamespace;
4752                 const char *attrname;
4753         } */ *uap;
4754 {
4755         struct nameidata nd;
4756         char attrname[EXTATTR_MAXNAMELEN];
4757         int error;
4758
4759         error = copyinstr(uap->attrname, attrname, EXTATTR_MAXNAMELEN, NULL);
4760         if (error)
4761                 return(error);
4762
4763         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
4764         error = namei(&nd);
4765         if (error)
4766                 return(error);
4767         NDFREE(&nd, NDF_ONLY_PNBUF);
4768
4769         error = extattr_delete_vp(nd.ni_vp, uap->attrnamespace, attrname, td);
4770         vrele(nd.ni_vp);
4771         return(error);
4772 }
4773
4774 /*-
4775  * Retrieve a list of extended attributes on a file or directory.
4776  *
4777  * Arguments: unlocked vnode "vp", attribute namespace 'attrnamespace",
4778  *            userspace buffer pointer "data", buffer length "nbytes",
4779  *            thread "td".
4780  * Returns: 0 on success, an error number otherwise
4781  * Locks: none
4782  * References: vp must be a valid reference for the duration of the call
4783  */
4784 static int
4785 extattr_list_vp(struct vnode *vp, int attrnamespace, void *data,
4786     size_t nbytes, struct thread *td)
4787 {
4788         struct uio auio, *auiop;
4789         size_t size, *sizep;
4790         struct iovec aiov;
4791         ssize_t cnt;
4792         int error;
4793
4794         VOP_LEASE(vp, td, td->td_ucred, LEASE_READ);
4795         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
4796
4797         auiop = NULL;
4798         sizep = NULL;
4799         cnt = 0;
4800         if (data != NULL) {
4801                 aiov.iov_base = data;
4802                 aiov.iov_len = nbytes;
4803                 auio.uio_iov = &aiov;
4804                 auio.uio_iovcnt = 1;
4805                 auio.uio_offset = 0;
4806                 if (nbytes > INT_MAX) {
4807                         error = EINVAL;
4808                         goto done;
4809                 }
4810                 auio.uio_resid = nbytes;
4811                 auio.uio_rw = UIO_READ;
4812                 auio.uio_segflg = UIO_USERSPACE;
4813                 auio.uio_td = td;
4814                 auiop = &auio;
4815                 cnt = nbytes;
4816         } else
4817                 sizep = &size;
4818
4819 #ifdef MAC
4820         error = mac_check_vnode_listextattr(td->td_ucred, vp, attrnamespace);
4821         if (error)
4822                 goto done;
4823 #endif
4824
4825         error = VOP_LISTEXTATTR(vp, attrnamespace, auiop, sizep,
4826             td->td_ucred, td);
4827
4828         if (auiop != NULL) {
4829                 cnt -= auio.uio_resid;
4830                 td->td_retval[0] = cnt;
4831         } else
4832                 td->td_retval[0] = size;
4833
4834 done:
4835         VOP_UNLOCK(vp, 0, td);
4836         return (error);
4837 }
4838
4839
4840 int
4841 extattr_list_fd(td, uap)
4842         struct thread *td;
4843         struct extattr_list_fd_args /* {
4844                 int fd;
4845                 int attrnamespace;
4846                 void *data;
4847                 size_t nbytes;
4848         } */ *uap;
4849 {
4850         struct file *fp;
4851         int error;
4852
4853         error = getvnode(td->td_proc->p_fd, uap->fd, &fp);
4854         if (error)
4855                 return (error);
4856
4857         error = extattr_list_vp(fp->f_vnode, uap->attrnamespace, uap->data,
4858             uap->nbytes, td);
4859
4860         fdrop(fp, td);
4861         return (error);
4862 }
4863
4864 int
4865 extattr_list_file(td, uap)
4866         struct thread*td;
4867         struct extattr_list_file_args /* {
4868                 const char *path;
4869                 int attrnamespace;
4870                 void *data;
4871                 size_t nbytes;
4872         } */ *uap;
4873 {
4874         struct nameidata nd;
4875         int error;
4876
4877         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, td);
4878         error = namei(&nd);
4879         if (error)
4880                 return (error);
4881         NDFREE(&nd, NDF_ONLY_PNBUF);
4882
4883         error = extattr_list_vp(nd.ni_vp, uap->attrnamespace, uap->data,
4884             uap->nbytes, td);
4885
4886         vrele(nd.ni_vp);
4887         return (error);
4888 }
4889
4890 int
4891 extattr_list_link(td, uap)
4892         struct thread*td;
4893         struct extattr_list_link_args /* {
4894                 const char *path;
4895                 int attrnamespace;
4896                 void *data;
4897                 size_t nbytes;
4898         } */ *uap;
4899 {
4900         struct nameidata nd;
4901         int error;
4902
4903         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, td);
4904         error = namei(&nd);
4905         if (error)
4906                 return (error);
4907         NDFREE(&nd, NDF_ONLY_PNBUF);
4908
4909         error = extattr_list_vp(nd.ni_vp, uap->attrnamespace, uap->data,
4910             uap->nbytes, td);
4911
4912         vrele(nd.ni_vp);
4913         return (error);
4914 }