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