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