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