]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - sys/ufs/ufs/ufs_vnops.c
MFC 232401:
[FreeBSD/stable/8.git] / sys / ufs / ufs / ufs_vnops.c
1 /*-
2  * Copyright (c) 1982, 1986, 1989, 1993, 1995
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  *      @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
35  */
36
37 #include <sys/cdefs.h>
38 __FBSDID("$FreeBSD$");
39
40 #include "opt_quota.h"
41 #include "opt_suiddir.h"
42 #include "opt_ufs.h"
43 #include "opt_ffs.h"
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/malloc.h>
48 #include <sys/namei.h>
49 #include <sys/kernel.h>
50 #include <sys/fcntl.h>
51 #include <sys/stat.h>
52 #include <sys/sysctl.h>
53 #include <sys/bio.h>
54 #include <sys/buf.h>
55 #include <sys/mount.h>
56 #include <sys/priv.h>
57 #include <sys/refcount.h>
58 #include <sys/unistd.h>
59 #include <sys/vnode.h>
60 #include <sys/dirent.h>
61 #include <sys/lockf.h>
62 #include <sys/conf.h>
63 #include <sys/acl.h>
64
65 #include <machine/mutex.h>
66
67 #include <security/mac/mac_framework.h>
68
69 #include <sys/file.h>           /* XXX */
70
71 #include <vm/vm.h>
72 #include <vm/vm_extern.h>
73
74 #include <fs/fifofs/fifo.h>
75
76 #include <ufs/ufs/acl.h>
77 #include <ufs/ufs/extattr.h>
78 #include <ufs/ufs/quota.h>
79 #include <ufs/ufs/inode.h>
80 #include <ufs/ufs/dir.h>
81 #include <ufs/ufs/ufsmount.h>
82 #include <ufs/ufs/ufs_extern.h>
83 #ifdef UFS_DIRHASH
84 #include <ufs/ufs/dirhash.h>
85 #endif
86 #ifdef UFS_GJOURNAL
87 #include <ufs/ufs/gjournal.h>
88 #endif
89
90 #include <ufs/ffs/ffs_extern.h>
91
92 static vop_accessx_t    ufs_accessx;
93 static int ufs_chmod(struct vnode *, int, struct ucred *, struct thread *);
94 static int ufs_chown(struct vnode *, uid_t, gid_t, struct ucred *, struct thread *);
95 static vop_close_t      ufs_close;
96 static vop_create_t     ufs_create;
97 static vop_getattr_t    ufs_getattr;
98 static vop_link_t       ufs_link;
99 static int ufs_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *);
100 static vop_markatime_t  ufs_markatime;
101 static vop_mkdir_t      ufs_mkdir;
102 static vop_mknod_t      ufs_mknod;
103 static vop_open_t       ufs_open;
104 static vop_pathconf_t   ufs_pathconf;
105 static vop_print_t      ufs_print;
106 static vop_readlink_t   ufs_readlink;
107 static vop_remove_t     ufs_remove;
108 static vop_rename_t     ufs_rename;
109 static vop_rmdir_t      ufs_rmdir;
110 static vop_setattr_t    ufs_setattr;
111 static vop_strategy_t   ufs_strategy;
112 static vop_symlink_t    ufs_symlink;
113 static vop_whiteout_t   ufs_whiteout;
114 static vop_close_t      ufsfifo_close;
115 static vop_kqfilter_t   ufsfifo_kqfilter;
116 static vop_pathconf_t   ufsfifo_pathconf;
117
118 SYSCTL_NODE(_vfs, OID_AUTO, ufs, CTLFLAG_RD, 0, "UFS filesystem");
119
120 /*
121  * A virgin directory (no blushing please).
122  */
123 static struct dirtemplate mastertemplate = {
124         0, 12, DT_DIR, 1, ".",
125         0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
126 };
127 static struct odirtemplate omastertemplate = {
128         0, 12, 1, ".",
129         0, DIRBLKSIZ - 12, 2, ".."
130 };
131
132 static void
133 ufs_itimes_locked(struct vnode *vp)
134 {
135         struct inode *ip;
136         struct timespec ts;
137
138         ASSERT_VI_LOCKED(vp, __func__);
139
140         ip = VTOI(vp);
141         if (UFS_RDONLY(ip))
142                 goto out;
143         if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0)
144                 return;
145
146         if ((vp->v_type == VBLK || vp->v_type == VCHR) && !DOINGSOFTDEP(vp))
147                 ip->i_flag |= IN_LAZYMOD;
148         else if (((vp->v_mount->mnt_kern_flag &
149                     (MNTK_SUSPENDED | MNTK_SUSPEND)) == 0) ||
150                     (ip->i_flag & (IN_CHANGE | IN_UPDATE)))
151                 ip->i_flag |= IN_MODIFIED;
152         else if (ip->i_flag & IN_ACCESS)
153                 ip->i_flag |= IN_LAZYACCESS;
154         vfs_timestamp(&ts);
155         if (ip->i_flag & IN_ACCESS) {
156                 DIP_SET(ip, i_atime, ts.tv_sec);
157                 DIP_SET(ip, i_atimensec, ts.tv_nsec);
158         }
159         if (ip->i_flag & IN_UPDATE) {
160                 DIP_SET(ip, i_mtime, ts.tv_sec);
161                 DIP_SET(ip, i_mtimensec, ts.tv_nsec);
162         }
163         if (ip->i_flag & IN_CHANGE) {
164                 DIP_SET(ip, i_ctime, ts.tv_sec);
165                 DIP_SET(ip, i_ctimensec, ts.tv_nsec);
166                 DIP_SET(ip, i_modrev, DIP(ip, i_modrev) + 1);
167         }
168
169  out:
170         ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE);
171 }
172
173 void
174 ufs_itimes(struct vnode *vp)
175 {
176
177         VI_LOCK(vp);
178         ufs_itimes_locked(vp);
179         VI_UNLOCK(vp);
180 }
181
182 /*
183  * Create a regular file
184  */
185 static int
186 ufs_create(ap)
187         struct vop_create_args /* {
188                 struct vnode *a_dvp;
189                 struct vnode **a_vpp;
190                 struct componentname *a_cnp;
191                 struct vattr *a_vap;
192         } */ *ap;
193 {
194         int error;
195
196         error =
197             ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode),
198             ap->a_dvp, ap->a_vpp, ap->a_cnp);
199         if (error)
200                 return (error);
201         return (0);
202 }
203
204 /*
205  * Mknod vnode call
206  */
207 /* ARGSUSED */
208 static int
209 ufs_mknod(ap)
210         struct vop_mknod_args /* {
211                 struct vnode *a_dvp;
212                 struct vnode **a_vpp;
213                 struct componentname *a_cnp;
214                 struct vattr *a_vap;
215         } */ *ap;
216 {
217         struct vattr *vap = ap->a_vap;
218         struct vnode **vpp = ap->a_vpp;
219         struct inode *ip;
220         ino_t ino;
221         int error;
222
223         error = ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
224             ap->a_dvp, vpp, ap->a_cnp);
225         if (error)
226                 return (error);
227         ip = VTOI(*vpp);
228         ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
229         if (vap->va_rdev != VNOVAL) {
230                 /*
231                  * Want to be able to use this to make badblock
232                  * inodes, so don't truncate the dev number.
233                  */
234                 DIP_SET(ip, i_rdev, vap->va_rdev);
235         }
236         /*
237          * Remove inode, then reload it through VFS_VGET so it is
238          * checked to see if it is an alias of an existing entry in
239          * the inode cache.  XXX I don't believe this is necessary now.
240          */
241         (*vpp)->v_type = VNON;
242         ino = ip->i_number;     /* Save this before vgone() invalidates ip. */
243         vgone(*vpp);
244         vput(*vpp);
245         error = VFS_VGET(ap->a_dvp->v_mount, ino, LK_EXCLUSIVE, vpp);
246         if (error) {
247                 *vpp = NULL;
248                 return (error);
249         }
250         return (0);
251 }
252
253 /*
254  * Open called.
255  */
256 /* ARGSUSED */
257 static int
258 ufs_open(struct vop_open_args *ap)
259 {
260         struct vnode *vp = ap->a_vp;
261         struct inode *ip;
262
263         if (vp->v_type == VCHR || vp->v_type == VBLK)
264                 return (EOPNOTSUPP);
265
266         ip = VTOI(vp);
267         /*
268          * Files marked append-only must be opened for appending.
269          */
270         if ((ip->i_flags & APPEND) &&
271             (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE)
272                 return (EPERM);
273         vnode_create_vobject(vp, DIP(ip, i_size), ap->a_td);
274         return (0);
275 }
276
277 /*
278  * Close called.
279  *
280  * Update the times on the inode.
281  */
282 /* ARGSUSED */
283 static int
284 ufs_close(ap)
285         struct vop_close_args /* {
286                 struct vnode *a_vp;
287                 int  a_fflag;
288                 struct ucred *a_cred;
289                 struct thread *a_td;
290         } */ *ap;
291 {
292         struct vnode *vp = ap->a_vp;
293         int usecount;
294
295         VI_LOCK(vp);
296         usecount = vp->v_usecount;
297         if (usecount > 1)
298                 ufs_itimes_locked(vp);
299         VI_UNLOCK(vp);
300         return (0);
301 }
302
303 static int
304 ufs_accessx(ap)
305         struct vop_accessx_args /* {
306                 struct vnode *a_vp;
307                 accmode_t a_accmode;
308                 struct ucred *a_cred;
309                 struct thread *a_td;
310         } */ *ap;
311 {
312         struct vnode *vp = ap->a_vp;
313         struct inode *ip = VTOI(vp);
314         accmode_t accmode = ap->a_accmode;
315         int error;
316 #ifdef QUOTA
317         int relocked;
318 #endif
319 #ifdef UFS_ACL
320         struct acl *acl;
321         acl_type_t type;
322 #endif
323
324         /*
325          * Disallow write attempts on read-only filesystems;
326          * unless the file is a socket, fifo, or a block or
327          * character device resident on the filesystem.
328          */
329         if (accmode & VMODIFY_PERMS) {
330                 switch (vp->v_type) {
331                 case VDIR:
332                 case VLNK:
333                 case VREG:
334                         if (vp->v_mount->mnt_flag & MNT_RDONLY)
335                                 return (EROFS);
336 #ifdef QUOTA
337                         /*
338                          * Inode is accounted in the quotas only if struct
339                          * dquot is attached to it. VOP_ACCESS() is called
340                          * from vn_open_cred() and provides a convenient
341                          * point to call getinoquota().
342                          */
343                         if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) {
344
345                                 /*
346                                  * Upgrade vnode lock, since getinoquota()
347                                  * requires exclusive lock to modify inode.
348                                  */
349                                 relocked = 1;
350                                 vhold(vp);
351                                 vn_lock(vp, LK_UPGRADE | LK_RETRY);
352                                 VI_LOCK(vp);
353                                 if (vp->v_iflag & VI_DOOMED) {
354                                         vdropl(vp);
355                                         error = ENOENT;
356                                         goto relock;
357                                 }
358                                 vdropl(vp);
359                         } else
360                                 relocked = 0;
361                         error = getinoquota(ip);
362 relock:
363                         if (relocked)
364                                 vn_lock(vp, LK_DOWNGRADE | LK_RETRY);
365                         if (error != 0)
366                                 return (error);
367 #endif
368                         break;
369                 default:
370                         break;
371                 }
372         }
373
374         /*
375          * If immutable bit set, nobody gets to write it.  "& ~VADMIN_PERMS"
376          * is here, because without it, * it would be impossible for the owner
377          * to remove the IMMUTABLE flag.
378          */
379         if ((accmode & (VMODIFY_PERMS & ~VADMIN_PERMS)) &&
380             (ip->i_flags & (IMMUTABLE | SF_SNAPSHOT)))
381                 return (EPERM);
382
383 #ifdef UFS_ACL
384         if ((vp->v_mount->mnt_flag & (MNT_ACLS | MNT_NFS4ACLS)) != 0) {
385                 if (vp->v_mount->mnt_flag & MNT_NFS4ACLS)
386                         type = ACL_TYPE_NFS4;
387                 else
388                         type = ACL_TYPE_ACCESS;
389
390                 acl = acl_alloc(M_WAITOK);
391                 if (type == ACL_TYPE_NFS4)
392                         error = ufs_getacl_nfs4_internal(vp, acl, ap->a_td);
393                 else
394                         error = VOP_GETACL(vp, type, acl, ap->a_cred, ap->a_td);
395                 switch (error) {
396                 case 0:
397                         if (type == ACL_TYPE_NFS4) {
398                                 error = vaccess_acl_nfs4(vp->v_type, ip->i_uid,
399                                     ip->i_gid, acl, accmode, ap->a_cred, NULL);
400                         } else {
401                                 error = vfs_unixify_accmode(&accmode);
402                                 if (error == 0)
403                                         error = vaccess_acl_posix1e(vp->v_type, ip->i_uid,
404                                             ip->i_gid, acl, accmode, ap->a_cred, NULL);
405                         }
406                         break;
407                 default:
408                         if (error != EOPNOTSUPP)
409                                 printf(
410 "ufs_accessx(): Error retrieving ACL on object (%d).\n",
411                                     error);
412                         /*
413                          * XXX: Fall back until debugged.  Should
414                          * eventually possibly log an error, and return
415                          * EPERM for safety.
416                          */
417                         error = vfs_unixify_accmode(&accmode);
418                         if (error == 0)
419                                 error = vaccess(vp->v_type, ip->i_mode, ip->i_uid,
420                                     ip->i_gid, accmode, ap->a_cred, NULL);
421                 }
422                 acl_free(acl);
423
424                 return (error);
425         }
426 #endif /* !UFS_ACL */
427         error = vfs_unixify_accmode(&accmode);
428         if (error == 0)
429                 error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid,
430                     accmode, ap->a_cred, NULL);
431         return (error);
432 }
433
434 /* ARGSUSED */
435 static int
436 ufs_getattr(ap)
437         struct vop_getattr_args /* {
438                 struct vnode *a_vp;
439                 struct vattr *a_vap;
440                 struct ucred *a_cred;
441         } */ *ap;
442 {
443         struct vnode *vp = ap->a_vp;
444         struct inode *ip = VTOI(vp);
445         struct vattr *vap = ap->a_vap;
446
447         VI_LOCK(vp);
448         ufs_itimes_locked(vp);
449         if (ip->i_ump->um_fstype == UFS1) {
450                 vap->va_atime.tv_sec = ip->i_din1->di_atime;
451                 vap->va_atime.tv_nsec = ip->i_din1->di_atimensec;
452         } else {
453                 vap->va_atime.tv_sec = ip->i_din2->di_atime;
454                 vap->va_atime.tv_nsec = ip->i_din2->di_atimensec;
455         }
456         VI_UNLOCK(vp);
457         /*
458          * Copy from inode table
459          */
460         vap->va_fsid = dev2udev(ip->i_dev);
461         vap->va_fileid = ip->i_number;
462         vap->va_mode = ip->i_mode & ~IFMT;
463         vap->va_nlink = ip->i_effnlink;
464         vap->va_uid = ip->i_uid;
465         vap->va_gid = ip->i_gid;
466         if (ip->i_ump->um_fstype == UFS1) {
467                 vap->va_rdev = ip->i_din1->di_rdev;
468                 vap->va_size = ip->i_din1->di_size;
469                 vap->va_mtime.tv_sec = ip->i_din1->di_mtime;
470                 vap->va_mtime.tv_nsec = ip->i_din1->di_mtimensec;
471                 vap->va_ctime.tv_sec = ip->i_din1->di_ctime;
472                 vap->va_ctime.tv_nsec = ip->i_din1->di_ctimensec;
473                 vap->va_bytes = dbtob((u_quad_t)ip->i_din1->di_blocks);
474                 vap->va_filerev = ip->i_din1->di_modrev;
475         } else {
476                 vap->va_rdev = ip->i_din2->di_rdev;
477                 vap->va_size = ip->i_din2->di_size;
478                 vap->va_mtime.tv_sec = ip->i_din2->di_mtime;
479                 vap->va_mtime.tv_nsec = ip->i_din2->di_mtimensec;
480                 vap->va_ctime.tv_sec = ip->i_din2->di_ctime;
481                 vap->va_ctime.tv_nsec = ip->i_din2->di_ctimensec;
482                 vap->va_birthtime.tv_sec = ip->i_din2->di_birthtime;
483                 vap->va_birthtime.tv_nsec = ip->i_din2->di_birthnsec;
484                 vap->va_bytes = dbtob((u_quad_t)ip->i_din2->di_blocks);
485                 vap->va_filerev = ip->i_din2->di_modrev;
486         }
487         vap->va_flags = ip->i_flags;
488         vap->va_gen = ip->i_gen;
489         vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
490         vap->va_type = IFTOVT(ip->i_mode);
491         return (0);
492 }
493
494 /*
495  * Set attribute vnode op. called from several syscalls
496  */
497 static int
498 ufs_setattr(ap)
499         struct vop_setattr_args /* {
500                 struct vnode *a_vp;
501                 struct vattr *a_vap;
502                 struct ucred *a_cred;
503         } */ *ap;
504 {
505         struct vattr *vap = ap->a_vap;
506         struct vnode *vp = ap->a_vp;
507         struct inode *ip = VTOI(vp);
508         struct ucred *cred = ap->a_cred;
509         struct thread *td = curthread;
510         int error;
511
512         /*
513          * Check for unsettable attributes.
514          */
515         if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
516             (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
517             (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
518             ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
519                 return (EINVAL);
520         }
521         if (vap->va_flags != VNOVAL) {
522                 if (vp->v_mount->mnt_flag & MNT_RDONLY)
523                         return (EROFS);
524                 /*
525                  * Callers may only modify the file flags on objects they
526                  * have VADMIN rights for.
527                  */
528                 if ((error = VOP_ACCESS(vp, VADMIN, cred, td)))
529                         return (error);
530                 /*
531                  * Unprivileged processes are not permitted to unset system
532                  * flags, or modify flags if any system flags are set.
533                  * Privileged non-jail processes may not modify system flags
534                  * if securelevel > 0 and any existing system flags are set.
535                  * Privileged jail processes behave like privileged non-jail
536                  * processes if the security.jail.chflags_allowed sysctl is
537                  * is non-zero; otherwise, they behave like unprivileged
538                  * processes.
539                  */
540                 if (!priv_check_cred(cred, PRIV_VFS_SYSFLAGS, 0)) {
541                         if (ip->i_flags
542                             & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) {
543                                 error = securelevel_gt(cred, 0);
544                                 if (error)
545                                         return (error);
546                         }
547                         /* Snapshot flag cannot be set or cleared */
548                         if (((vap->va_flags & SF_SNAPSHOT) != 0 &&
549                              (ip->i_flags & SF_SNAPSHOT) == 0) ||
550                             ((vap->va_flags & SF_SNAPSHOT) == 0 &&
551                              (ip->i_flags & SF_SNAPSHOT) != 0))
552                                 return (EPERM);
553                         ip->i_flags = vap->va_flags;
554                         DIP_SET(ip, i_flags, vap->va_flags);
555                 } else {
556                         if (ip->i_flags
557                             & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND) ||
558                             (vap->va_flags & UF_SETTABLE) != vap->va_flags)
559                                 return (EPERM);
560                         ip->i_flags &= SF_SETTABLE;
561                         ip->i_flags |= (vap->va_flags & UF_SETTABLE);
562                         DIP_SET(ip, i_flags, ip->i_flags);
563                 }
564                 ip->i_flag |= IN_CHANGE;
565                 error = UFS_UPDATE(vp, 0);
566                 if (vap->va_flags & (IMMUTABLE | APPEND))
567                         return (error);
568         }
569         if (ip->i_flags & (IMMUTABLE | APPEND))
570                 return (EPERM);
571         /*
572          * Go through the fields and update iff not VNOVAL.
573          */
574         if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
575                 if (vp->v_mount->mnt_flag & MNT_RDONLY)
576                         return (EROFS);
577                 if ((error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred,
578                     td)) != 0)
579                         return (error);
580         }
581         if (vap->va_size != VNOVAL) {
582                 /*
583                  * XXX most of the following special cases should be in
584                  * callers instead of in N filesystems.  The VDIR check
585                  * mostly already is.
586                  */
587                 switch (vp->v_type) {
588                 case VDIR:
589                         return (EISDIR);
590                 case VLNK:
591                 case VREG:
592                         /*
593                          * Truncation should have an effect in these cases.
594                          * Disallow it if the filesystem is read-only or
595                          * the file is being snapshotted.
596                          */
597                         if (vp->v_mount->mnt_flag & MNT_RDONLY)
598                                 return (EROFS);
599                         if ((ip->i_flags & SF_SNAPSHOT) != 0)
600                                 return (EPERM);
601                         break;
602                 default:
603                         /*
604                          * According to POSIX, the result is unspecified
605                          * for file types other than regular files,
606                          * directories and shared memory objects.  We
607                          * don't support shared memory objects in the file
608                          * system, and have dubious support for truncating
609                          * symlinks.  Just ignore the request in other cases.
610                          */
611                         return (0);
612                 }
613                 if ((error = UFS_TRUNCATE(vp, vap->va_size, IO_NORMAL,
614                     cred, td)) != 0)
615                         return (error);
616         }
617         if (vap->va_atime.tv_sec != VNOVAL ||
618             vap->va_mtime.tv_sec != VNOVAL ||
619             vap->va_birthtime.tv_sec != VNOVAL) {
620                 if (vp->v_mount->mnt_flag & MNT_RDONLY)
621                         return (EROFS);
622                 if ((ip->i_flags & SF_SNAPSHOT) != 0)
623                         return (EPERM);
624                 /*
625                  * From utimes(2):
626                  * If times is NULL, ... The caller must be the owner of
627                  * the file, have permission to write the file, or be the
628                  * super-user.
629                  * If times is non-NULL, ... The caller must be the owner of
630                  * the file or be the super-user.
631                  *
632                  * Possibly for historical reasons, try to use VADMIN in
633                  * preference to VWRITE for a NULL timestamp.  This means we
634                  * will return EACCES in preference to EPERM if neither
635                  * check succeeds.
636                  */
637                 if (vap->va_vaflags & VA_UTIMES_NULL) {
638                         /*
639                          * NFSv4.1, draft 21, 6.2.1.3.1, Discussion of Mask Attributes
640                          *
641                          * "A user having ACL_WRITE_DATA or ACL_WRITE_ATTRIBUTES
642                          * will be allowed to set the times [..] to the current
643                          * server time."
644                          *
645                          * XXX: Calling it four times seems a little excessive.
646                          */
647                         error = VOP_ACCESSX(vp, VWRITE_ATTRIBUTES, cred, td);
648                         if (error)
649                                 error = VOP_ACCESS(vp, VWRITE, cred, td);
650                 } else
651                         error = VOP_ACCESSX(vp, VWRITE_ATTRIBUTES, cred, td);
652                 if (error)
653                         return (error);
654                 if (vap->va_atime.tv_sec != VNOVAL)
655                         ip->i_flag |= IN_ACCESS;
656                 if (vap->va_mtime.tv_sec != VNOVAL)
657                         ip->i_flag |= IN_CHANGE | IN_UPDATE;
658                 if (vap->va_birthtime.tv_sec != VNOVAL &&
659                     ip->i_ump->um_fstype == UFS2)
660                         ip->i_flag |= IN_MODIFIED;
661                 ufs_itimes(vp);
662                 if (vap->va_atime.tv_sec != VNOVAL) {
663                         DIP_SET(ip, i_atime, vap->va_atime.tv_sec);
664                         DIP_SET(ip, i_atimensec, vap->va_atime.tv_nsec);
665                 }
666                 if (vap->va_mtime.tv_sec != VNOVAL) {
667                         DIP_SET(ip, i_mtime, vap->va_mtime.tv_sec);
668                         DIP_SET(ip, i_mtimensec, vap->va_mtime.tv_nsec);
669                 }
670                 if (vap->va_birthtime.tv_sec != VNOVAL &&
671                     ip->i_ump->um_fstype == UFS2) {
672                         ip->i_din2->di_birthtime = vap->va_birthtime.tv_sec;
673                         ip->i_din2->di_birthnsec = vap->va_birthtime.tv_nsec;
674                 }
675                 error = UFS_UPDATE(vp, 0);
676                 if (error)
677                         return (error);
678         }
679         error = 0;
680         if (vap->va_mode != (mode_t)VNOVAL) {
681                 if (vp->v_mount->mnt_flag & MNT_RDONLY)
682                         return (EROFS);
683                 if ((ip->i_flags & SF_SNAPSHOT) != 0 && (vap->va_mode &
684                    (S_IXUSR | S_IWUSR | S_IXGRP | S_IWGRP | S_IXOTH | S_IWOTH)))
685                         return (EPERM);
686                 error = ufs_chmod(vp, (int)vap->va_mode, cred, td);
687         }
688         return (error);
689 }
690
691 #ifdef UFS_ACL
692 static int
693 ufs_update_nfs4_acl_after_mode_change(struct vnode *vp, int mode,
694     int file_owner_id, struct ucred *cred, struct thread *td)
695 {
696         int error;
697         struct acl *aclp;
698
699         aclp = acl_alloc(M_WAITOK);
700         error = ufs_getacl_nfs4_internal(vp, aclp, td);
701         /*
702          * We don't have to handle EOPNOTSUPP here, as the filesystem claims
703          * it supports ACLs.
704          */
705         if (error)
706                 goto out;
707
708         acl_nfs4_sync_acl_from_mode(aclp, mode, file_owner_id);
709         error = ufs_setacl_nfs4_internal(vp, aclp, td);
710
711 out:
712         acl_free(aclp);
713         return (error);
714 }
715 #endif /* UFS_ACL */
716
717 /*
718  * Mark this file's access time for update for vfs_mark_atime().  This
719  * is called from execve() and mmap().
720  */
721 static int
722 ufs_markatime(ap)
723         struct vop_markatime_args /* {
724                 struct vnode *a_vp;
725         } */ *ap;
726 {
727         struct vnode *vp = ap->a_vp;
728         struct inode *ip = VTOI(vp);
729
730         VI_LOCK(vp);
731         ip->i_flag |= IN_ACCESS;
732         VI_UNLOCK(vp);
733         /*
734          * XXXKIB No UFS_UPDATE(ap->a_vp, 0) there.
735          */
736         return (0);
737 }
738
739 /*
740  * Change the mode on a file.
741  * Inode must be locked before calling.
742  */
743 static int
744 ufs_chmod(vp, mode, cred, td)
745         struct vnode *vp;
746         int mode;
747         struct ucred *cred;
748         struct thread *td;
749 {
750         struct inode *ip = VTOI(vp);
751         int error;
752
753         /*
754          * To modify the permissions on a file, must possess VADMIN
755          * for that file.
756          */
757         if ((error = VOP_ACCESSX(vp, VWRITE_ACL, cred, td)))
758                 return (error);
759         /*
760          * Privileged processes may set the sticky bit on non-directories,
761          * as well as set the setgid bit on a file with a group that the
762          * process is not a member of.  Both of these are allowed in
763          * jail(8).
764          */
765         if (vp->v_type != VDIR && (mode & S_ISTXT)) {
766                 if (priv_check_cred(cred, PRIV_VFS_STICKYFILE, 0))
767                         return (EFTYPE);
768         }
769         if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) {
770                 error = priv_check_cred(cred, PRIV_VFS_SETGID, 0);
771                 if (error)
772                         return (error);
773         }
774
775         /*
776          * Deny setting setuid if we are not the file owner.
777          */
778         if ((mode & ISUID) && ip->i_uid != cred->cr_uid) {
779                 error = priv_check_cred(cred, PRIV_VFS_ADMIN, 0);
780                 if (error)
781                         return (error);
782         }
783
784         ip->i_mode &= ~ALLPERMS;
785         ip->i_mode |= (mode & ALLPERMS);
786         DIP_SET(ip, i_mode, ip->i_mode);
787         ip->i_flag |= IN_CHANGE;
788 #ifdef UFS_ACL
789         if ((vp->v_mount->mnt_flag & MNT_NFS4ACLS) != 0)
790                 error = ufs_update_nfs4_acl_after_mode_change(vp, mode, ip->i_uid, cred, td);
791 #endif
792         if (error == 0 && (ip->i_flag & IN_CHANGE) != 0)
793                 error = UFS_UPDATE(vp, 0);
794
795         return (error);
796 }
797
798 /*
799  * Perform chown operation on inode ip;
800  * inode must be locked prior to call.
801  */
802 static int
803 ufs_chown(vp, uid, gid, cred, td)
804         struct vnode *vp;
805         uid_t uid;
806         gid_t gid;
807         struct ucred *cred;
808         struct thread *td;
809 {
810         struct inode *ip = VTOI(vp);
811         uid_t ouid;
812         gid_t ogid;
813         int error = 0;
814 #ifdef QUOTA
815         int i;
816         ufs2_daddr_t change;
817 #endif
818
819         if (uid == (uid_t)VNOVAL)
820                 uid = ip->i_uid;
821         if (gid == (gid_t)VNOVAL)
822                 gid = ip->i_gid;
823         /*
824          * To modify the ownership of a file, must possess VADMIN for that
825          * file.
826          */
827         if ((error = VOP_ACCESSX(vp, VWRITE_OWNER, cred, td)))
828                 return (error);
829         /*
830          * To change the owner of a file, or change the group of a file to a
831          * group of which we are not a member, the caller must have
832          * privilege.
833          */
834         if (((uid != ip->i_uid && uid != cred->cr_uid) || 
835             (gid != ip->i_gid && !groupmember(gid, cred))) &&
836             (error = priv_check_cred(cred, PRIV_VFS_CHOWN, 0)))
837                 return (error);
838         ogid = ip->i_gid;
839         ouid = ip->i_uid;
840 #ifdef QUOTA
841         if ((error = getinoquota(ip)) != 0)
842                 return (error);
843         if (ouid == uid) {
844                 dqrele(vp, ip->i_dquot[USRQUOTA]);
845                 ip->i_dquot[USRQUOTA] = NODQUOT;
846         }
847         if (ogid == gid) {
848                 dqrele(vp, ip->i_dquot[GRPQUOTA]);
849                 ip->i_dquot[GRPQUOTA] = NODQUOT;
850         }
851         change = DIP(ip, i_blocks);
852         (void) chkdq(ip, -change, cred, CHOWN);
853         (void) chkiq(ip, -1, cred, CHOWN);
854         for (i = 0; i < MAXQUOTAS; i++) {
855                 dqrele(vp, ip->i_dquot[i]);
856                 ip->i_dquot[i] = NODQUOT;
857         }
858 #endif
859         ip->i_gid = gid;
860         DIP_SET(ip, i_gid, gid);
861         ip->i_uid = uid;
862         DIP_SET(ip, i_uid, uid);
863 #ifdef QUOTA
864         if ((error = getinoquota(ip)) == 0) {
865                 if (ouid == uid) {
866                         dqrele(vp, ip->i_dquot[USRQUOTA]);
867                         ip->i_dquot[USRQUOTA] = NODQUOT;
868                 }
869                 if (ogid == gid) {
870                         dqrele(vp, ip->i_dquot[GRPQUOTA]);
871                         ip->i_dquot[GRPQUOTA] = NODQUOT;
872                 }
873                 if ((error = chkdq(ip, change, cred, CHOWN)) == 0) {
874                         if ((error = chkiq(ip, 1, cred, CHOWN)) == 0)
875                                 goto good;
876                         else
877                                 (void) chkdq(ip, -change, cred, CHOWN|FORCE);
878                 }
879                 for (i = 0; i < MAXQUOTAS; i++) {
880                         dqrele(vp, ip->i_dquot[i]);
881                         ip->i_dquot[i] = NODQUOT;
882                 }
883         }
884         ip->i_gid = ogid;
885         DIP_SET(ip, i_gid, ogid);
886         ip->i_uid = ouid;
887         DIP_SET(ip, i_uid, ouid);
888         if (getinoquota(ip) == 0) {
889                 if (ouid == uid) {
890                         dqrele(vp, ip->i_dquot[USRQUOTA]);
891                         ip->i_dquot[USRQUOTA] = NODQUOT;
892                 }
893                 if (ogid == gid) {
894                         dqrele(vp, ip->i_dquot[GRPQUOTA]);
895                         ip->i_dquot[GRPQUOTA] = NODQUOT;
896                 }
897                 (void) chkdq(ip, change, cred, FORCE|CHOWN);
898                 (void) chkiq(ip, 1, cred, FORCE|CHOWN);
899                 (void) getinoquota(ip);
900         }
901         return (error);
902 good:
903         if (getinoquota(ip))
904                 panic("ufs_chown: lost quota");
905 #endif /* QUOTA */
906         ip->i_flag |= IN_CHANGE;
907         if ((ip->i_mode & (ISUID | ISGID)) && (ouid != uid || ogid != gid)) {
908                 if (priv_check_cred(cred, PRIV_VFS_RETAINSUGID, 0)) {
909                         ip->i_mode &= ~(ISUID | ISGID);
910                         DIP_SET(ip, i_mode, ip->i_mode);
911                 }
912         }
913         error = UFS_UPDATE(vp, 0);
914         return (error);
915 }
916
917 static int
918 ufs_remove(ap)
919         struct vop_remove_args /* {
920                 struct vnode *a_dvp;
921                 struct vnode *a_vp;
922                 struct componentname *a_cnp;
923         } */ *ap;
924 {
925         struct inode *ip;
926         struct vnode *vp = ap->a_vp;
927         struct vnode *dvp = ap->a_dvp;
928         int error;
929         struct thread *td;
930
931         td = curthread;
932         ip = VTOI(vp);
933         if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
934             (VTOI(dvp)->i_flags & APPEND)) {
935                 error = EPERM;
936                 goto out;
937         }
938 #ifdef UFS_GJOURNAL
939         ufs_gjournal_orphan(vp);
940 #endif
941         error = ufs_dirremove(dvp, ip, ap->a_cnp->cn_flags, 0);
942         if (ip->i_nlink <= 0)
943                 vp->v_vflag |= VV_NOSYNC;
944         if ((ip->i_flags & SF_SNAPSHOT) != 0) {
945                 /*
946                  * Avoid deadlock where another thread is trying to
947                  * update the inodeblock for dvp and is waiting on
948                  * snaplk.  Temporary unlock the vnode lock for the
949                  * unlinked file and sync the directory.  This should
950                  * allow vput() of the directory to not block later on
951                  * while holding the snapshot vnode locked, assuming
952                  * that the directory hasn't been unlinked too.
953                  */
954                 VOP_UNLOCK(vp, 0);
955                 (void) VOP_FSYNC(dvp, MNT_WAIT, td);
956                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
957         }
958 out:
959         return (error);
960 }
961
962 /*
963  * link vnode call
964  */
965 static int
966 ufs_link(ap)
967         struct vop_link_args /* {
968                 struct vnode *a_tdvp;
969                 struct vnode *a_vp;
970                 struct componentname *a_cnp;
971         } */ *ap;
972 {
973         struct vnode *vp = ap->a_vp;
974         struct vnode *tdvp = ap->a_tdvp;
975         struct componentname *cnp = ap->a_cnp;
976         struct inode *ip;
977         struct direct newdir;
978         int error;
979
980 #ifdef INVARIANTS
981         if ((cnp->cn_flags & HASBUF) == 0)
982                 panic("ufs_link: no name");
983 #endif
984         if (tdvp->v_mount != vp->v_mount) {
985                 error = EXDEV;
986                 goto out;
987         }
988         ip = VTOI(vp);
989         if ((nlink_t)ip->i_nlink >= LINK_MAX) {
990                 error = EMLINK;
991                 goto out;
992         }
993         if (ip->i_flags & (IMMUTABLE | APPEND)) {
994                 error = EPERM;
995                 goto out;
996         }
997         ip->i_effnlink++;
998         ip->i_nlink++;
999         DIP_SET(ip, i_nlink, ip->i_nlink);
1000         ip->i_flag |= IN_CHANGE;
1001         if (DOINGSOFTDEP(vp))
1002                 softdep_change_linkcnt(ip);
1003         error = UFS_UPDATE(vp, !(DOINGSOFTDEP(vp) | DOINGASYNC(vp)));
1004         if (!error) {
1005                 ufs_makedirentry(ip, cnp, &newdir);
1006                 error = ufs_direnter(tdvp, vp, &newdir, cnp, NULL, 0);
1007         }
1008
1009         if (error) {
1010                 ip->i_effnlink--;
1011                 ip->i_nlink--;
1012                 DIP_SET(ip, i_nlink, ip->i_nlink);
1013                 ip->i_flag |= IN_CHANGE;
1014                 if (DOINGSOFTDEP(vp))
1015                         softdep_change_linkcnt(ip);
1016         }
1017 out:
1018         return (error);
1019 }
1020
1021 /*
1022  * whiteout vnode call
1023  */
1024 static int
1025 ufs_whiteout(ap)
1026         struct vop_whiteout_args /* {
1027                 struct vnode *a_dvp;
1028                 struct componentname *a_cnp;
1029                 int a_flags;
1030         } */ *ap;
1031 {
1032         struct vnode *dvp = ap->a_dvp;
1033         struct componentname *cnp = ap->a_cnp;
1034         struct direct newdir;
1035         int error = 0;
1036
1037         switch (ap->a_flags) {
1038         case LOOKUP:
1039                 /* 4.4 format directories support whiteout operations */
1040                 if (dvp->v_mount->mnt_maxsymlinklen > 0)
1041                         return (0);
1042                 return (EOPNOTSUPP);
1043
1044         case CREATE:
1045                 /* create a new directory whiteout */
1046 #ifdef INVARIANTS
1047                 if ((cnp->cn_flags & SAVENAME) == 0)
1048                         panic("ufs_whiteout: missing name");
1049                 if (dvp->v_mount->mnt_maxsymlinklen <= 0)
1050                         panic("ufs_whiteout: old format filesystem");
1051 #endif
1052
1053                 newdir.d_ino = WINO;
1054                 newdir.d_namlen = cnp->cn_namelen;
1055                 bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1);
1056                 newdir.d_type = DT_WHT;
1057                 error = ufs_direnter(dvp, NULL, &newdir, cnp, NULL, 0);
1058                 break;
1059
1060         case DELETE:
1061                 /* remove an existing directory whiteout */
1062 #ifdef INVARIANTS
1063                 if (dvp->v_mount->mnt_maxsymlinklen <= 0)
1064                         panic("ufs_whiteout: old format filesystem");
1065 #endif
1066
1067                 cnp->cn_flags &= ~DOWHITEOUT;
1068                 error = ufs_dirremove(dvp, NULL, cnp->cn_flags, 0);
1069                 break;
1070         default:
1071                 panic("ufs_whiteout: unknown op");
1072         }
1073         return (error);
1074 }
1075
1076 static volatile int rename_restarts;
1077 SYSCTL_INT(_vfs_ufs, OID_AUTO, rename_restarts, CTLFLAG_RD,
1078     __DEVOLATILE(int *, &rename_restarts), 0,
1079     "Times rename had to restart due to lock contention");
1080
1081 /*
1082  * Rename system call.
1083  *      rename("foo", "bar");
1084  * is essentially
1085  *      unlink("bar");
1086  *      link("foo", "bar");
1087  *      unlink("foo");
1088  * but ``atomically''.  Can't do full commit without saving state in the
1089  * inode on disk which isn't feasible at this time.  Best we can do is
1090  * always guarantee the target exists.
1091  *
1092  * Basic algorithm is:
1093  *
1094  * 1) Bump link count on source while we're linking it to the
1095  *    target.  This also ensure the inode won't be deleted out
1096  *    from underneath us while we work (it may be truncated by
1097  *    a concurrent `trunc' or `open' for creation).
1098  * 2) Link source to destination.  If destination already exists,
1099  *    delete it first.
1100  * 3) Unlink source reference to inode if still around. If a
1101  *    directory was moved and the parent of the destination
1102  *    is different from the source, patch the ".." entry in the
1103  *    directory.
1104  */
1105 static int
1106 ufs_rename(ap)
1107         struct vop_rename_args  /* {
1108                 struct vnode *a_fdvp;
1109                 struct vnode *a_fvp;
1110                 struct componentname *a_fcnp;
1111                 struct vnode *a_tdvp;
1112                 struct vnode *a_tvp;
1113                 struct componentname *a_tcnp;
1114         } */ *ap;
1115 {
1116         struct vnode *tvp = ap->a_tvp;
1117         struct vnode *tdvp = ap->a_tdvp;
1118         struct vnode *fvp = ap->a_fvp;
1119         struct vnode *fdvp = ap->a_fdvp;
1120         struct vnode *nvp;
1121         struct componentname *tcnp = ap->a_tcnp;
1122         struct componentname *fcnp = ap->a_fcnp;
1123         struct thread *td = fcnp->cn_thread;
1124         struct inode *fip, *tip, *tdp, *fdp;
1125         struct direct newdir;
1126         off_t endoff;
1127         int doingdirectory, newparent;
1128         int error = 0, ioflag;
1129         struct mount *mp;
1130         ino_t ino;
1131
1132 #ifdef INVARIANTS
1133         if ((tcnp->cn_flags & HASBUF) == 0 ||
1134             (fcnp->cn_flags & HASBUF) == 0)
1135                 panic("ufs_rename: no name");
1136 #endif
1137         endoff = 0;
1138         mp = tdvp->v_mount;
1139         VOP_UNLOCK(tdvp, 0);
1140         if (tvp && tvp != tdvp)
1141                 VOP_UNLOCK(tvp, 0);
1142         /*
1143          * Check for cross-device rename.
1144          */
1145         if ((fvp->v_mount != tdvp->v_mount) ||
1146             (tvp && (fvp->v_mount != tvp->v_mount))) {
1147                 error = EXDEV;
1148                 mp = NULL;
1149                 goto releout;
1150         }
1151         error = vfs_busy(mp, 0);
1152         if (error) {
1153                 mp = NULL;
1154                 goto releout;
1155         }
1156 relock:
1157         /* 
1158          * We need to acquire 2 to 4 locks depending on whether tvp is NULL
1159          * and fdvp and tdvp are the same directory.  Subsequently we need
1160          * to double-check all paths and in the directory rename case we
1161          * need to verify that we are not creating a directory loop.  To
1162          * handle this we acquire all but fdvp using non-blocking
1163          * acquisitions.  If we fail to acquire any lock in the path we will
1164          * drop all held locks, acquire the new lock in a blocking fashion,
1165          * and then release it and restart the rename.  This acquire/release
1166          * step ensures that we do not spin on a lock waiting for release.
1167          */
1168         error = vn_lock(fdvp, LK_EXCLUSIVE);
1169         if (error)
1170                 goto releout;
1171         if (vn_lock(tdvp, LK_EXCLUSIVE | LK_NOWAIT) != 0) {
1172                 VOP_UNLOCK(fdvp, 0);
1173                 error = vn_lock(tdvp, LK_EXCLUSIVE);
1174                 if (error)
1175                         goto releout;
1176                 VOP_UNLOCK(tdvp, 0);
1177                 atomic_add_int(&rename_restarts, 1);
1178                 goto relock;
1179         }
1180         /*
1181          * Re-resolve fvp to be certain it still exists and fetch the
1182          * correct vnode.
1183          */
1184         error = ufs_lookup_ino(fdvp, NULL, fcnp, &ino);
1185         if (error) {
1186                 VOP_UNLOCK(fdvp, 0);
1187                 VOP_UNLOCK(tdvp, 0);
1188                 goto releout;
1189         }
1190         error = VFS_VGET(mp, ino, LK_EXCLUSIVE | LK_NOWAIT, &nvp);
1191         if (error) {
1192                 VOP_UNLOCK(fdvp, 0);
1193                 VOP_UNLOCK(tdvp, 0);
1194                 if (error != EBUSY)
1195                         goto releout;
1196                 error = VFS_VGET(mp, ino, LK_EXCLUSIVE, &nvp);
1197                 if (error != 0)
1198                         goto releout;
1199                 VOP_UNLOCK(nvp, 0);
1200                 vrele(fvp);
1201                 fvp = nvp;
1202                 atomic_add_int(&rename_restarts, 1);
1203                 goto relock;
1204         }
1205         vrele(fvp);
1206         fvp = nvp;
1207         /*
1208          * Re-resolve tvp and acquire the vnode lock if present.
1209          */
1210         error = ufs_lookup_ino(tdvp, NULL, tcnp, &ino);
1211         if (error != 0 && error != EJUSTRETURN) {
1212                 VOP_UNLOCK(fdvp, 0);
1213                 VOP_UNLOCK(tdvp, 0);
1214                 VOP_UNLOCK(fvp, 0);
1215                 goto releout;
1216         }
1217         /*
1218          * If tvp disappeared we just carry on.
1219          */
1220         if (error == EJUSTRETURN && tvp != NULL) {
1221                 vrele(tvp);
1222                 tvp = NULL;
1223         }
1224         /*
1225          * Get the tvp ino if the lookup succeeded.  We may have to restart
1226          * if the non-blocking acquire fails.
1227          */
1228         if (error == 0) {
1229                 nvp = NULL;
1230                 error = VFS_VGET(mp, ino, LK_EXCLUSIVE | LK_NOWAIT, &nvp);
1231                 if (tvp)
1232                         vrele(tvp);
1233                 tvp = nvp;
1234                 if (error) {
1235                         VOP_UNLOCK(fdvp, 0);
1236                         VOP_UNLOCK(tdvp, 0);
1237                         VOP_UNLOCK(fvp, 0);
1238                         if (error != EBUSY)
1239                                 goto releout;
1240                         error = VFS_VGET(mp, ino, LK_EXCLUSIVE, &nvp);
1241                         if (error != 0)
1242                                 goto releout;
1243                         VOP_UNLOCK(nvp, 0);
1244                         atomic_add_int(&rename_restarts, 1);
1245                         goto relock;
1246                 }
1247         }
1248         fdp = VTOI(fdvp);
1249         fip = VTOI(fvp);
1250         tdp = VTOI(tdvp);
1251         tip = NULL;
1252         if (tvp)
1253                 tip = VTOI(tvp);
1254         if (tvp && ((VTOI(tvp)->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
1255             (VTOI(tdvp)->i_flags & APPEND))) {
1256                 error = EPERM;
1257                 goto unlockout;
1258         }
1259         /*
1260          * Renaming a file to itself has no effect.  The upper layers should
1261          * not call us in that case.  However, things could change after
1262          * we drop the locks above.
1263          */
1264         if (fvp == tvp) {
1265                 error = 0;
1266                 goto unlockout;
1267         }
1268         doingdirectory = 0;
1269         newparent = 0;
1270         ino = fip->i_number;
1271         if (fip->i_nlink >= LINK_MAX) {
1272                 error = EMLINK;
1273                 goto unlockout;
1274         }
1275         if ((fip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))
1276             || (fdp->i_flags & APPEND)) {
1277                 error = EPERM;
1278                 goto unlockout;
1279         }
1280         if ((fip->i_mode & IFMT) == IFDIR) {
1281                 /*
1282                  * Avoid ".", "..", and aliases of "." for obvious reasons.
1283                  */
1284                 if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
1285                     fdp == fip ||
1286                     (fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT) {
1287                         error = EINVAL;
1288                         goto unlockout;
1289                 }
1290                 if (fdp->i_number != tdp->i_number)
1291                         newparent = tdp->i_number;
1292                 doingdirectory = 1;
1293         }
1294         if ((fvp->v_type == VDIR && fvp->v_mountedhere != NULL) ||
1295             (tvp != NULL && tvp->v_type == VDIR &&
1296             tvp->v_mountedhere != NULL)) {
1297                 error = EXDEV;
1298                 goto unlockout;
1299         }
1300
1301         /*
1302          * If ".." must be changed (ie the directory gets a new
1303          * parent) then the source directory must not be in the
1304          * directory hierarchy above the target, as this would
1305          * orphan everything below the source directory. Also
1306          * the user must have write permission in the source so
1307          * as to be able to change "..".
1308          */
1309         if (doingdirectory && newparent) {
1310                 error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_thread);
1311                 if (error)
1312                         goto unlockout;
1313                 error = ufs_checkpath(ino, fdp->i_number, tdp, tcnp->cn_cred,
1314                     &ino);
1315                 /*
1316                  * We encountered a lock that we have to wait for.  Unlock
1317                  * everything else and VGET before restarting.
1318                  */
1319                 if (ino) {
1320                         VOP_UNLOCK(fdvp, 0);
1321                         VOP_UNLOCK(fvp, 0);
1322                         VOP_UNLOCK(tdvp, 0);
1323                         if (tvp)
1324                                 VOP_UNLOCK(tvp, 0);
1325                         error = VFS_VGET(mp, ino, LK_SHARED, &nvp);
1326                         if (error == 0)
1327                                 vput(nvp);
1328                         atomic_add_int(&rename_restarts, 1);
1329                         goto relock;
1330                 }
1331                 if (error)
1332                         goto unlockout;
1333                 if ((tcnp->cn_flags & SAVESTART) == 0)
1334                         panic("ufs_rename: lost to startdir");
1335         }
1336         if (fip->i_effnlink == 0 || fdp->i_effnlink == 0 ||
1337             tdp->i_effnlink == 0)
1338                 panic("Bad effnlink fip %p, fdp %p, tdp %p", fip, fdp, tdp);
1339
1340         /*
1341          * 1) Bump link count while we're moving stuff
1342          *    around.  If we crash somewhere before
1343          *    completing our work, the link count
1344          *    may be wrong, but correctable.
1345          */
1346         fip->i_effnlink++;
1347         fip->i_nlink++;
1348         DIP_SET(fip, i_nlink, fip->i_nlink);
1349         fip->i_flag |= IN_CHANGE;
1350         if (DOINGSOFTDEP(fvp))
1351                 softdep_change_linkcnt(fip);
1352         error = UFS_UPDATE(fvp, !(DOINGSOFTDEP(fvp) | DOINGASYNC(fvp)));
1353         if (error)
1354                 goto bad;
1355
1356         /*
1357          * 2) If target doesn't exist, link the target
1358          *    to the source and unlink the source.
1359          *    Otherwise, rewrite the target directory
1360          *    entry to reference the source inode and
1361          *    expunge the original entry's existence.
1362          */
1363         if (tip == NULL) {
1364                 if (tdp->i_dev != fip->i_dev)
1365                         panic("ufs_rename: EXDEV");
1366                 if (doingdirectory && newparent) {
1367                         /*
1368                          * Account for ".." in new directory.
1369                          * When source and destination have the same
1370                          * parent we don't adjust the link count.  The
1371                          * actual link modification is completed when
1372                          * .. is rewritten below.
1373                          */
1374                         if ((nlink_t)tdp->i_nlink >= LINK_MAX) {
1375                                 error = EMLINK;
1376                                 goto bad;
1377                         }
1378                 }
1379                 ufs_makedirentry(fip, tcnp, &newdir);
1380                 error = ufs_direnter(tdvp, NULL, &newdir, tcnp, NULL, 1);
1381                 if (error)
1382                         goto bad;
1383                 /* Setup tdvp for directory compaction if needed. */
1384                 if (tdp->i_count && tdp->i_endoff &&
1385                     tdp->i_endoff < tdp->i_size)
1386                         endoff = tdp->i_endoff;
1387         } else {
1388                 if (tip->i_dev != tdp->i_dev || tip->i_dev != fip->i_dev)
1389                         panic("ufs_rename: EXDEV");
1390                 /*
1391                  * Short circuit rename(foo, foo).
1392                  */
1393                 if (tip->i_number == fip->i_number)
1394                         panic("ufs_rename: same file");
1395                 /*
1396                  * If the parent directory is "sticky", then the caller
1397                  * must possess VADMIN for the parent directory, or the
1398                  * destination of the rename.  This implements append-only
1399                  * directories.
1400                  */
1401                 if ((tdp->i_mode & S_ISTXT) &&
1402                     VOP_ACCESS(tdvp, VADMIN, tcnp->cn_cred, td) &&
1403                     VOP_ACCESS(tvp, VADMIN, tcnp->cn_cred, td)) {
1404                         error = EPERM;
1405                         goto bad;
1406                 }
1407                 /*
1408                  * Target must be empty if a directory and have no links
1409                  * to it. Also, ensure source and target are compatible
1410                  * (both directories, or both not directories).
1411                  */
1412                 if ((tip->i_mode & IFMT) == IFDIR) {
1413                         if ((tip->i_effnlink > 2) ||
1414                             !ufs_dirempty(tip, tdp->i_number, tcnp->cn_cred)) {
1415                                 error = ENOTEMPTY;
1416                                 goto bad;
1417                         }
1418                         if (!doingdirectory) {
1419                                 error = ENOTDIR;
1420                                 goto bad;
1421                         }
1422                         cache_purge(tdvp);
1423                 } else if (doingdirectory) {
1424                         error = EISDIR;
1425                         goto bad;
1426                 }
1427                 if (doingdirectory) {
1428                         if (!newparent) {
1429                                 tdp->i_effnlink--;
1430                                 if (DOINGSOFTDEP(tdvp))
1431                                         softdep_change_linkcnt(tdp);
1432                         }
1433                         tip->i_effnlink--;
1434                         if (DOINGSOFTDEP(tvp))
1435                                 softdep_change_linkcnt(tip);
1436                 }
1437                 error = ufs_dirrewrite(tdp, tip, fip->i_number,
1438                     IFTODT(fip->i_mode),
1439                     (doingdirectory && newparent) ? newparent : doingdirectory);
1440                 if (error) {
1441                         if (doingdirectory) {
1442                                 if (!newparent) {
1443                                         tdp->i_effnlink++;
1444                                         if (DOINGSOFTDEP(tdvp))
1445                                                 softdep_change_linkcnt(tdp);
1446                                 }
1447                                 tip->i_effnlink++;
1448                                 if (DOINGSOFTDEP(tvp))
1449                                         softdep_change_linkcnt(tip);
1450                         }
1451                 }
1452                 if (doingdirectory && !DOINGSOFTDEP(tvp)) {
1453                         /*
1454                          * Truncate inode. The only stuff left in the directory
1455                          * is "." and "..". The "." reference is inconsequential
1456                          * since we are quashing it. We have removed the "."
1457                          * reference and the reference in the parent directory,
1458                          * but there may be other hard links. The soft
1459                          * dependency code will arrange to do these operations
1460                          * after the parent directory entry has been deleted on
1461                          * disk, so when running with that code we avoid doing
1462                          * them now.
1463                          */
1464                         if (!newparent) {
1465                                 tdp->i_nlink--;
1466                                 DIP_SET(tdp, i_nlink, tdp->i_nlink);
1467                                 tdp->i_flag |= IN_CHANGE;
1468                         }
1469                         tip->i_nlink--;
1470                         DIP_SET(tip, i_nlink, tip->i_nlink);
1471                         tip->i_flag |= IN_CHANGE;
1472                         ioflag = IO_NORMAL;
1473                         if (!DOINGASYNC(tvp))
1474                                 ioflag |= IO_SYNC;
1475                         /* Don't go to bad here as the new link exists. */
1476                         if ((error = UFS_TRUNCATE(tvp, (off_t)0, ioflag,
1477                             tcnp->cn_cred, tcnp->cn_thread)) != 0)
1478                                 goto unlockout;
1479                 }
1480         }
1481
1482         /*
1483          * 3) Unlink the source.  We have to resolve the path again to
1484          * fixup the directory offset and count for ufs_dirremove.
1485          */
1486         if (fdvp == tdvp) {
1487                 error = ufs_lookup_ino(fdvp, NULL, fcnp, &ino);
1488                 if (error)
1489                         panic("ufs_rename: from entry went away!");
1490                 if (ino != fip->i_number)
1491                         panic("ufs_rename: ino mismatch %d != %d\n", ino,
1492                             fip->i_number);
1493         }
1494         /*
1495          * If the source is a directory with a
1496          * new parent, the link count of the old
1497          * parent directory must be decremented
1498          * and ".." set to point to the new parent.
1499          */
1500         if (doingdirectory && newparent) {
1501                 /*
1502                  * If tip exists we simply use its link, otherwise we must
1503                  * add a new one.
1504                  */
1505                 if (tip == NULL) {
1506                         tdp->i_effnlink++;
1507                         tdp->i_nlink++;
1508                         DIP_SET(tdp, i_nlink, tdp->i_nlink);
1509                         tdp->i_flag |= IN_CHANGE;
1510                         if (DOINGSOFTDEP(tdvp))
1511                                 softdep_change_linkcnt(tdp);
1512                         error = UFS_UPDATE(tdvp, !(DOINGSOFTDEP(tdvp) |
1513                                                    DOINGASYNC(tdvp)));
1514                         /* Don't go to bad here as the new link exists. */
1515                         if (error)
1516                                 goto unlockout;
1517                 }
1518                 fip->i_offset = mastertemplate.dot_reclen;
1519                 ufs_dirrewrite(fip, fdp, newparent, DT_DIR, 0);
1520                 cache_purge(fdvp);
1521         }
1522         error = ufs_dirremove(fdvp, fip, fcnp->cn_flags, 0);
1523         /*
1524          * The kern_renameat() looks up the fvp using the DELETE flag, which
1525          * causes the removal of the name cache entry for fvp.
1526          * As the relookup of the fvp is done in two steps:
1527          * ufs_lookup_ino() and then VFS_VGET(), another thread might do a
1528          * normal lookup of the from name just before the VFS_VGET() call,
1529          * causing the cache entry to be re-instantiated.
1530          *
1531          * The same issue also applies to tvp if it exists as
1532          * otherwise we may have a stale name cache entry for the new
1533          * name that references the old i-node if it has other links
1534          * or open file descriptors.
1535          */
1536         cache_purge(fvp);
1537         if (tvp)
1538                 cache_purge(tvp);
1539
1540 unlockout:
1541         vput(fdvp);
1542         vput(fvp);
1543         if (tvp)
1544                 vput(tvp);
1545         /*
1546          * If compaction or fsync was requested do it now that other locks
1547          * are no longer needed.
1548          */
1549         if (error == 0 && endoff != 0) {
1550 #ifdef UFS_DIRHASH
1551                 if (tdp->i_dirhash != NULL)
1552                         ufsdirhash_dirtrunc(tdp, endoff);
1553 #endif
1554                 UFS_TRUNCATE(tdvp, endoff, IO_NORMAL | IO_SYNC, tcnp->cn_cred,
1555                     td);
1556         }
1557         if (error == 0 && tdp->i_flag & IN_NEEDSYNC)
1558                 error = VOP_FSYNC(tdvp, MNT_WAIT, td);
1559         vput(tdvp);
1560         if (mp)
1561                 vfs_unbusy(mp);
1562         return (error);
1563
1564 bad:
1565         fip->i_effnlink--;
1566         fip->i_nlink--;
1567         DIP_SET(fip, i_nlink, fip->i_nlink);
1568         fip->i_flag |= IN_CHANGE;
1569         if (DOINGSOFTDEP(fvp))
1570                 softdep_change_linkcnt(fip);
1571         goto unlockout;
1572
1573 releout:
1574         vrele(fdvp);
1575         vrele(fvp);
1576         vrele(tdvp);
1577         if (tvp)
1578                 vrele(tvp);
1579         if (mp)
1580                 vfs_unbusy(mp);
1581
1582         return (error);
1583 }
1584
1585 #ifdef UFS_ACL
1586 static int
1587 ufs_do_posix1e_acl_inheritance_dir(struct vnode *dvp, struct vnode *tvp,
1588     mode_t dmode, struct ucred *cred, struct thread *td)
1589 {
1590         int error;
1591         struct inode *ip = VTOI(tvp);
1592         struct acl *dacl, *acl;
1593
1594         acl = acl_alloc(M_WAITOK);
1595         dacl = acl_alloc(M_WAITOK);
1596
1597         /*
1598          * Retrieve default ACL from parent, if any.
1599          */
1600         error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cred, td);
1601         switch (error) {
1602         case 0:
1603                 /*
1604                  * Retrieved a default ACL, so merge mode and ACL if
1605                  * necessary.  If the ACL is empty, fall through to
1606                  * the "not defined or available" case.
1607                  */
1608                 if (acl->acl_cnt != 0) {
1609                         dmode = acl_posix1e_newfilemode(dmode, acl);
1610                         ip->i_mode = dmode;
1611                         DIP_SET(ip, i_mode, dmode);
1612                         *dacl = *acl;
1613                         ufs_sync_acl_from_inode(ip, acl);
1614                         break;
1615                 }
1616                 /* FALLTHROUGH */
1617
1618         case EOPNOTSUPP:
1619                 /*
1620                  * Just use the mode as-is.
1621                  */
1622                 ip->i_mode = dmode;
1623                 DIP_SET(ip, i_mode, dmode);
1624                 error = 0;
1625                 goto out;
1626         
1627         default:
1628                 goto out;
1629         }
1630
1631         /*
1632          * XXX: If we abort now, will Soft Updates notify the extattr
1633          * code that the EAs for the file need to be released?
1634          */
1635         error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cred, td);
1636         if (error == 0)
1637                 error = VOP_SETACL(tvp, ACL_TYPE_DEFAULT, dacl, cred, td);
1638         switch (error) {
1639         case 0:
1640                 break;
1641
1642         case EOPNOTSUPP:
1643                 /*
1644                  * XXX: This should not happen, as EOPNOTSUPP above
1645                  * was supposed to free acl.
1646                  */
1647                 printf("ufs_mkdir: VOP_GETACL() but no VOP_SETACL()\n");
1648                 /*
1649                 panic("ufs_mkdir: VOP_GETACL() but no VOP_SETACL()");
1650                  */
1651                 break;
1652
1653         default:
1654                 goto out;
1655         }
1656
1657 out:
1658         acl_free(acl);
1659         acl_free(dacl);
1660
1661         return (error);
1662 }
1663
1664 static int
1665 ufs_do_posix1e_acl_inheritance_file(struct vnode *dvp, struct vnode *tvp,
1666     mode_t mode, struct ucred *cred, struct thread *td)
1667 {
1668         int error;
1669         struct inode *ip = VTOI(tvp);
1670         struct acl *acl;
1671
1672         acl = acl_alloc(M_WAITOK);
1673
1674         /*
1675          * Retrieve default ACL for parent, if any.
1676          */
1677         error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cred, td);
1678         switch (error) {
1679         case 0:
1680                 /*
1681                  * Retrieved a default ACL, so merge mode and ACL if
1682                  * necessary.
1683                  */
1684                 if (acl->acl_cnt != 0) {
1685                         /*
1686                          * Two possible ways for default ACL to not
1687                          * be present.  First, the EA can be
1688                          * undefined, or second, the default ACL can
1689                          * be blank.  If it's blank, fall through to
1690                          * the it's not defined case.
1691                          */
1692                         mode = acl_posix1e_newfilemode(mode, acl);
1693                         ip->i_mode = mode;
1694                         DIP_SET(ip, i_mode, mode);
1695                         ufs_sync_acl_from_inode(ip, acl);
1696                         break;
1697                 }
1698                 /* FALLTHROUGH */
1699
1700         case EOPNOTSUPP:
1701                 /*
1702                  * Just use the mode as-is.
1703                  */
1704                 ip->i_mode = mode;
1705                 DIP_SET(ip, i_mode, mode);
1706                 error = 0;
1707                 goto out;
1708
1709         default:
1710                 goto out;
1711         }
1712
1713         /*
1714          * XXX: If we abort now, will Soft Updates notify the extattr
1715          * code that the EAs for the file need to be released?
1716          */
1717         error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cred, td);
1718         switch (error) {
1719         case 0:
1720                 break;
1721
1722         case EOPNOTSUPP:
1723                 /*
1724                  * XXX: This should not happen, as EOPNOTSUPP above was
1725                  * supposed to free acl.
1726                  */
1727                 printf("ufs_makeinode: VOP_GETACL() but no "
1728                     "VOP_SETACL()\n");
1729                 /* panic("ufs_makeinode: VOP_GETACL() but no "
1730                     "VOP_SETACL()"); */
1731                 break;
1732
1733         default:
1734                 goto out;
1735         }
1736
1737 out:
1738         acl_free(acl);
1739
1740         return (error);
1741 }
1742
1743 static int
1744 ufs_do_nfs4_acl_inheritance(struct vnode *dvp, struct vnode *tvp,
1745     mode_t child_mode, struct ucred *cred, struct thread *td)
1746 {
1747         int error;
1748         struct acl *parent_aclp, *child_aclp;
1749
1750         parent_aclp = acl_alloc(M_WAITOK);
1751         child_aclp = acl_alloc(M_WAITOK | M_ZERO);
1752
1753         error = ufs_getacl_nfs4_internal(dvp, parent_aclp, td);
1754         if (error)
1755                 goto out;
1756         acl_nfs4_compute_inherited_acl(parent_aclp, child_aclp,
1757             child_mode, VTOI(tvp)->i_uid, tvp->v_type == VDIR);
1758         error = ufs_setacl_nfs4_internal(tvp, child_aclp, td);
1759         if (error)
1760                 goto out;
1761 out:
1762         acl_free(parent_aclp);
1763         acl_free(child_aclp);
1764
1765         return (error);
1766 }
1767 #endif
1768
1769 /*
1770  * Mkdir system call
1771  */
1772 static int
1773 ufs_mkdir(ap)
1774         struct vop_mkdir_args /* {
1775                 struct vnode *a_dvp;
1776                 struct vnode **a_vpp;
1777                 struct componentname *a_cnp;
1778                 struct vattr *a_vap;
1779         } */ *ap;
1780 {
1781         struct vnode *dvp = ap->a_dvp;
1782         struct vattr *vap = ap->a_vap;
1783         struct componentname *cnp = ap->a_cnp;
1784         struct inode *ip, *dp;
1785         struct vnode *tvp;
1786         struct buf *bp;
1787         struct dirtemplate dirtemplate, *dtp;
1788         struct direct newdir;
1789         int error, dmode;
1790         long blkoff;
1791
1792 #ifdef INVARIANTS
1793         if ((cnp->cn_flags & HASBUF) == 0)
1794                 panic("ufs_mkdir: no name");
1795 #endif
1796         dp = VTOI(dvp);
1797         if ((nlink_t)dp->i_nlink >= LINK_MAX) {
1798                 error = EMLINK;
1799                 goto out;
1800         }
1801         dmode = vap->va_mode & 0777;
1802         dmode |= IFDIR;
1803         /*
1804          * Must simulate part of ufs_makeinode here to acquire the inode,
1805          * but not have it entered in the parent directory. The entry is
1806          * made later after writing "." and ".." entries.
1807          */
1808         error = UFS_VALLOC(dvp, dmode, cnp->cn_cred, &tvp);
1809         if (error)
1810                 goto out;
1811         ip = VTOI(tvp);
1812         ip->i_gid = dp->i_gid;
1813         DIP_SET(ip, i_gid, dp->i_gid);
1814 #ifdef SUIDDIR
1815         {
1816 #ifdef QUOTA
1817                 struct ucred ucred, *ucp;
1818                 gid_t ucred_group;
1819                 ucp = cnp->cn_cred;
1820 #endif
1821                 /*
1822                  * If we are hacking owners here, (only do this where told to)
1823                  * and we are not giving it TO root, (would subvert quotas)
1824                  * then go ahead and give it to the other user.
1825                  * The new directory also inherits the SUID bit.
1826                  * If user's UID and dir UID are the same,
1827                  * 'give it away' so that the SUID is still forced on.
1828                  */
1829                 if ((dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
1830                     (dp->i_mode & ISUID) && dp->i_uid) {
1831                         dmode |= ISUID;
1832                         ip->i_uid = dp->i_uid;
1833                         DIP_SET(ip, i_uid, dp->i_uid);
1834 #ifdef QUOTA
1835                         if (dp->i_uid != cnp->cn_cred->cr_uid) {
1836                                 /*
1837                                  * Make sure the correct user gets charged
1838                                  * for the space.
1839                                  * Make a dummy credential for the victim.
1840                                  * XXX This seems to never be accessed out of
1841                                  * our context so a stack variable is ok.
1842                                  */
1843                                 refcount_init(&ucred.cr_ref, 1);
1844                                 ucred.cr_uid = ip->i_uid;
1845                                 ucred.cr_ngroups = 1;
1846                                 ucred.cr_groups = &ucred_group;
1847                                 ucred.cr_groups[0] = dp->i_gid;
1848                                 ucp = &ucred;
1849                         }
1850 #endif
1851                 } else {
1852                         ip->i_uid = cnp->cn_cred->cr_uid;
1853                         DIP_SET(ip, i_uid, ip->i_uid);
1854                 }
1855 #ifdef QUOTA
1856                 if ((error = getinoquota(ip)) ||
1857                     (error = chkiq(ip, 1, ucp, 0))) {
1858                         UFS_VFREE(tvp, ip->i_number, dmode);
1859                         vput(tvp);
1860                         return (error);
1861                 }
1862 #endif
1863         }
1864 #else   /* !SUIDDIR */
1865         ip->i_uid = cnp->cn_cred->cr_uid;
1866         DIP_SET(ip, i_uid, ip->i_uid);
1867 #ifdef QUOTA
1868         if ((error = getinoquota(ip)) ||
1869             (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
1870                 UFS_VFREE(tvp, ip->i_number, dmode);
1871                 vput(tvp);
1872                 return (error);
1873         }
1874 #endif
1875 #endif  /* !SUIDDIR */
1876         ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
1877         ip->i_mode = dmode;
1878         DIP_SET(ip, i_mode, dmode);
1879         tvp->v_type = VDIR;     /* Rest init'd in getnewvnode(). */
1880         ip->i_effnlink = 2;
1881         ip->i_nlink = 2;
1882         DIP_SET(ip, i_nlink, 2);
1883         if (DOINGSOFTDEP(tvp))
1884                 softdep_change_linkcnt(ip);
1885         if (cnp->cn_flags & ISWHITEOUT) {
1886                 ip->i_flags |= UF_OPAQUE;
1887                 DIP_SET(ip, i_flags, ip->i_flags);
1888         }
1889
1890         /*
1891          * Bump link count in parent directory to reflect work done below.
1892          * Should be done before reference is created so cleanup is
1893          * possible if we crash.
1894          */
1895         dp->i_effnlink++;
1896         dp->i_nlink++;
1897         DIP_SET(dp, i_nlink, dp->i_nlink);
1898         dp->i_flag |= IN_CHANGE;
1899         if (DOINGSOFTDEP(dvp))
1900                 softdep_change_linkcnt(dp);
1901         error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(dvp) | DOINGASYNC(dvp)));
1902         if (error)
1903                 goto bad;
1904 #ifdef MAC
1905         if (dvp->v_mount->mnt_flag & MNT_MULTILABEL) {
1906                 error = mac_vnode_create_extattr(cnp->cn_cred, dvp->v_mount,
1907                     dvp, tvp, cnp);
1908                 if (error)
1909                         goto bad;
1910         }
1911 #endif
1912 #ifdef UFS_ACL
1913         if (dvp->v_mount->mnt_flag & MNT_ACLS) {
1914                 error = ufs_do_posix1e_acl_inheritance_dir(dvp, tvp, dmode,
1915                     cnp->cn_cred, cnp->cn_thread);
1916                 if (error)
1917                         goto bad;
1918         } else if (dvp->v_mount->mnt_flag & MNT_NFS4ACLS) {
1919                 error = ufs_do_nfs4_acl_inheritance(dvp, tvp, dmode,
1920                     cnp->cn_cred, cnp->cn_thread);
1921                 if (error)
1922                         goto bad;
1923         }
1924 #endif /* !UFS_ACL */
1925
1926         /*
1927          * Initialize directory with "." and ".." from static template.
1928          */
1929         if (dvp->v_mount->mnt_maxsymlinklen > 0)
1930                 dtp = &mastertemplate;
1931         else
1932                 dtp = (struct dirtemplate *)&omastertemplate;
1933         dirtemplate = *dtp;
1934         dirtemplate.dot_ino = ip->i_number;
1935         dirtemplate.dotdot_ino = dp->i_number;
1936         if ((error = UFS_BALLOC(tvp, (off_t)0, DIRBLKSIZ, cnp->cn_cred,
1937             BA_CLRBUF, &bp)) != 0)
1938                 goto bad;
1939         ip->i_size = DIRBLKSIZ;
1940         DIP_SET(ip, i_size, DIRBLKSIZ);
1941         ip->i_flag |= IN_CHANGE | IN_UPDATE;
1942         vnode_pager_setsize(tvp, (u_long)ip->i_size);
1943         bcopy((caddr_t)&dirtemplate, (caddr_t)bp->b_data, sizeof dirtemplate);
1944         if (DOINGSOFTDEP(tvp)) {
1945                 /*
1946                  * Ensure that the entire newly allocated block is a
1947                  * valid directory so that future growth within the
1948                  * block does not have to ensure that the block is
1949                  * written before the inode.
1950                  */
1951                 blkoff = DIRBLKSIZ;
1952                 while (blkoff < bp->b_bcount) {
1953                         ((struct direct *)
1954                            (bp->b_data + blkoff))->d_reclen = DIRBLKSIZ;
1955                         blkoff += DIRBLKSIZ;
1956                 }
1957         }
1958         if ((error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(tvp) |
1959                                        DOINGASYNC(tvp)))) != 0) {
1960                 (void)bwrite(bp);
1961                 goto bad;
1962         }
1963         /*
1964          * Directory set up, now install its entry in the parent directory.
1965          *
1966          * If we are not doing soft dependencies, then we must write out the
1967          * buffer containing the new directory body before entering the new 
1968          * name in the parent. If we are doing soft dependencies, then the
1969          * buffer containing the new directory body will be passed to and
1970          * released in the soft dependency code after the code has attached
1971          * an appropriate ordering dependency to the buffer which ensures that
1972          * the buffer is written before the new name is written in the parent.
1973          */
1974         if (DOINGASYNC(dvp))
1975                 bdwrite(bp);
1976         else if (!DOINGSOFTDEP(dvp) && ((error = bwrite(bp))))
1977                 goto bad;
1978         ufs_makedirentry(ip, cnp, &newdir);
1979         error = ufs_direnter(dvp, tvp, &newdir, cnp, bp, 0);
1980         
1981 bad:
1982         if (error == 0) {
1983                 *ap->a_vpp = tvp;
1984         } else {
1985                 dp->i_effnlink--;
1986                 dp->i_nlink--;
1987                 DIP_SET(dp, i_nlink, dp->i_nlink);
1988                 dp->i_flag |= IN_CHANGE;
1989                 if (DOINGSOFTDEP(dvp))
1990                         softdep_change_linkcnt(dp);
1991                 /*
1992                  * No need to do an explicit VOP_TRUNCATE here, vrele will
1993                  * do this for us because we set the link count to 0.
1994                  */
1995                 ip->i_effnlink = 0;
1996                 ip->i_nlink = 0;
1997                 DIP_SET(ip, i_nlink, 0);
1998                 ip->i_flag |= IN_CHANGE;
1999                 if (DOINGSOFTDEP(tvp))
2000                         softdep_change_linkcnt(ip);
2001                 vput(tvp);
2002         }
2003 out:
2004         return (error);
2005 }
2006
2007 /*
2008  * Rmdir system call.
2009  */
2010 static int
2011 ufs_rmdir(ap)
2012         struct vop_rmdir_args /* {
2013                 struct vnode *a_dvp;
2014                 struct vnode *a_vp;
2015                 struct componentname *a_cnp;
2016         } */ *ap;
2017 {
2018         struct vnode *vp = ap->a_vp;
2019         struct vnode *dvp = ap->a_dvp;
2020         struct componentname *cnp = ap->a_cnp;
2021         struct inode *ip, *dp;
2022         int error, ioflag;
2023
2024         ip = VTOI(vp);
2025         dp = VTOI(dvp);
2026
2027         /*
2028          * Do not remove a directory that is in the process of being renamed.
2029          * Verify the directory is empty (and valid). Rmdir ".." will not be
2030          * valid since ".." will contain a reference to the current directory
2031          * and thus be non-empty. Do not allow the removal of mounted on
2032          * directories (this can happen when an NFS exported filesystem
2033          * tries to remove a locally mounted on directory).
2034          */
2035         error = 0;
2036         if (ip->i_effnlink < 2) {
2037                 error = EINVAL;
2038                 goto out;
2039         }
2040         if (!ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) {
2041                 error = ENOTEMPTY;
2042                 goto out;
2043         }
2044         if ((dp->i_flags & APPEND)
2045             || (ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))) {
2046                 error = EPERM;
2047                 goto out;
2048         }
2049         if (vp->v_mountedhere != 0) {
2050                 error = EINVAL;
2051                 goto out;
2052         }
2053 #ifdef UFS_GJOURNAL
2054         ufs_gjournal_orphan(vp);
2055 #endif
2056         /*
2057          * Delete reference to directory before purging
2058          * inode.  If we crash in between, the directory
2059          * will be reattached to lost+found,
2060          */
2061         dp->i_effnlink--;
2062         ip->i_effnlink--;
2063         if (DOINGSOFTDEP(vp)) {
2064                 softdep_change_linkcnt(dp);
2065                 softdep_change_linkcnt(ip);
2066         }
2067         error = ufs_dirremove(dvp, ip, cnp->cn_flags, 1);
2068         if (error) {
2069                 dp->i_effnlink++;
2070                 ip->i_effnlink++;
2071                 if (DOINGSOFTDEP(vp)) {
2072                         softdep_change_linkcnt(dp);
2073                         softdep_change_linkcnt(ip);
2074                 }
2075                 goto out;
2076         }
2077         cache_purge(dvp);
2078         /*
2079          * Truncate inode. The only stuff left in the directory is "." and
2080          * "..". The "." reference is inconsequential since we are quashing
2081          * it. The soft dependency code will arrange to do these operations
2082          * after the parent directory entry has been deleted on disk, so
2083          * when running with that code we avoid doing them now.
2084          */
2085         if (!DOINGSOFTDEP(vp)) {
2086                 dp->i_nlink--;
2087                 DIP_SET(dp, i_nlink, dp->i_nlink);
2088                 dp->i_flag |= IN_CHANGE;
2089                 error = UFS_UPDATE(dvp, 0);
2090                 ip->i_nlink--;
2091                 DIP_SET(ip, i_nlink, ip->i_nlink);
2092                 ip->i_flag |= IN_CHANGE;
2093                 ioflag = IO_NORMAL;
2094                 if (!DOINGASYNC(vp))
2095                         ioflag |= IO_SYNC;
2096                 error = UFS_TRUNCATE(vp, (off_t)0, ioflag, cnp->cn_cred,
2097                     cnp->cn_thread);
2098         }
2099         cache_purge(vp);
2100 #ifdef UFS_DIRHASH
2101         /* Kill any active hash; i_effnlink == 0, so it will not come back. */
2102         if (ip->i_dirhash != NULL)
2103                 ufsdirhash_free(ip);
2104 #endif
2105 out:
2106         return (error);
2107 }
2108
2109 /*
2110  * symlink -- make a symbolic link
2111  */
2112 static int
2113 ufs_symlink(ap)
2114         struct vop_symlink_args /* {
2115                 struct vnode *a_dvp;
2116                 struct vnode **a_vpp;
2117                 struct componentname *a_cnp;
2118                 struct vattr *a_vap;
2119                 char *a_target;
2120         } */ *ap;
2121 {
2122         struct vnode *vp, **vpp = ap->a_vpp;
2123         struct inode *ip;
2124         int len, error;
2125
2126         error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
2127             vpp, ap->a_cnp);
2128         if (error)
2129                 return (error);
2130         vp = *vpp;
2131         len = strlen(ap->a_target);
2132         if (len < vp->v_mount->mnt_maxsymlinklen) {
2133                 ip = VTOI(vp);
2134                 bcopy(ap->a_target, SHORTLINK(ip), len);
2135                 ip->i_size = len;
2136                 DIP_SET(ip, i_size, len);
2137                 ip->i_flag |= IN_CHANGE | IN_UPDATE;
2138                 error = UFS_UPDATE(vp, 0);
2139         } else
2140                 error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
2141                     UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK,
2142                     ap->a_cnp->cn_cred, NOCRED, NULL, NULL);
2143         if (error)
2144                 vput(vp);
2145         return (error);
2146 }
2147
2148 /*
2149  * Vnode op for reading directories.
2150  *
2151  * The routine below assumes that the on-disk format of a directory
2152  * is the same as that defined by <sys/dirent.h>. If the on-disk
2153  * format changes, then it will be necessary to do a conversion
2154  * from the on-disk format that read returns to the format defined
2155  * by <sys/dirent.h>.
2156  */
2157 int
2158 ufs_readdir(ap)
2159         struct vop_readdir_args /* {
2160                 struct vnode *a_vp;
2161                 struct uio *a_uio;
2162                 struct ucred *a_cred;
2163                 int *a_eofflag;
2164                 int *a_ncookies;
2165                 u_long **a_cookies;
2166         } */ *ap;
2167 {
2168         struct uio *uio = ap->a_uio;
2169         int error;
2170         size_t count, lost;
2171         off_t off;
2172
2173         if (ap->a_ncookies != NULL)
2174                 /*
2175                  * Ensure that the block is aligned.  The caller can use
2176                  * the cookies to determine where in the block to start.
2177                  */
2178                 uio->uio_offset &= ~(DIRBLKSIZ - 1);
2179         off = uio->uio_offset;
2180         count = uio->uio_resid;
2181         /* Make sure we don't return partial entries. */
2182         if (count <= ((uio->uio_offset + count) & (DIRBLKSIZ -1)))
2183                 return (EINVAL);
2184         count -= (uio->uio_offset + count) & (DIRBLKSIZ -1);
2185         lost = uio->uio_resid - count;
2186         uio->uio_resid = count;
2187         uio->uio_iov->iov_len = count;
2188 #       if (BYTE_ORDER == LITTLE_ENDIAN)
2189                 if (ap->a_vp->v_mount->mnt_maxsymlinklen > 0) {
2190                         error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
2191                 } else {
2192                         struct dirent *dp, *edp;
2193                         struct uio auio;
2194                         struct iovec aiov;
2195                         caddr_t dirbuf;
2196                         int readcnt;
2197                         u_char tmp;
2198
2199                         auio = *uio;
2200                         auio.uio_iov = &aiov;
2201                         auio.uio_iovcnt = 1;
2202                         auio.uio_segflg = UIO_SYSSPACE;
2203                         aiov.iov_len = count;
2204                         dirbuf = malloc(count, M_TEMP, M_WAITOK);
2205                         aiov.iov_base = dirbuf;
2206                         error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred);
2207                         if (error == 0) {
2208                                 readcnt = count - auio.uio_resid;
2209                                 edp = (struct dirent *)&dirbuf[readcnt];
2210                                 for (dp = (struct dirent *)dirbuf; dp < edp; ) {
2211                                         tmp = dp->d_namlen;
2212                                         dp->d_namlen = dp->d_type;
2213                                         dp->d_type = tmp;
2214                                         if (dp->d_reclen > 0) {
2215                                                 dp = (struct dirent *)
2216                                                     ((char *)dp + dp->d_reclen);
2217                                         } else {
2218                                                 error = EIO;
2219                                                 break;
2220                                         }
2221                                 }
2222                                 if (dp >= edp)
2223                                         error = uiomove(dirbuf, readcnt, uio);
2224                         }
2225                         free(dirbuf, M_TEMP);
2226                 }
2227 #       else
2228                 error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
2229 #       endif
2230         if (!error && ap->a_ncookies != NULL) {
2231                 struct dirent* dpStart;
2232                 struct dirent* dpEnd;
2233                 struct dirent* dp;
2234                 int ncookies;
2235                 u_long *cookies;
2236                 u_long *cookiep;
2237
2238                 if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
2239                         panic("ufs_readdir: unexpected uio from NFS server");
2240                 dpStart = (struct dirent *)
2241                     ((char *)uio->uio_iov->iov_base - (uio->uio_offset - off));
2242                 dpEnd = (struct dirent *) uio->uio_iov->iov_base;
2243                 for (dp = dpStart, ncookies = 0;
2244                      dp < dpEnd;
2245                      dp = (struct dirent *)((caddr_t) dp + dp->d_reclen))
2246                         ncookies++;
2247                 cookies = malloc(ncookies * sizeof(u_long), M_TEMP,
2248                     M_WAITOK);
2249                 for (dp = dpStart, cookiep = cookies;
2250                      dp < dpEnd;
2251                      dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) {
2252                         off += dp->d_reclen;
2253                         *cookiep++ = (u_long) off;
2254                 }
2255                 *ap->a_ncookies = ncookies;
2256                 *ap->a_cookies = cookies;
2257         }
2258         uio->uio_resid += lost;
2259         if (ap->a_eofflag)
2260             *ap->a_eofflag = VTOI(ap->a_vp)->i_size <= uio->uio_offset;
2261         return (error);
2262 }
2263
2264 /*
2265  * Return target name of a symbolic link
2266  */
2267 static int
2268 ufs_readlink(ap)
2269         struct vop_readlink_args /* {
2270                 struct vnode *a_vp;
2271                 struct uio *a_uio;
2272                 struct ucred *a_cred;
2273         } */ *ap;
2274 {
2275         struct vnode *vp = ap->a_vp;
2276         struct inode *ip = VTOI(vp);
2277         doff_t isize;
2278
2279         isize = ip->i_size;
2280         if ((isize < vp->v_mount->mnt_maxsymlinklen) ||
2281             DIP(ip, i_blocks) == 0) { /* XXX - for old fastlink support */
2282                 return (uiomove(SHORTLINK(ip), isize, ap->a_uio));
2283         }
2284         return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred));
2285 }
2286
2287 /*
2288  * Calculate the logical to physical mapping if not done already,
2289  * then call the device strategy routine.
2290  *
2291  * In order to be able to swap to a file, the ufs_bmaparray() operation may not
2292  * deadlock on memory.  See ufs_bmap() for details.
2293  */
2294 static int
2295 ufs_strategy(ap)
2296         struct vop_strategy_args /* {
2297                 struct vnode *a_vp;
2298                 struct buf *a_bp;
2299         } */ *ap;
2300 {
2301         struct buf *bp = ap->a_bp;
2302         struct vnode *vp = ap->a_vp;
2303         struct bufobj *bo;
2304         struct inode *ip;
2305         ufs2_daddr_t blkno;
2306         int error;
2307
2308         ip = VTOI(vp);
2309         if (bp->b_blkno == bp->b_lblkno) {
2310                 error = ufs_bmaparray(vp, bp->b_lblkno, &blkno, bp, NULL, NULL);
2311                 bp->b_blkno = blkno;
2312                 if (error) {
2313                         bp->b_error = error;
2314                         bp->b_ioflags |= BIO_ERROR;
2315                         bufdone(bp);
2316                         return (0);
2317                 }
2318                 if ((long)bp->b_blkno == -1)
2319                         vfs_bio_clrbuf(bp);
2320         }
2321         if ((long)bp->b_blkno == -1) {
2322                 bufdone(bp);
2323                 return (0);
2324         }
2325         bp->b_iooffset = dbtob(bp->b_blkno);
2326         bo = ip->i_umbufobj;
2327         BO_STRATEGY(bo, bp);
2328         return (0);
2329 }
2330
2331 /*
2332  * Print out the contents of an inode.
2333  */
2334 static int
2335 ufs_print(ap)
2336         struct vop_print_args /* {
2337                 struct vnode *a_vp;
2338         } */ *ap;
2339 {
2340         struct vnode *vp = ap->a_vp;
2341         struct inode *ip = VTOI(vp);
2342
2343         printf("\tino %lu, on dev %s", (u_long)ip->i_number,
2344             devtoname(ip->i_dev));
2345         if (vp->v_type == VFIFO)
2346                 fifo_printinfo(vp);
2347         printf("\n");
2348         return (0);
2349 }
2350
2351 /*
2352  * Close wrapper for fifos.
2353  *
2354  * Update the times on the inode then do device close.
2355  */
2356 static int
2357 ufsfifo_close(ap)
2358         struct vop_close_args /* {
2359                 struct vnode *a_vp;
2360                 int  a_fflag;
2361                 struct ucred *a_cred;
2362                 struct thread *a_td;
2363         } */ *ap;
2364 {
2365         struct vnode *vp = ap->a_vp;
2366         int usecount;
2367
2368         VI_LOCK(vp);
2369         usecount = vp->v_usecount;
2370         if (usecount > 1)
2371                 ufs_itimes_locked(vp);
2372         VI_UNLOCK(vp);
2373         return (fifo_specops.vop_close(ap));
2374 }
2375
2376 /*
2377  * Kqfilter wrapper for fifos.
2378  *
2379  * Fall through to ufs kqfilter routines if needed 
2380  */
2381 static int
2382 ufsfifo_kqfilter(ap)
2383         struct vop_kqfilter_args *ap;
2384 {
2385         int error;
2386
2387         error = fifo_specops.vop_kqfilter(ap);
2388         if (error)
2389                 error = vfs_kqfilter(ap);
2390         return (error);
2391 }
2392
2393 /*
2394  * Return POSIX pathconf information applicable to fifos.
2395  */
2396 static int
2397 ufsfifo_pathconf(ap)
2398         struct vop_pathconf_args /* {
2399                 struct vnode *a_vp;
2400                 int a_name;
2401                 int *a_retval;
2402         } */ *ap;
2403 {
2404
2405         switch (ap->a_name) {
2406         case _PC_ACL_EXTENDED:
2407         case _PC_ACL_NFS4:
2408         case _PC_ACL_PATH_MAX:
2409         case _PC_MAC_PRESENT:
2410                 return (ufs_pathconf(ap));
2411         default:
2412                 return (fifo_specops.vop_pathconf(ap));
2413         }
2414         /* NOTREACHED */
2415 }
2416
2417 /*
2418  * Return POSIX pathconf information applicable to ufs filesystems.
2419  */
2420 static int
2421 ufs_pathconf(ap)
2422         struct vop_pathconf_args /* {
2423                 struct vnode *a_vp;
2424                 int a_name;
2425                 int *a_retval;
2426         } */ *ap;
2427 {
2428         int error;
2429
2430         error = 0;
2431         switch (ap->a_name) {
2432         case _PC_LINK_MAX:
2433                 *ap->a_retval = LINK_MAX;
2434                 break;
2435         case _PC_NAME_MAX:
2436                 *ap->a_retval = NAME_MAX;
2437                 break;
2438         case _PC_PATH_MAX:
2439                 *ap->a_retval = PATH_MAX;
2440                 break;
2441         case _PC_PIPE_BUF:
2442                 *ap->a_retval = PIPE_BUF;
2443                 break;
2444         case _PC_CHOWN_RESTRICTED:
2445                 *ap->a_retval = 1;
2446                 break;
2447         case _PC_NO_TRUNC:
2448                 *ap->a_retval = 1;
2449                 break;
2450         case _PC_ACL_EXTENDED:
2451 #ifdef UFS_ACL
2452                 if (ap->a_vp->v_mount->mnt_flag & MNT_ACLS)
2453                         *ap->a_retval = 1;
2454                 else
2455                         *ap->a_retval = 0;
2456 #else
2457                 *ap->a_retval = 0;
2458 #endif
2459                 break;
2460
2461         case _PC_ACL_NFS4:
2462 #ifdef UFS_ACL
2463                 if (ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS)
2464                         *ap->a_retval = 1;
2465                 else
2466                         *ap->a_retval = 0;
2467 #else
2468                 *ap->a_retval = 0;
2469 #endif
2470                 break;
2471
2472         case _PC_ACL_PATH_MAX:
2473 #ifdef UFS_ACL
2474                 if (ap->a_vp->v_mount->mnt_flag & (MNT_ACLS | MNT_NFS4ACLS))
2475                         *ap->a_retval = ACL_MAX_ENTRIES;
2476                 else
2477                         *ap->a_retval = 3;
2478 #else
2479                 *ap->a_retval = 3;
2480 #endif
2481                 break;
2482         case _PC_MAC_PRESENT:
2483 #ifdef MAC
2484                 if (ap->a_vp->v_mount->mnt_flag & MNT_MULTILABEL)
2485                         *ap->a_retval = 1;
2486                 else
2487                         *ap->a_retval = 0;
2488 #else
2489                 *ap->a_retval = 0;
2490 #endif
2491                 break;
2492         case _PC_ASYNC_IO:
2493                 /* _PC_ASYNC_IO should have been handled by upper layers. */
2494                 KASSERT(0, ("_PC_ASYNC_IO should not get here"));
2495                 error = EINVAL;
2496                 break;
2497         case _PC_PRIO_IO:
2498                 *ap->a_retval = 0;
2499                 break;
2500         case _PC_SYNC_IO:
2501                 *ap->a_retval = 0;
2502                 break;
2503         case _PC_ALLOC_SIZE_MIN:
2504                 *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_bsize;
2505                 break;
2506         case _PC_FILESIZEBITS:
2507                 *ap->a_retval = 64;
2508                 break;
2509         case _PC_REC_INCR_XFER_SIZE:
2510                 *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
2511                 break;
2512         case _PC_REC_MAX_XFER_SIZE:
2513                 *ap->a_retval = -1; /* means ``unlimited'' */
2514                 break;
2515         case _PC_REC_MIN_XFER_SIZE:
2516                 *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
2517                 break;
2518         case _PC_REC_XFER_ALIGN:
2519                 *ap->a_retval = PAGE_SIZE;
2520                 break;
2521         case _PC_SYMLINK_MAX:
2522                 *ap->a_retval = MAXPATHLEN;
2523                 break;
2524
2525         default:
2526                 error = EINVAL;
2527                 break;
2528         }
2529         return (error);
2530 }
2531
2532 /*
2533  * Initialize the vnode associated with a new inode, handle aliased
2534  * vnodes.
2535  */
2536 int
2537 ufs_vinit(mntp, fifoops, vpp)
2538         struct mount *mntp;
2539         struct vop_vector *fifoops;
2540         struct vnode **vpp;
2541 {
2542         struct inode *ip;
2543         struct vnode *vp;
2544
2545         vp = *vpp;
2546         ip = VTOI(vp);
2547         vp->v_type = IFTOVT(ip->i_mode);
2548         if (vp->v_type == VFIFO)
2549                 vp->v_op = fifoops;
2550         ASSERT_VOP_LOCKED(vp, "ufs_vinit");
2551         if (ip->i_number == ROOTINO)
2552                 vp->v_vflag |= VV_ROOT;
2553         *vpp = vp;
2554         return (0);
2555 }
2556
2557 /*
2558  * Allocate a new inode.
2559  * Vnode dvp must be locked.
2560  */
2561 static int
2562 ufs_makeinode(mode, dvp, vpp, cnp)
2563         int mode;
2564         struct vnode *dvp;
2565         struct vnode **vpp;
2566         struct componentname *cnp;
2567 {
2568         struct inode *ip, *pdir;
2569         struct direct newdir;
2570         struct vnode *tvp;
2571         int error;
2572
2573         pdir = VTOI(dvp);
2574 #ifdef INVARIANTS
2575         if ((cnp->cn_flags & HASBUF) == 0)
2576                 panic("ufs_makeinode: no name");
2577 #endif
2578         *vpp = NULL;
2579         if ((mode & IFMT) == 0)
2580                 mode |= IFREG;
2581
2582         error = UFS_VALLOC(dvp, mode, cnp->cn_cred, &tvp);
2583         if (error)
2584                 return (error);
2585         ip = VTOI(tvp);
2586         ip->i_gid = pdir->i_gid;
2587         DIP_SET(ip, i_gid, pdir->i_gid);
2588 #ifdef SUIDDIR
2589         {
2590 #ifdef QUOTA
2591                 struct ucred ucred, *ucp;
2592                 gid_t ucred_group;
2593                 ucp = cnp->cn_cred;
2594 #endif
2595                 /*
2596                  * If we are not the owner of the directory,
2597                  * and we are hacking owners here, (only do this where told to)
2598                  * and we are not giving it TO root, (would subvert quotas)
2599                  * then go ahead and give it to the other user.
2600                  * Note that this drops off the execute bits for security.
2601                  */
2602                 if ((dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
2603                     (pdir->i_mode & ISUID) &&
2604                     (pdir->i_uid != cnp->cn_cred->cr_uid) && pdir->i_uid) {
2605                         ip->i_uid = pdir->i_uid;
2606                         DIP_SET(ip, i_uid, ip->i_uid);
2607                         mode &= ~07111;
2608 #ifdef QUOTA
2609                         /*
2610                          * Make sure the correct user gets charged
2611                          * for the space.
2612                          * Quickly knock up a dummy credential for the victim.
2613                          * XXX This seems to never be accessed out of our
2614                          * context so a stack variable is ok.
2615                          */
2616                         refcount_init(&ucred.cr_ref, 1);
2617                         ucred.cr_uid = ip->i_uid;
2618                         ucred.cr_ngroups = 1;
2619                         ucred.cr_groups = &ucred_group;
2620                         ucred.cr_groups[0] = pdir->i_gid;
2621                         ucp = &ucred;
2622 #endif
2623                 } else {
2624                         ip->i_uid = cnp->cn_cred->cr_uid;
2625                         DIP_SET(ip, i_uid, ip->i_uid);
2626                 }
2627
2628 #ifdef QUOTA
2629                 if ((error = getinoquota(ip)) ||
2630                     (error = chkiq(ip, 1, ucp, 0))) {
2631                         UFS_VFREE(tvp, ip->i_number, mode);
2632                         vput(tvp);
2633                         return (error);
2634                 }
2635 #endif
2636         }
2637 #else   /* !SUIDDIR */
2638         ip->i_uid = cnp->cn_cred->cr_uid;
2639         DIP_SET(ip, i_uid, ip->i_uid);
2640 #ifdef QUOTA
2641         if ((error = getinoquota(ip)) ||
2642             (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
2643                 UFS_VFREE(tvp, ip->i_number, mode);
2644                 vput(tvp);
2645                 return (error);
2646         }
2647 #endif
2648 #endif  /* !SUIDDIR */
2649         ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
2650         ip->i_mode = mode;
2651         DIP_SET(ip, i_mode, mode);
2652         tvp->v_type = IFTOVT(mode);     /* Rest init'd in getnewvnode(). */
2653         ip->i_effnlink = 1;
2654         ip->i_nlink = 1;
2655         DIP_SET(ip, i_nlink, 1);
2656         if (DOINGSOFTDEP(tvp))
2657                 softdep_change_linkcnt(ip);
2658         if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
2659             priv_check_cred(cnp->cn_cred, PRIV_VFS_SETGID, 0)) {
2660                 ip->i_mode &= ~ISGID;
2661                 DIP_SET(ip, i_mode, ip->i_mode);
2662         }
2663
2664         if (cnp->cn_flags & ISWHITEOUT) {
2665                 ip->i_flags |= UF_OPAQUE;
2666                 DIP_SET(ip, i_flags, ip->i_flags);
2667         }
2668
2669         /*
2670          * Make sure inode goes to disk before directory entry.
2671          */
2672         error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(tvp) | DOINGASYNC(tvp)));
2673         if (error)
2674                 goto bad;
2675 #ifdef MAC
2676         if (dvp->v_mount->mnt_flag & MNT_MULTILABEL) {
2677                 error = mac_vnode_create_extattr(cnp->cn_cred, dvp->v_mount,
2678                     dvp, tvp, cnp);
2679                 if (error)
2680                         goto bad;
2681         }
2682 #endif
2683 #ifdef UFS_ACL
2684         if (dvp->v_mount->mnt_flag & MNT_ACLS) {
2685                 error = ufs_do_posix1e_acl_inheritance_file(dvp, tvp, mode,
2686                     cnp->cn_cred, cnp->cn_thread);
2687                 if (error)
2688                         goto bad;
2689         } else if (dvp->v_mount->mnt_flag & MNT_NFS4ACLS) {
2690                 error = ufs_do_nfs4_acl_inheritance(dvp, tvp, mode,
2691                     cnp->cn_cred, cnp->cn_thread);
2692                 if (error)
2693                         goto bad;
2694         }
2695 #endif /* !UFS_ACL */
2696         ufs_makedirentry(ip, cnp, &newdir);
2697         error = ufs_direnter(dvp, tvp, &newdir, cnp, NULL, 0);
2698         if (error)
2699                 goto bad;
2700         *vpp = tvp;
2701         return (0);
2702
2703 bad:
2704         /*
2705          * Write error occurred trying to update the inode
2706          * or the directory so must deallocate the inode.
2707          */
2708         ip->i_effnlink = 0;
2709         ip->i_nlink = 0;
2710         DIP_SET(ip, i_nlink, 0);
2711         ip->i_flag |= IN_CHANGE;
2712         if (DOINGSOFTDEP(tvp))
2713                 softdep_change_linkcnt(ip);
2714         vput(tvp);
2715         return (error);
2716 }
2717
2718 /* Global vfs data structures for ufs. */
2719 struct vop_vector ufs_vnodeops = {
2720         .vop_default =          &default_vnodeops,
2721         .vop_fsync =            VOP_PANIC,
2722         .vop_read =             VOP_PANIC,
2723         .vop_reallocblks =      VOP_PANIC,
2724         .vop_write =            VOP_PANIC,
2725         .vop_accessx =          ufs_accessx,
2726         .vop_bmap =             ufs_bmap,
2727         .vop_cachedlookup =     ufs_lookup,
2728         .vop_close =            ufs_close,
2729         .vop_create =           ufs_create,
2730         .vop_getattr =          ufs_getattr,
2731         .vop_inactive =         ufs_inactive,
2732         .vop_link =             ufs_link,
2733         .vop_lookup =           vfs_cache_lookup,
2734         .vop_markatime =        ufs_markatime,
2735         .vop_mkdir =            ufs_mkdir,
2736         .vop_mknod =            ufs_mknod,
2737         .vop_open =             ufs_open,
2738         .vop_pathconf =         ufs_pathconf,
2739         .vop_poll =             vop_stdpoll,
2740         .vop_print =            ufs_print,
2741         .vop_readdir =          ufs_readdir,
2742         .vop_readlink =         ufs_readlink,
2743         .vop_reclaim =          ufs_reclaim,
2744         .vop_remove =           ufs_remove,
2745         .vop_rename =           ufs_rename,
2746         .vop_rmdir =            ufs_rmdir,
2747         .vop_setattr =          ufs_setattr,
2748 #ifdef MAC
2749         .vop_setlabel =         vop_stdsetlabel_ea,
2750 #endif
2751         .vop_strategy =         ufs_strategy,
2752         .vop_symlink =          ufs_symlink,
2753         .vop_whiteout =         ufs_whiteout,
2754 #ifdef UFS_EXTATTR
2755         .vop_getextattr =       ufs_getextattr,
2756         .vop_deleteextattr =    ufs_deleteextattr,
2757         .vop_setextattr =       ufs_setextattr,
2758 #endif
2759 #ifdef UFS_ACL
2760         .vop_getacl =           ufs_getacl,
2761         .vop_setacl =           ufs_setacl,
2762         .vop_aclcheck =         ufs_aclcheck,
2763 #endif
2764 };
2765
2766 struct vop_vector ufs_fifoops = {
2767         .vop_default =          &fifo_specops,
2768         .vop_fsync =            VOP_PANIC,
2769         .vop_accessx =          ufs_accessx,
2770         .vop_close =            ufsfifo_close,
2771         .vop_getattr =          ufs_getattr,
2772         .vop_inactive =         ufs_inactive,
2773         .vop_kqfilter =         ufsfifo_kqfilter,
2774         .vop_markatime =        ufs_markatime,
2775         .vop_pathconf =         ufsfifo_pathconf,
2776         .vop_print =            ufs_print,
2777         .vop_read =             VOP_PANIC,
2778         .vop_reclaim =          ufs_reclaim,
2779         .vop_setattr =          ufs_setattr,
2780 #ifdef MAC
2781         .vop_setlabel =         vop_stdsetlabel_ea,
2782 #endif
2783         .vop_write =            VOP_PANIC,
2784 #ifdef UFS_EXTATTR
2785         .vop_getextattr =       ufs_getextattr,
2786         .vop_deleteextattr =    ufs_deleteextattr,
2787         .vop_setextattr =       ufs_setextattr,
2788 #endif
2789 #ifdef UFS_ACL
2790         .vop_getacl =           ufs_getacl,
2791         .vop_setacl =           ufs_setacl,
2792         .vop_aclcheck =         ufs_aclcheck,
2793 #endif
2794 };