xref: /netbsd/sys/ufs/ufs/ufs_vnops.c (revision c4a72b64)
1 /*	$NetBSD: ufs_vnops.c,v 1.88 2002/10/23 09:15:09 jdolecek Exp $	*/
2 
3 /*
4  * Copyright (c) 1982, 1986, 1989, 1993, 1995
5  *	The Regents of the University of California.  All rights reserved.
6  * (c) UNIX System Laboratories, Inc.
7  * All or some portions of this file are derived from material licensed
8  * to the University of California by American Telephone and Telegraph
9  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10  * the permission of UNIX System Laboratories, Inc.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *	This product includes software developed by the University of
23  *	California, Berkeley and its contributors.
24  * 4. Neither the name of the University nor the names of its contributors
25  *    may be used to endorse or promote products derived from this software
26  *    without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38  * SUCH DAMAGE.
39  *
40  *	@(#)ufs_vnops.c	8.28 (Berkeley) 7/31/95
41  */
42 
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.88 2002/10/23 09:15:09 jdolecek Exp $");
45 
46 #include "opt_quota.h"
47 #include "fs_lfs.h"
48 
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/namei.h>
52 #include <sys/resourcevar.h>
53 #include <sys/kernel.h>
54 #include <sys/file.h>
55 #include <sys/stat.h>
56 #include <sys/buf.h>
57 #include <sys/proc.h>
58 #include <sys/mount.h>
59 #include <sys/vnode.h>
60 #include <sys/malloc.h>
61 #include <sys/dirent.h>
62 #include <sys/lockf.h>
63 
64 #include <miscfs/specfs/specdev.h>
65 #include <miscfs/fifofs/fifo.h>
66 
67 #include <ufs/ufs/quota.h>
68 #include <ufs/ufs/inode.h>
69 #include <ufs/ufs/dir.h>
70 #include <ufs/ufs/ufsmount.h>
71 #include <ufs/ufs/ufs_bswap.h>
72 #include <ufs/ufs/ufs_extern.h>
73 #include <ufs/ext2fs/ext2fs_extern.h>
74 #include <ufs/lfs/lfs_extern.h>
75 
76 static int ufs_chmod(struct vnode *, int, struct ucred *, struct proc *);
77 static int ufs_chown(struct vnode *, uid_t, gid_t, struct ucred *,
78 		    struct proc *);
79 
80 union _qcvt {
81 	int64_t	qcvt;
82 	int32_t	val[2];
83 };
84 
85 #define SETHIGH(q, h)							\
86 do {									\
87 	union _qcvt tmp;						\
88 	tmp.qcvt = (q);							\
89 	tmp.val[_QUAD_HIGHWORD] = (h);					\
90 	(q) = tmp.qcvt;							\
91 } while (0)
92 
93 #define SETLOW(q, l)							\
94 do {									\
95 	union _qcvt tmp;						\
96 	tmp.qcvt = (q);							\
97 	tmp.val[_QUAD_LOWWORD] = (l);					\
98 	(q) = tmp.qcvt;							\
99 } while (0)
100 
101 /*
102  * A virgin directory (no blushing please).
103  */
104 static struct dirtemplate mastertemplate = {
105 	0,	12,		DT_DIR,	1,	".",
106 	0,	DIRBLKSIZ - 12,	DT_DIR,	2,	".."
107 };
108 
109 /*
110  * Create a regular file
111  */
112 int
113 ufs_create(void *v)
114 {
115 	struct vop_create_args /* {
116 		struct vnode		*a_dvp;
117 		struct vnode		**a_vpp;
118 		struct componentname	*a_cnp;
119 		struct vattr		*a_vap;
120 	} */ *ap = v;
121 	int	error;
122 
123 	error =
124 	    ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode),
125 			  ap->a_dvp, ap->a_vpp, ap->a_cnp);
126 	if (error)
127 		return (error);
128 	VN_KNOTE(ap->a_dvp, NOTE_WRITE);
129 	return (0);
130 }
131 
132 /*
133  * Mknod vnode call
134  */
135 /* ARGSUSED */
136 int
137 ufs_mknod(void *v)
138 {
139 	struct vop_mknod_args /* {
140 		struct vnode		*a_dvp;
141 		struct vnode		**a_vpp;
142 		struct componentname	*a_cnp;
143 		struct vattr		*a_vap;
144 	} */ *ap = v;
145 	struct vattr	*vap;
146 	struct vnode	**vpp;
147 	struct inode	*ip;
148 	int		error;
149 	struct mount	*mp;
150 	ino_t		ino;
151 
152 	vap = ap->a_vap;
153 	vpp = ap->a_vpp;
154 	if ((error =
155 	    ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
156 	    ap->a_dvp, vpp, ap->a_cnp)) != 0)
157 		return (error);
158 	VN_KNOTE(ap->a_dvp, NOTE_WRITE);
159 	ip = VTOI(*vpp);
160 	mp  = (*vpp)->v_mount;
161 	ino = ip->i_number;
162 	ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
163 	if (vap->va_rdev != VNOVAL) {
164 		/*
165 		 * Want to be able to use this to make badblock
166 		 * inodes, so don't truncate the dev number.
167 		 */
168 		ip->i_ffs_rdev = ufs_rw32(vap->va_rdev,
169 		    UFS_MPNEEDSWAP(mp));
170 	}
171 	/*
172 	 * Remove inode so that it will be reloaded by VFS_VGET and
173 	 * checked to see if it is an alias of an existing entry in
174 	 * the inode cache.
175 	 */
176 	vput(*vpp);
177 	(*vpp)->v_type = VNON;
178 	vgone(*vpp);
179 	error = VFS_VGET(mp, ino, vpp);
180 	if (error != 0) {
181 		*vpp = NULL;
182 		return (error);
183 	}
184 	return (0);
185 }
186 
187 /*
188  * Open called.
189  *
190  * Nothing to do.
191  */
192 /* ARGSUSED */
193 int
194 ufs_open(void *v)
195 {
196 	struct vop_open_args /* {
197 		struct vnode	*a_vp;
198 		int		a_mode;
199 		struct ucred	*a_cred;
200 		struct proc	*a_p;
201 	} */ *ap = v;
202 
203 	/*
204 	 * Files marked append-only must be opened for appending.
205 	 */
206 	if ((VTOI(ap->a_vp)->i_ffs_flags & APPEND) &&
207 	    (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE)
208 		return (EPERM);
209 	return (0);
210 }
211 
212 /*
213  * Close called.
214  *
215  * Update the times on the inode.
216  */
217 /* ARGSUSED */
218 int
219 ufs_close(void *v)
220 {
221 	struct vop_close_args /* {
222 		struct vnode	*a_vp;
223 		int		a_fflag;
224 		struct ucred	*a_cred;
225 		struct proc	*a_p;
226 	} */ *ap = v;
227 	struct vnode	*vp;
228 	struct inode	*ip;
229 	struct timespec	ts;
230 
231 	vp = ap->a_vp;
232 	ip = VTOI(vp);
233 	simple_lock(&vp->v_interlock);
234 	if (vp->v_usecount > 1) {
235 		TIMEVAL_TO_TIMESPEC(&time, &ts);
236 		ITIMES(ip, &ts, &ts, &ts);
237 	}
238 	simple_unlock(&vp->v_interlock);
239 	return (0);
240 }
241 
242 int
243 ufs_access(void *v)
244 {
245 	struct vop_access_args /* {
246 		struct vnode	*a_vp;
247 		int		a_mode;
248 		struct ucred	*a_cred;
249 		struct proc	*a_p;
250 	} */ *ap = v;
251 	struct vnode	*vp;
252 	struct inode	*ip;
253 	mode_t		mode;
254 #ifdef QUOTA
255 	int		error;
256 #endif
257 
258 	vp = ap->a_vp;
259 	ip = VTOI(vp);
260 	mode = ap->a_mode;
261 	/*
262 	 * Disallow write attempts on read-only file systems;
263 	 * unless the file is a socket, fifo, or a block or
264 	 * character device resident on the file system.
265 	 */
266 	if (mode & VWRITE) {
267 		switch (vp->v_type) {
268 		case VDIR:
269 		case VLNK:
270 		case VREG:
271 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
272 				return (EROFS);
273 #ifdef QUOTA
274 			if ((error = getinoquota(ip)) != 0)
275 				return (error);
276 #endif
277 			break;
278 		case VBAD:
279 		case VBLK:
280 		case VCHR:
281 		case VSOCK:
282 		case VFIFO:
283 		case VNON:
284 		default:
285 			break;
286 		}
287 	}
288 
289 	/* If immutable bit set, nobody gets to write it. */
290 	if ((mode & VWRITE) && (ip->i_ffs_flags & IMMUTABLE))
291 		return (EPERM);
292 
293 	return (vaccess(vp->v_type, ip->i_ffs_mode & ALLPERMS,
294 		ip->i_ffs_uid, ip->i_ffs_gid, mode, ap->a_cred));
295 }
296 
297 /* ARGSUSED */
298 int
299 ufs_getattr(void *v)
300 {
301 	struct vop_getattr_args /* {
302 		struct vnode	*a_vp;
303 		struct vattr	*a_vap;
304 		struct ucred	*a_cred;
305 		struct proc	*a_p;
306 	} */ *ap = v;
307 	struct vnode	*vp;
308 	struct inode	*ip;
309 	struct vattr	*vap;
310 	struct timespec	ts;
311 
312 	vp = ap->a_vp;
313 	ip = VTOI(vp);
314 	vap = ap->a_vap;
315 	TIMEVAL_TO_TIMESPEC(&time, &ts);
316 	ITIMES(ip, &ts, &ts, &ts);
317 	/*
318 	 * Copy from inode table
319 	 */
320 	vap->va_fsid = ip->i_dev;
321 	vap->va_fileid = ip->i_number;
322 	vap->va_mode = ip->i_ffs_mode & ALLPERMS;
323 	vap->va_nlink = ip->i_ffs_effnlink;
324 	vap->va_uid = ip->i_ffs_uid;
325 	vap->va_gid = ip->i_ffs_gid;
326 	vap->va_rdev = ufs_rw32((dev_t)ip->i_ffs_rdev,
327 	    UFS_MPNEEDSWAP(vp->v_mount));
328 	vap->va_size = vp->v_size;
329 	vap->va_atime.tv_sec = ip->i_ffs_atime;
330 	vap->va_atime.tv_nsec = ip->i_ffs_atimensec;
331 	vap->va_mtime.tv_sec = ip->i_ffs_mtime;
332 	vap->va_mtime.tv_nsec = ip->i_ffs_mtimensec;
333 	vap->va_ctime.tv_sec = ip->i_ffs_ctime;
334 	vap->va_ctime.tv_nsec = ip->i_ffs_ctimensec;
335 	vap->va_flags = ip->i_ffs_flags;
336 	vap->va_gen = ip->i_ffs_gen;
337 	/* this doesn't belong here */
338 	if (vp->v_type == VBLK)
339 		vap->va_blocksize = BLKDEV_IOSIZE;
340 	else if (vp->v_type == VCHR)
341 		vap->va_blocksize = MAXBSIZE;
342 	else
343 		vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
344 	vap->va_bytes = dbtob((u_quad_t)ip->i_ffs_blocks);
345 	vap->va_type = vp->v_type;
346 	vap->va_filerev = ip->i_modrev;
347 	return (0);
348 }
349 
350 /*
351  * Set attribute vnode op. called from several syscalls
352  */
353 int
354 ufs_setattr(void *v)
355 {
356 	struct vop_setattr_args /* {
357 		struct vnode	*a_vp;
358 		struct vattr	*a_vap;
359 		struct ucred	*a_cred;
360 		struct proc	*a_p;
361 	} */ *ap = v;
362 	struct vattr	*vap;
363 	struct vnode	*vp;
364 	struct inode	*ip;
365 	struct ucred	*cred;
366 	struct proc	*p;
367 	int		error;
368 
369 	vap = ap->a_vap;
370 	vp = ap->a_vp;
371 	ip = VTOI(vp);
372 	cred = ap->a_cred;
373 	p = ap->a_p;
374 
375 	/*
376 	 * Check for unsettable attributes.
377 	 */
378 	if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
379 	    (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
380 	    (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
381 	    ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
382 		return (EINVAL);
383 	}
384 	if (vap->va_flags != VNOVAL) {
385 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
386 			return (EROFS);
387 		if (cred->cr_uid != ip->i_ffs_uid &&
388 		    (error = suser(cred, &p->p_acflag)))
389 			return (error);
390 		if (cred->cr_uid == 0) {
391 			if ((ip->i_ffs_flags & (SF_IMMUTABLE | SF_APPEND)) &&
392 			    securelevel > 0)
393 				return (EPERM);
394 			ip->i_ffs_flags = vap->va_flags;
395 		} else {
396 			if ((ip->i_ffs_flags & (SF_IMMUTABLE | SF_APPEND)) ||
397 			    (vap->va_flags & UF_SETTABLE) != vap->va_flags)
398 				return (EPERM);
399 			if ((ip->i_ffs_flags & SF_SETTABLE) !=
400 			    (vap->va_flags & SF_SETTABLE))
401 				return (EPERM);
402 			ip->i_ffs_flags &= SF_SETTABLE;
403 			ip->i_ffs_flags |= (vap->va_flags & UF_SETTABLE);
404 		}
405 		ip->i_flag |= IN_CHANGE;
406 		if (vap->va_flags & (IMMUTABLE | APPEND))
407 			return (0);
408 	}
409 	if (ip->i_ffs_flags & (IMMUTABLE | APPEND))
410 		return (EPERM);
411 	/*
412 	 * Go through the fields and update iff not VNOVAL.
413 	 */
414 	if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
415 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
416 			return (EROFS);
417 		error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, p);
418 		if (error)
419 			return (error);
420 	}
421 	if (vap->va_size != VNOVAL) {
422 		/*
423 		 * Disallow write attempts on read-only file systems;
424 		 * unless the file is a socket, fifo, or a block or
425 		 * character device resident on the file system.
426 		 */
427 		switch (vp->v_type) {
428 		case VDIR:
429 			return (EISDIR);
430 		case VLNK:
431 		case VREG:
432 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
433 				 return (EROFS);
434 			break;
435 		default:
436 			break;
437 		}
438 		error = VOP_TRUNCATE(vp, vap->va_size, 0, cred, p);
439 		if (error)
440 			return (error);
441 	}
442 	ip = VTOI(vp);
443 	if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
444 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
445 			return (EROFS);
446 		if (cred->cr_uid != ip->i_ffs_uid &&
447 		    (error = suser(cred, &p->p_acflag)) &&
448 		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
449 		    (error = VOP_ACCESS(vp, VWRITE, cred, p))))
450 			return (error);
451 		if (vap->va_atime.tv_sec != VNOVAL)
452 			if (!(vp->v_mount->mnt_flag & MNT_NOATIME))
453 				ip->i_flag |= IN_ACCESS;
454 		if (vap->va_mtime.tv_sec != VNOVAL)
455 			ip->i_flag |= IN_CHANGE | IN_UPDATE;
456 		error = VOP_UPDATE(vp, &vap->va_atime, &vap->va_mtime, 0);
457 		if (error)
458 			return (error);
459 	}
460 	error = 0;
461 	if (vap->va_mode != (mode_t)VNOVAL) {
462 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
463 			return (EROFS);
464 		error = ufs_chmod(vp, (int)vap->va_mode, cred, p);
465 	}
466 	VN_KNOTE(vp, NOTE_ATTRIB);
467 	return (error);
468 }
469 
470 /*
471  * Change the mode on a file.
472  * Inode must be locked before calling.
473  */
474 static int
475 ufs_chmod(struct vnode *vp, int mode, struct ucred *cred, struct proc *p)
476 {
477 	struct inode	*ip;
478 	int		error;
479 
480 	ip = VTOI(vp);
481 	if (cred->cr_uid != ip->i_ffs_uid &&
482 	    (error = suser(cred, &p->p_acflag)))
483 		return (error);
484 	if (cred->cr_uid) {
485 		if (vp->v_type != VDIR && (mode & S_ISTXT))
486 			return (EFTYPE);
487 		if (!groupmember(ip->i_ffs_gid, cred) && (mode & ISGID))
488 			return (EPERM);
489 	}
490 	ip->i_ffs_mode &= ~ALLPERMS;
491 	ip->i_ffs_mode |= (mode & ALLPERMS);
492 	ip->i_flag |= IN_CHANGE;
493 	return (0);
494 }
495 
496 /*
497  * Perform chown operation on inode ip;
498  * inode must be locked prior to call.
499  */
500 static int
501 ufs_chown(struct vnode *vp, uid_t uid, gid_t gid, struct ucred *cred,
502     	struct proc *p)
503 {
504 	struct inode	*ip;
505 	int		error;
506 #ifdef QUOTA
507 	uid_t		ouid;
508 	gid_t		ogid;
509 	int		i;
510 	long		change;
511 #endif
512 	ip = VTOI(vp);
513 	error = 0;
514 
515 	if (uid == (uid_t)VNOVAL)
516 		uid = ip->i_ffs_uid;
517 	if (gid == (gid_t)VNOVAL)
518 		gid = ip->i_ffs_gid;
519 	/*
520 	 * If we don't own the file, are trying to change the owner
521 	 * of the file, or are not a member of the target group,
522 	 * the caller's credentials must imply super-user privilege
523 	 * or the call fails.
524 	 */
525 	if ((cred->cr_uid != ip->i_ffs_uid || uid != ip->i_ffs_uid ||
526 	    (gid != ip->i_ffs_gid && !groupmember((gid_t)gid, cred))) &&
527 	    ((error = suser(cred, &p->p_acflag)) != 0))
528 		return (error);
529 
530 #ifdef QUOTA
531 	ogid = ip->i_ffs_gid;
532 	ouid = ip->i_ffs_uid;
533 	if ((error = getinoquota(ip)) != 0)
534 		return (error);
535 	if (ouid == uid) {
536 		dqrele(vp, ip->i_dquot[USRQUOTA]);
537 		ip->i_dquot[USRQUOTA] = NODQUOT;
538 	}
539 	if (ogid == gid) {
540 		dqrele(vp, ip->i_dquot[GRPQUOTA]);
541 		ip->i_dquot[GRPQUOTA] = NODQUOT;
542 	}
543 	change = ip->i_ffs_blocks;
544 	(void) chkdq(ip, -change, cred, CHOWN);
545 	(void) chkiq(ip, -1, cred, CHOWN);
546 	for (i = 0; i < MAXQUOTAS; i++) {
547 		dqrele(vp, ip->i_dquot[i]);
548 		ip->i_dquot[i] = NODQUOT;
549 	}
550 #endif
551 	ip->i_ffs_gid = gid;
552 	ip->i_ffs_uid = uid;
553 #ifdef QUOTA
554 	if ((error = getinoquota(ip)) == 0) {
555 		if (ouid == uid) {
556 			dqrele(vp, ip->i_dquot[USRQUOTA]);
557 			ip->i_dquot[USRQUOTA] = NODQUOT;
558 		}
559 		if (ogid == gid) {
560 			dqrele(vp, ip->i_dquot[GRPQUOTA]);
561 			ip->i_dquot[GRPQUOTA] = NODQUOT;
562 		}
563 		if ((error = chkdq(ip, change, cred, CHOWN)) == 0) {
564 			if ((error = chkiq(ip, 1, cred, CHOWN)) == 0)
565 				goto good;
566 			else
567 				(void) chkdq(ip, -change, cred, CHOWN|FORCE);
568 		}
569 		for (i = 0; i < MAXQUOTAS; i++) {
570 			dqrele(vp, ip->i_dquot[i]);
571 			ip->i_dquot[i] = NODQUOT;
572 		}
573 	}
574 	ip->i_ffs_gid = ogid;
575 	ip->i_ffs_uid = ouid;
576 	if (getinoquota(ip) == 0) {
577 		if (ouid == uid) {
578 			dqrele(vp, ip->i_dquot[USRQUOTA]);
579 			ip->i_dquot[USRQUOTA] = NODQUOT;
580 		}
581 		if (ogid == gid) {
582 			dqrele(vp, ip->i_dquot[GRPQUOTA]);
583 			ip->i_dquot[GRPQUOTA] = NODQUOT;
584 		}
585 		(void) chkdq(ip, change, cred, FORCE|CHOWN);
586 		(void) chkiq(ip, 1, cred, FORCE|CHOWN);
587 		(void) getinoquota(ip);
588 	}
589 	return (error);
590  good:
591 	if (getinoquota(ip))
592 		panic("chown: lost quota");
593 #endif /* QUOTA */
594 	ip->i_flag |= IN_CHANGE;
595 	return (0);
596 }
597 
598 int
599 ufs_remove(void *v)
600 {
601 	struct vop_remove_args /* {
602 		struct vnode		*a_dvp;
603 		struct vnode		*a_vp;
604 		struct componentname	*a_cnp;
605 	} */ *ap = v;
606 	struct vnode	*vp, *dvp;
607 	struct inode	*ip;
608 	int		error;
609 
610 	vp = ap->a_vp;
611 	dvp = ap->a_dvp;
612 	ip = VTOI(vp);
613 	if (vp->v_type == VDIR || (ip->i_ffs_flags & (IMMUTABLE | APPEND)) ||
614 	    (VTOI(dvp)->i_ffs_flags & APPEND))
615 		error = EPERM;
616 	else
617 		error = ufs_dirremove(dvp, ip, ap->a_cnp->cn_flags, 0);
618 	VN_KNOTE(vp, NOTE_DELETE);
619 	VN_KNOTE(dvp, NOTE_WRITE);
620 	if (dvp == vp)
621 		vrele(vp);
622 	else
623 		vput(vp);
624 	vput(dvp);
625 	return (error);
626 }
627 
628 /*
629  * link vnode call
630  */
631 int
632 ufs_link(void *v)
633 {
634 	struct vop_link_args /* {
635 		struct vnode *a_dvp;
636 		struct vnode *a_vp;
637 		struct componentname *a_cnp;
638 	} */ *ap = v;
639 	struct vnode		*vp, *dvp;
640 	struct componentname	*cnp;
641 	struct inode		*ip;
642 	struct direct		newdir;
643 	int			error;
644 
645 	dvp = ap->a_dvp;
646 	vp = ap->a_vp;
647 	cnp = ap->a_cnp;
648 #ifdef DIAGNOSTIC
649 	if ((cnp->cn_flags & HASBUF) == 0)
650 		panic("ufs_link: no name");
651 #endif
652 	if (vp->v_type == VDIR) {
653 		VOP_ABORTOP(dvp, cnp);
654 		error = EPERM;
655 		goto out2;
656 	}
657 	if (dvp->v_mount != vp->v_mount) {
658 		VOP_ABORTOP(dvp, cnp);
659 		error = EXDEV;
660 		goto out2;
661 	}
662 	if (dvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE))) {
663 		VOP_ABORTOP(dvp, cnp);
664 		goto out2;
665 	}
666 	ip = VTOI(vp);
667 	if ((nlink_t)ip->i_ffs_nlink >= LINK_MAX) {
668 		VOP_ABORTOP(dvp, cnp);
669 		error = EMLINK;
670 		goto out1;
671 	}
672 	if (ip->i_ffs_flags & (IMMUTABLE | APPEND)) {
673 		VOP_ABORTOP(dvp, cnp);
674 		error = EPERM;
675 		goto out1;
676 	}
677 	ip->i_ffs_effnlink++;
678 	ip->i_ffs_nlink++;
679 	ip->i_flag |= IN_CHANGE;
680 	if (DOINGSOFTDEP(vp))
681 		softdep_change_linkcnt(ip);
682 	error = VOP_UPDATE(vp, NULL, NULL, UPDATE_DIROP);
683 	if (!error) {
684 		ufs_makedirentry(ip, cnp, &newdir);
685 		error = ufs_direnter(dvp, vp, &newdir, cnp, NULL);
686 	}
687 	if (error) {
688 		ip->i_ffs_effnlink--;
689 		ip->i_ffs_nlink--;
690 		ip->i_flag |= IN_CHANGE;
691 		if (DOINGSOFTDEP(vp))
692 			softdep_change_linkcnt(ip);
693 	}
694 	PNBUF_PUT(cnp->cn_pnbuf);
695  out1:
696 	if (dvp != vp)
697 		VOP_UNLOCK(vp, 0);
698  out2:
699 	VN_KNOTE(vp, NOTE_LINK);
700 	VN_KNOTE(dvp, NOTE_WRITE);
701 	vput(dvp);
702 	return (error);
703 }
704 
705 /*
706  * whiteout vnode call
707  */
708 int
709 ufs_whiteout(void *v)
710 {
711 	struct vop_whiteout_args /* {
712 		struct vnode		*a_dvp;
713 		struct componentname	*a_cnp;
714 		int			a_flags;
715 	} */ *ap = v;
716 	struct vnode		*dvp;
717 	struct componentname	*cnp;
718 	struct direct		newdir;
719 	int			error;
720 
721 	dvp = ap->a_dvp;
722 	cnp = ap->a_cnp;
723 	error = 0;
724 	switch (ap->a_flags) {
725 	case LOOKUP:
726 		/* 4.4 format directories support whiteout operations */
727 		if (dvp->v_mount->mnt_maxsymlinklen > 0)
728 			return (0);
729 		return (EOPNOTSUPP);
730 
731 	case CREATE:
732 		/* create a new directory whiteout */
733 #ifdef DIAGNOSTIC
734 		if ((cnp->cn_flags & SAVENAME) == 0)
735 			panic("ufs_whiteout: missing name");
736 		if (dvp->v_mount->mnt_maxsymlinklen <= 0)
737 			panic("ufs_whiteout: old format filesystem");
738 #endif
739 
740 		newdir.d_ino = WINO;
741 		newdir.d_namlen = cnp->cn_namelen;
742 		memcpy(newdir.d_name, cnp->cn_nameptr,
743 		    (unsigned)cnp->cn_namelen + 1);
744 		newdir.d_type = DT_WHT;
745 		error = ufs_direnter(dvp, NULL, &newdir, cnp, NULL);
746 		break;
747 
748 	case DELETE:
749 		/* remove an existing directory whiteout */
750 #ifdef DIAGNOSTIC
751 		if (dvp->v_mount->mnt_maxsymlinklen <= 0)
752 			panic("ufs_whiteout: old format filesystem");
753 #endif
754 
755 		cnp->cn_flags &= ~DOWHITEOUT;
756 		error = ufs_dirremove(dvp, NULL, cnp->cn_flags, 0);
757 		break;
758 	default:
759 		panic("ufs_whiteout: unknown op");
760 		/* NOTREACHED */
761 	}
762 	if (cnp->cn_flags & HASBUF) {
763 		PNBUF_PUT(cnp->cn_pnbuf);
764 		cnp->cn_flags &= ~HASBUF;
765 	}
766 	return (error);
767 }
768 
769 
770 /*
771  * Rename system call.
772  * 	rename("foo", "bar");
773  * is essentially
774  *	unlink("bar");
775  *	link("foo", "bar");
776  *	unlink("foo");
777  * but ``atomically''.  Can't do full commit without saving state in the
778  * inode on disk which isn't feasible at this time.  Best we can do is
779  * always guarantee the target exists.
780  *
781  * Basic algorithm is:
782  *
783  * 1) Bump link count on source while we're linking it to the
784  *    target.  This also ensure the inode won't be deleted out
785  *    from underneath us while we work (it may be truncated by
786  *    a concurrent `trunc' or `open' for creation).
787  * 2) Link source to destination.  If destination already exists,
788  *    delete it first.
789  * 3) Unlink source reference to inode if still around. If a
790  *    directory was moved and the parent of the destination
791  *    is different from the source, patch the ".." entry in the
792  *    directory.
793  */
794 int
795 ufs_rename(void *v)
796 {
797 	struct vop_rename_args  /* {
798 		struct vnode		*a_fdvp;
799 		struct vnode		*a_fvp;
800 		struct componentname	*a_fcnp;
801 		struct vnode		*a_tdvp;
802 		struct vnode		*a_tvp;
803 		struct componentname	*a_tcnp;
804 	} */ *ap = v;
805 	struct vnode		*tvp, *tdvp, *fvp, *fdvp;
806 	struct componentname	*tcnp, *fcnp;
807 	struct inode		*ip, *xp, *dp;
808 	struct direct		newdir;
809 	int			doingdirectory, oldparent, newparent, error;
810 
811 	tvp = ap->a_tvp;
812 	tdvp = ap->a_tdvp;
813 	fvp = ap->a_fvp;
814 	fdvp = ap->a_fdvp;
815 	tcnp = ap->a_tcnp;
816 	fcnp = ap->a_fcnp;
817 	doingdirectory = oldparent = newparent = error = 0;
818 
819 #ifdef DIAGNOSTIC
820 	if ((tcnp->cn_flags & HASBUF) == 0 ||
821 	    (fcnp->cn_flags & HASBUF) == 0)
822 		panic("ufs_rename: no name");
823 #endif
824 	/*
825 	 * Check for cross-device rename.
826 	 */
827 	if ((fvp->v_mount != tdvp->v_mount) ||
828 	    (tvp && (fvp->v_mount != tvp->v_mount))) {
829 		error = EXDEV;
830  abortit:
831 		VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
832 		if (tdvp == tvp)
833 			vrele(tdvp);
834 		else
835 			vput(tdvp);
836 		if (tvp)
837 			vput(tvp);
838 		VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
839 		vrele(fdvp);
840 		vrele(fvp);
841 		return (error);
842 	}
843 
844 	/*
845 	 * Check if just deleting a link name.
846 	 */
847 	if (tvp && ((VTOI(tvp)->i_ffs_flags & (IMMUTABLE | APPEND)) ||
848 	    (VTOI(tdvp)->i_ffs_flags & APPEND))) {
849 		error = EPERM;
850 		goto abortit;
851 	}
852 	if (fvp == tvp) {
853 		if (fvp->v_type == VDIR) {
854 			error = EINVAL;
855 			goto abortit;
856 		}
857 
858 		/* Release destination completely. */
859 		VOP_ABORTOP(tdvp, tcnp);
860 		vput(tdvp);
861 		vput(tvp);
862 
863 		/* Delete source. */
864 		vrele(fvp);
865 		fcnp->cn_flags &= ~(MODMASK | SAVESTART);
866 		fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
867 		fcnp->cn_nameiop = DELETE;
868 		if ((error = relookup(fdvp, &fvp, fcnp))){
869 			/* relookup blew away fdvp */
870 			return (error);
871 		}
872 		return (VOP_REMOVE(fdvp, fvp, fcnp));
873 	}
874 	if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
875 		goto abortit;
876 	dp = VTOI(fdvp);
877 	ip = VTOI(fvp);
878 	if ((nlink_t) ip->i_ffs_nlink >= LINK_MAX) {
879 		VOP_UNLOCK(fvp, 0);
880 		error = EMLINK;
881 		goto abortit;
882 	}
883 	if ((ip->i_ffs_flags & (IMMUTABLE | APPEND)) ||
884 		(dp->i_ffs_flags & APPEND)) {
885 		VOP_UNLOCK(fvp, 0);
886 		error = EPERM;
887 		goto abortit;
888 	}
889 	if ((ip->i_ffs_mode & IFMT) == IFDIR) {
890 		/*
891 		 * Avoid ".", "..", and aliases of "." for obvious reasons.
892 		 */
893 		if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
894 		    dp == ip ||
895 		    (fcnp->cn_flags & ISDOTDOT) ||
896 		    (tcnp->cn_flags & ISDOTDOT) ||
897 		    (ip->i_flag & IN_RENAME)) {
898 			VOP_UNLOCK(fvp, 0);
899 			error = EINVAL;
900 			goto abortit;
901 		}
902 		ip->i_flag |= IN_RENAME;
903 		oldparent = dp->i_number;
904 		doingdirectory = 1;
905 	}
906 	VN_KNOTE(fdvp, NOTE_WRITE);		/* XXXLUKEM/XXX: right place? */
907 	/* vrele(fdvp); */
908 
909 	/*
910 	 * When the target exists, both the directory
911 	 * and target vnodes are returned locked.
912 	 */
913 	dp = VTOI(tdvp);
914 	xp = NULL;
915 	if (tvp)
916 		xp = VTOI(tvp);
917 
918 	/*
919 	 * 1) Bump link count while we're moving stuff
920 	 *    around.  If we crash somewhere before
921 	 *    completing our work, the link count
922 	 *    may be wrong, but correctable.
923 	 */
924 	ip->i_ffs_effnlink++;
925 	ip->i_ffs_nlink++;
926 	ip->i_flag |= IN_CHANGE;
927 	if (DOINGSOFTDEP(fvp))
928 		softdep_change_linkcnt(ip);
929 	if ((error = VOP_UPDATE(fvp, NULL, NULL, UPDATE_DIROP)) != 0) {
930 		VOP_UNLOCK(fvp, 0);
931 		goto bad;
932 	}
933 
934 	/*
935 	 * If ".." must be changed (ie the directory gets a new
936 	 * parent) then the source directory must not be in the
937 	 * directory hierarchy above the target, as this would
938 	 * orphan everything below the source directory. Also
939 	 * the user must have write permission in the source so
940 	 * as to be able to change "..". We must repeat the call
941 	 * to namei, as the parent directory is unlocked by the
942 	 * call to checkpath().
943 	 */
944 	error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_proc);
945 	VOP_UNLOCK(fvp, 0);
946 	if (oldparent != dp->i_number)
947 		newparent = dp->i_number;
948 	if (doingdirectory && newparent) {
949 		if (error)	/* write access check above */
950 			goto bad;
951 		if (xp != NULL)
952 			vput(tvp);
953 		vref(tdvp);	/* compensate for the ref checkpath looses */
954 		if ((error = ufs_checkpath(ip, dp, tcnp->cn_cred)) != 0) {
955 			vrele(tdvp);
956 			goto out;
957 		}
958 		tcnp->cn_flags &= ~SAVESTART;
959 		if ((error = relookup(tdvp, &tvp, tcnp)) != 0)
960 			goto out;
961 		dp = VTOI(tdvp);
962 		xp = NULL;
963 		if (tvp)
964 			xp = VTOI(tvp);
965 	}
966 	/*
967 	 * 2) If target doesn't exist, link the target
968 	 *    to the source and unlink the source.
969 	 *    Otherwise, rewrite the target directory
970 	 *    entry to reference the source inode and
971 	 *    expunge the original entry's existence.
972 	 */
973 	if (xp == NULL) {
974 		if (dp->i_dev != ip->i_dev)
975 			panic("rename: EXDEV");
976 		/*
977 		 * Account for ".." in new directory.
978 		 * When source and destination have the same
979 		 * parent we don't fool with the link count.
980 		 */
981 		if (doingdirectory && newparent) {
982 			if ((nlink_t)dp->i_ffs_nlink >= LINK_MAX) {
983 				error = EMLINK;
984 				goto bad;
985 			}
986 			dp->i_ffs_effnlink++;
987 			dp->i_ffs_nlink++;
988 			dp->i_flag |= IN_CHANGE;
989 			if (DOINGSOFTDEP(tdvp))
990 				softdep_change_linkcnt(dp);
991 			if ((error = VOP_UPDATE(tdvp, NULL, NULL,
992 			    UPDATE_DIROP)) != 0) {
993 				dp->i_ffs_effnlink--;
994 				dp->i_ffs_nlink--;
995 				dp->i_flag |= IN_CHANGE;
996 				if (DOINGSOFTDEP(tdvp))
997 					softdep_change_linkcnt(dp);
998 				goto bad;
999 			}
1000 		}
1001 		ufs_makedirentry(ip, tcnp, &newdir);
1002 		error = ufs_direnter(tdvp, NULL, &newdir, tcnp, NULL);
1003 		if (error != 0) {
1004 			if (doingdirectory && newparent) {
1005 				dp->i_ffs_effnlink--;
1006 				dp->i_ffs_nlink--;
1007 				dp->i_flag |= IN_CHANGE;
1008 				if (DOINGSOFTDEP(tdvp))
1009 					softdep_change_linkcnt(dp);
1010 				(void)VOP_UPDATE(tdvp, NULL, NULL,
1011 						 UPDATE_WAIT|UPDATE_DIROP);
1012 			}
1013 			goto bad;
1014 		}
1015 		VN_KNOTE(tdvp, NOTE_WRITE);
1016 		vput(tdvp);
1017 	} else {
1018 		if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev)
1019 			panic("rename: EXDEV");
1020 		/*
1021 		 * Short circuit rename(foo, foo).
1022 		 */
1023 		if (xp->i_number == ip->i_number)
1024 			panic("rename: same file");
1025 		/*
1026 		 * If the parent directory is "sticky", then the user must
1027 		 * own the parent directory, or the destination of the rename,
1028 		 * otherwise the destination may not be changed (except by
1029 		 * root). This implements append-only directories.
1030 		 */
1031 		if ((dp->i_ffs_mode & S_ISTXT) && tcnp->cn_cred->cr_uid != 0 &&
1032 		    tcnp->cn_cred->cr_uid != dp->i_ffs_uid &&
1033 		    xp->i_ffs_uid != tcnp->cn_cred->cr_uid) {
1034 			error = EPERM;
1035 			goto bad;
1036 		}
1037 		/*
1038 		 * Target must be empty if a directory and have no links
1039 		 * to it. Also, ensure source and target are compatible
1040 		 * (both directories, or both not directories).
1041 		 */
1042 		if ((xp->i_ffs_mode & IFMT) == IFDIR) {
1043 			if (xp->i_ffs_effnlink > 2 ||
1044 			    !ufs_dirempty(xp, dp->i_number, tcnp->cn_cred)) {
1045 				error = ENOTEMPTY;
1046 				goto bad;
1047 			}
1048 			if (!doingdirectory) {
1049 				error = ENOTDIR;
1050 				goto bad;
1051 			}
1052 			cache_purge(tdvp);
1053 		} else if (doingdirectory) {
1054 			error = EISDIR;
1055 			goto bad;
1056 		}
1057 		if ((error = ufs_dirrewrite(dp, xp, ip->i_number,
1058 		    IFTODT(ip->i_ffs_mode), doingdirectory && newparent ?
1059 		    newparent : doingdirectory)) != 0)
1060 			goto bad;
1061 		if (doingdirectory) {
1062 			if (!newparent) {
1063 				dp->i_ffs_effnlink--;
1064 				if (DOINGSOFTDEP(tdvp))
1065 					softdep_change_linkcnt(dp);
1066 			}
1067 			xp->i_ffs_effnlink--;
1068 			if (DOINGSOFTDEP(tvp))
1069 				softdep_change_linkcnt(xp);
1070 		}
1071 		if (doingdirectory && !DOINGSOFTDEP(tvp)) {
1072 			/*
1073 			 * Truncate inode. The only stuff left in the directory
1074 			 * is "." and "..". The "." reference is inconsequential
1075 			 * since we are quashing it. We have removed the "."
1076 			 * reference and the reference in the parent directory,
1077 			 * but there may be other hard links. The soft
1078 			 * dependency code will arrange to do these operations
1079 			 * after the parent directory entry has been deleted on
1080 			 * disk, so when running with that code we avoid doing
1081 			 * them now.
1082 			 */
1083 			if (!newparent) {
1084 				dp->i_ffs_nlink--;
1085 				dp->i_flag |= IN_CHANGE;
1086 			}
1087 			xp->i_ffs_nlink--;
1088 			xp->i_flag |= IN_CHANGE;
1089 			if ((error = VOP_TRUNCATE(tvp, (off_t)0, IO_SYNC,
1090 			    tcnp->cn_cred, tcnp->cn_proc)))
1091 				goto bad;
1092 		}
1093 		VN_KNOTE(tdvp, NOTE_WRITE);
1094 		vput(tdvp);
1095 		VN_KNOTE(tvp, NOTE_DELETE);
1096 		vput(tvp);
1097 		xp = NULL;
1098 	}
1099 
1100 	/*
1101 	 * 3) Unlink the source.
1102 	 */
1103 	fcnp->cn_flags &= ~(MODMASK | SAVESTART);
1104 	fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
1105 	if ((error = relookup(fdvp, &fvp, fcnp))) {
1106 		vrele(ap->a_fvp);
1107 		return (error);
1108 	}
1109 	if (fvp != NULL) {
1110 		xp = VTOI(fvp);
1111 		dp = VTOI(fdvp);
1112 	} else {
1113 		/*
1114 		 * From name has disappeared.
1115 		 */
1116 		if (doingdirectory)
1117 			panic("rename: lost dir entry");
1118 		vrele(ap->a_fvp);
1119 		return (0);
1120 	}
1121 	/*
1122 	 * Ensure that the directory entry still exists and has not
1123 	 * changed while the new name has been entered. If the source is
1124 	 * a file then the entry may have been unlinked or renamed. In
1125 	 * either case there is no further work to be done. If the source
1126 	 * is a directory then it cannot have been rmdir'ed; The IRENAME
1127 	 * flag ensures that it cannot be moved by another rename or removed
1128 	 * by a rmdir.
1129 	 */
1130 	if (xp != ip) {
1131 		if (doingdirectory)
1132 			panic("rename: lost dir entry");
1133 	} else {
1134 		/*
1135 		 * If the source is a directory with a
1136 		 * new parent, the link count of the old
1137 		 * parent directory must be decremented
1138 		 * and ".." set to point to the new parent.
1139 		 */
1140 		if (doingdirectory && newparent) {
1141 			xp->i_offset = mastertemplate.dot_reclen;
1142 			ufs_dirrewrite(xp, dp, newparent, DT_DIR, 0);
1143 			cache_purge(fdvp);
1144 		}
1145 		error = ufs_dirremove(fdvp, xp, fcnp->cn_flags, 0);
1146 		xp->i_flag &= ~IN_RENAME;
1147 	}
1148 	VN_KNOTE(fvp, NOTE_RENAME);
1149 	if (dp)
1150 		vput(fdvp);
1151 	if (xp)
1152 		vput(fvp);
1153 	vrele(ap->a_fvp);
1154 	return (error);
1155 
1156 	/* exit routines from steps 1 & 2 */
1157  bad:
1158 	if (xp)
1159 		vput(ITOV(xp));
1160 	vput(ITOV(dp));
1161  out:
1162 	if (doingdirectory)
1163 		ip->i_flag &= ~IN_RENAME;
1164 	if (vn_lock(fvp, LK_EXCLUSIVE) == 0) {
1165 		ip->i_ffs_effnlink--;
1166 		ip->i_ffs_nlink--;
1167 		ip->i_flag |= IN_CHANGE;
1168 		if (DOINGSOFTDEP(fvp))
1169 			softdep_change_linkcnt(ip);
1170 		vput(fvp);
1171 	} else
1172 		vrele(fvp);
1173 	vrele(fdvp);
1174 	return (error);
1175 }
1176 
1177 /*
1178  * Mkdir system call
1179  */
1180 int
1181 ufs_mkdir(void *v)
1182 {
1183 	struct vop_mkdir_args /* {
1184 		struct vnode		*a_dvp;
1185 		struct vnode		**a_vpp;
1186 		struct componentname	*a_cnp;
1187 		struct vattr		*a_vap;
1188 	} */ *ap = v;
1189 	struct vnode		*dvp, *tvp;
1190 	struct vattr		*vap;
1191 	struct componentname *cnp;
1192 	struct inode		*ip, *dp;
1193 	struct buf		*bp;
1194 	struct dirtemplate	dirtemplate;
1195 	struct direct		newdir;
1196 	int			error, dmode, blkoff;
1197 	int dirblksiz = DIRBLKSIZ;
1198 	if (UFS_MPISAPPLEUFS(ap->a_dvp->v_mount)) {
1199 		dirblksiz = APPLEUFS_DIRBLKSIZ;
1200 	}
1201 
1202 	dvp = ap->a_dvp;
1203 	vap = ap->a_vap;
1204 	cnp = ap->a_cnp;
1205 #ifdef DIAGNOSTIC
1206 	if ((cnp->cn_flags & HASBUF) == 0)
1207 		panic("ufs_mkdir: no name");
1208 #endif
1209 	dp = VTOI(dvp);
1210 	if ((nlink_t)dp->i_ffs_nlink >= LINK_MAX) {
1211 		error = EMLINK;
1212 		goto out;
1213 	}
1214 	dmode = vap->va_mode & ACCESSPERMS;
1215 	dmode |= IFDIR;
1216 	/*
1217 	 * Must simulate part of ufs_makeinode here to acquire the inode,
1218 	 * but not have it entered in the parent directory. The entry is
1219 	 * made later after writing "." and ".." entries.
1220 	 */
1221 	if ((error = VOP_VALLOC(dvp, dmode, cnp->cn_cred, &tvp)) != 0)
1222 		goto out;
1223 	ip = VTOI(tvp);
1224 	ip->i_ffs_uid = cnp->cn_cred->cr_uid;
1225 	ip->i_ffs_gid = dp->i_ffs_gid;
1226 #ifdef QUOTA
1227 	if ((error = getinoquota(ip)) ||
1228 	    (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
1229 		PNBUF_PUT(cnp->cn_pnbuf);
1230 		VOP_VFREE(tvp, ip->i_number, dmode);
1231 		vput(tvp);
1232 		vput(dvp);
1233 		return (error);
1234 	}
1235 #endif
1236 	ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
1237 	ip->i_ffs_mode = dmode;
1238 	tvp->v_type = VDIR;	/* Rest init'd in getnewvnode(). */
1239 	ip->i_ffs_effnlink = 2;
1240 	ip->i_ffs_nlink = 2;
1241 	if (DOINGSOFTDEP(tvp))
1242 		softdep_change_linkcnt(ip);
1243 	if (cnp->cn_flags & ISWHITEOUT)
1244 		ip->i_ffs_flags |= UF_OPAQUE;
1245 
1246 	/*
1247 	 * Bump link count in parent directory to reflect work done below.
1248 	 * Should be done before reference is created so cleanup is
1249 	 * possible if we crash.
1250 	 */
1251 	dp->i_ffs_effnlink++;
1252 	dp->i_ffs_nlink++;
1253 	dp->i_flag |= IN_CHANGE;
1254 	if (DOINGSOFTDEP(dvp))
1255 		softdep_change_linkcnt(dp);
1256 	if ((error = VOP_UPDATE(dvp, NULL, NULL, UPDATE_DIROP)) != 0)
1257 		goto bad;
1258 
1259 	/*
1260 	 * Initialize directory with "." and ".." from static template.
1261 	 */
1262 	dirtemplate = mastertemplate;
1263 	dirtemplate.dotdot_reclen = dirblksiz - dirtemplate.dot_reclen;
1264 	dirtemplate.dot_ino = ufs_rw32(ip->i_number,
1265 	    UFS_MPNEEDSWAP(dvp->v_mount));
1266 	dirtemplate.dotdot_ino = ufs_rw32(dp->i_number,
1267 	    UFS_MPNEEDSWAP(dvp->v_mount));
1268 	dirtemplate.dot_reclen = ufs_rw16(dirtemplate.dot_reclen,
1269 	    UFS_MPNEEDSWAP(dvp->v_mount));
1270 	dirtemplate.dotdot_reclen = ufs_rw16(dirtemplate.dotdot_reclen,
1271 	    UFS_MPNEEDSWAP(dvp->v_mount));
1272 	if (dvp->v_mount->mnt_maxsymlinklen <= 0) {
1273 #if BYTE_ORDER == LITTLE_ENDIAN
1274 		if (UFS_MPNEEDSWAP(dvp->v_mount) == 0)
1275 #else
1276 		if (UFS_MPNEEDSWAP(dvp->v_mount) != 0)
1277 #endif
1278 		{
1279 			dirtemplate.dot_type = dirtemplate.dot_namlen;
1280 			dirtemplate.dotdot_type = dirtemplate.dotdot_namlen;
1281 			dirtemplate.dot_namlen = dirtemplate.dotdot_namlen = 0;
1282 		} else
1283 			dirtemplate.dot_type = dirtemplate.dotdot_type = 0;
1284 	}
1285 	if ((error = VOP_BALLOC(tvp, (off_t)0, dirblksiz, cnp->cn_cred,
1286 	    B_CLRBUF, &bp)) != 0)
1287 		goto bad;
1288 	ip->i_ffs_size = dirblksiz;
1289 	ip->i_flag |= IN_CHANGE | IN_UPDATE;
1290 	uvm_vnp_setsize(tvp, ip->i_ffs_size);
1291 	memcpy((caddr_t)bp->b_data, (caddr_t)&dirtemplate, sizeof dirtemplate);
1292 	if (DOINGSOFTDEP(tvp)) {
1293 		/*
1294 		 * Ensure that the entire newly allocated block is a
1295 		 * valid directory so that future growth within the
1296 		 * block does not have to ensure that the block is
1297 		 * written before the inode.
1298 		 */
1299 		blkoff = dirblksiz;
1300 		while (blkoff < bp->b_bcount) {
1301 			((struct direct *)
1302 			  (bp->b_data + blkoff))->d_reclen = dirblksiz;
1303 			blkoff += dirblksiz;
1304 		}
1305 	}
1306 	/*
1307 	 * Directory set up, now install it's entry in the parent directory.
1308 	 *
1309 	 * If we are not doing soft dependencies, then we must write out the
1310 	 * buffer containing the new directory body before entering the new
1311 	 * name in the parent. If we are doing soft dependencies, then the
1312 	 * buffer containing the new directory body will be passed to and
1313 	 * released in the soft dependency code after the code has attached
1314 	 * an appropriate ordering dependency to the buffer which ensures that
1315 	 * the buffer is written before the new name is written in the parent.
1316 	 */
1317 	if (!DOINGSOFTDEP(tvp) && ((error = VOP_BWRITE(bp)) != 0))
1318 		goto bad;
1319 	if ((error = VOP_UPDATE(tvp, NULL, NULL, UPDATE_DIROP)) != 0) {
1320 		if (DOINGSOFTDEP(tvp))
1321 			(void)VOP_BWRITE(bp);
1322 		goto bad;
1323 	}
1324 	ufs_makedirentry(ip, cnp, &newdir);
1325 	error = ufs_direnter(dvp, tvp, &newdir, cnp, bp);
1326  bad:
1327 	if (error == 0) {
1328 		VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
1329 		*ap->a_vpp = tvp;
1330 	} else {
1331 		dp->i_ffs_effnlink--;
1332 		dp->i_ffs_nlink--;
1333 		dp->i_flag |= IN_CHANGE;
1334 		if (DOINGSOFTDEP(dvp))
1335 			softdep_change_linkcnt(dp);
1336 		/*
1337 		 * No need to do an explicit VOP_TRUNCATE here, vrele will
1338 		 * do this for us because we set the link count to 0.
1339 		 */
1340 		ip->i_ffs_effnlink = 0;
1341 		ip->i_ffs_nlink = 0;
1342 		ip->i_flag |= IN_CHANGE;
1343 #ifdef LFS
1344 		/* If IN_ADIROP, account for it */
1345 		lfs_unmark_vnode(tvp);
1346 #endif
1347 		if (DOINGSOFTDEP(tvp))
1348 			softdep_change_linkcnt(ip);
1349 		vput(tvp);
1350 	}
1351  out:
1352 	PNBUF_PUT(cnp->cn_pnbuf);
1353 	vput(dvp);
1354 	return (error);
1355 }
1356 
1357 /*
1358  * Rmdir system call.
1359  */
1360 int
1361 ufs_rmdir(void *v)
1362 {
1363 	struct vop_rmdir_args /* {
1364 		struct vnode		*a_dvp;
1365 		struct vnode		*a_vp;
1366 		struct componentname	*a_cnp;
1367 	} */ *ap = v;
1368 	struct vnode		*vp, *dvp;
1369 	struct componentname	*cnp;
1370 	struct inode		*ip, *dp;
1371 	int			error;
1372 
1373 	vp = ap->a_vp;
1374 	dvp = ap->a_dvp;
1375 	cnp = ap->a_cnp;
1376 	ip = VTOI(vp);
1377 	dp = VTOI(dvp);
1378 	/*
1379 	 * No rmdir "." or of mounted directories please.
1380 	 */
1381 	if (dp == ip || vp->v_mountedhere != NULL) {
1382 		vrele(dvp);
1383 		if (vp->v_mountedhere != NULL)
1384 			VOP_UNLOCK(dvp, 0);
1385 		vput(vp);
1386 		return (EINVAL);
1387 	}
1388 	/*
1389 	 * Do not remove a directory that is in the process of being renamed.
1390 	 * Verify that the directory is empty (and valid). (Rmdir ".." won't
1391 	 * be valid since ".." will contain a reference to the current
1392 	 * directory and thus be non-empty.)
1393 	 */
1394 	error = 0;
1395 	if (ip->i_flag & IN_RENAME) {
1396 		error = EINVAL;
1397 		goto out;
1398 	}
1399 	if (ip->i_ffs_effnlink != 2 ||
1400 	    !ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) {
1401 		error = ENOTEMPTY;
1402 		goto out;
1403 	}
1404 	if ((dp->i_ffs_flags & APPEND) ||
1405 		(ip->i_ffs_flags & (IMMUTABLE | APPEND))) {
1406 		error = EPERM;
1407 		goto out;
1408 	}
1409 	/*
1410 	 * Delete reference to directory before purging
1411 	 * inode.  If we crash in between, the directory
1412 	 * will be reattached to lost+found,
1413 	 */
1414 	dp->i_ffs_effnlink--;
1415 	ip->i_ffs_effnlink--;
1416 	if (DOINGSOFTDEP(vp)) {
1417 		softdep_change_linkcnt(dp);
1418 		softdep_change_linkcnt(ip);
1419 	}
1420 	error = ufs_dirremove(dvp, ip, cnp->cn_flags, 1);
1421 	if (error) {
1422 		dp->i_ffs_effnlink++;
1423 		ip->i_ffs_effnlink++;
1424 		if (DOINGSOFTDEP(vp)) {
1425 			softdep_change_linkcnt(dp);
1426 			softdep_change_linkcnt(ip);
1427 		}
1428 		goto out;
1429 	}
1430 	VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
1431 	cache_purge(dvp);
1432 	/*
1433 	 * Truncate inode.  The only stuff left in the directory is "." and
1434 	 * "..".  The "." reference is inconsequential since we're quashing
1435 	 * it. The soft dependency code will arrange to do these operations
1436 	 * after the parent directory entry has been deleted on disk, so
1437 	 * when running with that code we avoid doing them now.
1438 	 */
1439 	if (!DOINGSOFTDEP(vp)) {
1440 		dp->i_ffs_nlink--;
1441 		dp->i_flag |= IN_CHANGE;
1442 		ip->i_ffs_nlink--;
1443 		ip->i_flag |= IN_CHANGE;
1444 		error = VOP_TRUNCATE(vp, (off_t)0, IO_SYNC, cnp->cn_cred,
1445 		    cnp->cn_proc);
1446 	}
1447 	cache_purge(vp);
1448  out:
1449 	VN_KNOTE(vp, NOTE_DELETE);
1450 	vput(dvp);
1451 	vput(vp);
1452 	return (error);
1453 }
1454 
1455 /*
1456  * symlink -- make a symbolic link
1457  */
1458 int
1459 ufs_symlink(void *v)
1460 {
1461 	struct vop_symlink_args /* {
1462 		struct vnode		*a_dvp;
1463 		struct vnode		**a_vpp;
1464 		struct componentname	*a_cnp;
1465 		struct vattr		*a_vap;
1466 		char			*a_target;
1467 	} */ *ap = v;
1468 	struct vnode	*vp, **vpp;
1469 	struct inode	*ip;
1470 	int		len, error;
1471 
1472 	vpp = ap->a_vpp;
1473 	error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
1474 			      vpp, ap->a_cnp);
1475 	if (error)
1476 		return (error);
1477 	VN_KNOTE(ap->a_dvp, NOTE_WRITE);
1478 	vp = *vpp;
1479 	len = strlen(ap->a_target);
1480 	if (len < vp->v_mount->mnt_maxsymlinklen) {
1481 		ip = VTOI(vp);
1482 		memcpy((char *)ip->i_ffs_shortlink, ap->a_target, len);
1483 		ip->i_ffs_size = len;
1484 		uvm_vnp_setsize(vp, ip->i_ffs_size);
1485 		ip->i_flag |= IN_CHANGE | IN_UPDATE;
1486 	} else
1487 		error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
1488 		    UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, NULL,
1489 		    (struct proc *)0);
1490 	if (error)
1491 		vput(vp);
1492 	return (error);
1493 }
1494 
1495 /*
1496  * Vnode op for reading directories.
1497  *
1498  * The routine below assumes that the on-disk format of a directory
1499  * is the same as that defined by <sys/dirent.h>. If the on-disk
1500  * format changes, then it will be necessary to do a conversion
1501  * from the on-disk format that read returns to the format defined
1502  * by <sys/dirent.h>.
1503  */
1504 int
1505 ufs_readdir(void *v)
1506 {
1507 	struct vop_readdir_args /* {
1508 		struct vnode	*a_vp;
1509 		struct uio	*a_uio;
1510 		struct ucred	*a_cred;
1511 		int		*a_eofflag;
1512 		off_t		**a_cookies;
1513 		int		*ncookies;
1514 	} */ *ap = v;
1515 	struct uio	*uio;
1516 	int		error;
1517 	size_t		count, lost;
1518 	off_t		off;
1519 	int dirblksiz = DIRBLKSIZ;
1520 	if (UFS_MPISAPPLEUFS(ap->a_vp->v_mount)) {
1521 		dirblksiz = APPLEUFS_DIRBLKSIZ;
1522 	}
1523 
1524 	uio = ap->a_uio;
1525 	off = uio->uio_offset;
1526 	count = uio->uio_resid;
1527 	/* Make sure we don't return partial entries. */
1528 	count -= (uio->uio_offset + count) & (dirblksiz -1);
1529 	if (count <= 0)
1530 		return (EINVAL);
1531 	lost = uio->uio_resid - count;
1532 	uio->uio_resid = count;
1533 	uio->uio_iov->iov_len = count;
1534 #if BYTE_ORDER == LITTLE_ENDIAN
1535 	if (ap->a_vp->v_mount->mnt_maxsymlinklen > 0 &&
1536 	    UFS_MPNEEDSWAP(ap->a_vp->v_mount) == 0)
1537 #else
1538 	if (UFS_MPNEEDSWAP(ap->a_vp->v_mount) == 0)
1539 #endif
1540 	{
1541 		error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
1542 	} else {
1543 		struct dirent	*dp, *edp;
1544 		struct uio	auio;
1545 		struct iovec	aiov;
1546 		caddr_t		dirbuf;
1547 		int		readcnt;
1548 		u_char		tmp;
1549 
1550 		auio = *uio;
1551 		auio.uio_iov = &aiov;
1552 		auio.uio_iovcnt = 1;
1553 		auio.uio_segflg = UIO_SYSSPACE;
1554 		aiov.iov_len = count;
1555 		MALLOC(dirbuf, caddr_t, count, M_TEMP, M_WAITOK);
1556 		aiov.iov_base = dirbuf;
1557 		error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred);
1558 		if (error == 0) {
1559 			readcnt = count - auio.uio_resid;
1560 			edp = (struct dirent *)&dirbuf[readcnt];
1561 			for (dp = (struct dirent *)dirbuf; dp < edp; ) {
1562 #if BYTE_ORDER == LITTLE_ENDIAN
1563 				if (ap->a_vp->v_mount->mnt_maxsymlinklen <= 0 &&
1564 					UFS_MPNEEDSWAP(ap->a_vp->v_mount) == 0)
1565 #else
1566 				if (ap->a_vp->v_mount->mnt_maxsymlinklen <= 0 &&
1567 					UFS_MPNEEDSWAP(ap->a_vp->v_mount) != 0)
1568 #endif
1569 				{
1570 					tmp = dp->d_namlen;
1571 					dp->d_namlen = dp->d_type;
1572 					dp->d_type = tmp;
1573 				}
1574 				dp->d_fileno = ufs_rw32(dp->d_fileno,
1575 				    UFS_MPNEEDSWAP(ap->a_vp->v_mount));
1576 				dp->d_reclen = ufs_rw16(dp->d_reclen,
1577 				    UFS_MPNEEDSWAP(ap->a_vp->v_mount));
1578 				if (dp->d_reclen > 0) {
1579 					dp = (struct dirent *)
1580 					    ((char *)dp + dp->d_reclen);
1581 				} else {
1582 					error = EIO;
1583 					break;
1584 				}
1585 			}
1586 			if (dp >= edp)
1587 				error = uiomove(dirbuf, readcnt, uio);
1588 		}
1589 		FREE(dirbuf, M_TEMP);
1590 	}
1591 	if (!error && ap->a_ncookies) {
1592 		struct dirent	*dp, *dpstart;
1593 		off_t		*cookies, offstart;
1594 		int		ncookies;
1595 
1596 		/*
1597 		 * Only the NFS server and emulations use cookies, and they
1598 		 * load the directory block into system space, so we can
1599 		 * just look at it directly.
1600 		 */
1601 		if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
1602 			panic("ufs_readdir: lost in space");
1603 		dpstart = (struct dirent *)
1604 		    ((caddr_t)uio->uio_iov->iov_base - (uio->uio_offset - off));
1605 		offstart = off;
1606 		for (dp = dpstart, ncookies = 0; off < uio->uio_offset; ) {
1607 			if (dp->d_reclen == 0)
1608 				break;
1609 			off += dp->d_reclen;
1610 			ncookies++;
1611 			dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
1612 		}
1613 		lost += uio->uio_offset - off;
1614 		cookies = malloc(ncookies * sizeof(off_t), M_TEMP, M_WAITOK);
1615 		uio->uio_offset = off;
1616 		*ap->a_ncookies = ncookies;
1617 		*ap->a_cookies = cookies;
1618 		for (off = offstart, dp = dpstart; off < uio->uio_offset; ) {
1619 			off += dp->d_reclen;
1620 			*(cookies++) = off;
1621 			dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
1622 		}
1623 	}
1624 	uio->uio_resid += lost;
1625 	*ap->a_eofflag = VTOI(ap->a_vp)->i_ffs_size <= uio->uio_offset;
1626 	return (error);
1627 }
1628 
1629 /*
1630  * Return target name of a symbolic link
1631  */
1632 int
1633 ufs_readlink(void *v)
1634 {
1635 	struct vop_readlink_args /* {
1636 		struct vnode	*a_vp;
1637 		struct uio	*a_uio;
1638 		struct ucred	*a_cred;
1639 	} */ *ap = v;
1640 	struct vnode	*vp;
1641 	struct inode	*ip;
1642 	int		isize;
1643 
1644 	vp = ap->a_vp;
1645 	ip = VTOI(vp);
1646 	isize = ip->i_ffs_size;
1647 	if (isize < vp->v_mount->mnt_maxsymlinklen ||
1648 	    (vp->v_mount->mnt_maxsymlinklen == 0 && ip->i_ffs_blocks == 0)) {
1649 		uiomove((char *)ip->i_ffs_shortlink, isize, ap->a_uio);
1650 		return (0);
1651 	}
1652 	return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred));
1653 }
1654 
1655 /*
1656  * Calculate the logical to physical mapping if not done already,
1657  * then call the device strategy routine.
1658  */
1659 int
1660 ufs_strategy(void *v)
1661 {
1662 	struct vop_strategy_args /* {
1663 		struct buf *a_bp;
1664 	} */ *ap = v;
1665 	struct buf	*bp;
1666 	struct vnode	*vp;
1667 	struct inode	*ip;
1668 	int		error;
1669 
1670 	bp = ap->a_bp;
1671 	vp = bp->b_vp;
1672 	ip = VTOI(vp);
1673 	if (vp->v_type == VBLK || vp->v_type == VCHR)
1674 		panic("ufs_strategy: spec");
1675 	KASSERT(bp->b_bcount != 0);
1676 	if (bp->b_blkno == bp->b_lblkno) {
1677 		error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno,
1678 				 NULL);
1679 		if (error) {
1680 			bp->b_error = error;
1681 			bp->b_flags |= B_ERROR;
1682 			biodone(bp);
1683 			return (error);
1684 		}
1685 		if ((long)bp->b_blkno == -1) /* no valid data */
1686 			clrbuf(bp);
1687 	}
1688 	if ((long)bp->b_blkno < 0) { /* block is not on disk */
1689 		biodone(bp);
1690 		return (0);
1691 	}
1692 	vp = ip->i_devvp;
1693 	bp->b_dev = vp->v_rdev;
1694 	VOCALL (vp->v_op, VOFFSET(vop_strategy), ap);
1695 	return (0);
1696 }
1697 
1698 /*
1699  * Print out the contents of an inode.
1700  */
1701 int
1702 ufs_print(void *v)
1703 {
1704 	struct vop_print_args /* {
1705 		struct vnode	*a_vp;
1706 	} */ *ap = v;
1707 	struct vnode	*vp;
1708 	struct inode	*ip;
1709 
1710 	vp = ap->a_vp;
1711 	ip = VTOI(vp);
1712 	printf("tag VT_UFS, ino %d, on dev %d, %d", ip->i_number,
1713 	    major(ip->i_dev), minor(ip->i_dev));
1714 	printf(" flags 0x%x, effnlink %d, nlink %d\n",
1715 	    ip->i_flag, ip->i_ffs_effnlink, ip->i_ffs_nlink);
1716 	printf("\tmode 0%o, owner %d, group %d, size %qd",
1717 	    ip->i_ffs_mode, ip->i_ffs_uid, ip->i_ffs_gid,
1718 	    (long long)ip->i_ffs_size);
1719 	if (vp->v_type == VFIFO)
1720 		fifo_printinfo(vp);
1721 	lockmgr_printinfo(&vp->v_lock);
1722 	printf("\n");
1723 	return (0);
1724 }
1725 
1726 /*
1727  * Read wrapper for special devices.
1728  */
1729 int
1730 ufsspec_read(void *v)
1731 {
1732 	struct vop_read_args /* {
1733 		struct vnode	*a_vp;
1734 		struct uio	*a_uio;
1735 		int		a_ioflag;
1736 		struct ucred	*a_cred;
1737 	} */ *ap = v;
1738 
1739 	/*
1740 	 * Set access flag.
1741 	 */
1742 	if ((ap->a_vp->v_mount->mnt_flag & MNT_NODEVMTIME) == 0)
1743 		VTOI(ap->a_vp)->i_flag |= IN_ACCESS;
1744 	return (VOCALL (spec_vnodeop_p, VOFFSET(vop_read), ap));
1745 }
1746 
1747 /*
1748  * Write wrapper for special devices.
1749  */
1750 int
1751 ufsspec_write(void *v)
1752 {
1753 	struct vop_write_args /* {
1754 		struct vnode	*a_vp;
1755 		struct uio	*a_uio;
1756 		int		a_ioflag;
1757 		struct ucred	*a_cred;
1758 	} */ *ap = v;
1759 
1760 	/*
1761 	 * Set update and change flags.
1762 	 */
1763 	if ((ap->a_vp->v_mount->mnt_flag & MNT_NODEVMTIME) == 0)
1764 		VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
1765 	return (VOCALL (spec_vnodeop_p, VOFFSET(vop_write), ap));
1766 }
1767 
1768 /*
1769  * Close wrapper for special devices.
1770  *
1771  * Update the times on the inode then do device close.
1772  */
1773 int
1774 ufsspec_close(void *v)
1775 {
1776 	struct vop_close_args /* {
1777 		struct vnode	*a_vp;
1778 		int		a_fflag;
1779 		struct ucred	*a_cred;
1780 		struct proc	*a_p;
1781 	} */ *ap = v;
1782 	struct vnode	*vp;
1783 	struct inode	*ip;
1784 	struct timespec	ts;
1785 
1786 	vp = ap->a_vp;
1787 	ip = VTOI(vp);
1788 	simple_lock(&vp->v_interlock);
1789 	if (vp->v_usecount > 1) {
1790 		TIMEVAL_TO_TIMESPEC(&time, &ts);
1791 		ITIMES(ip, &ts, &ts, &ts);
1792 	}
1793 	simple_unlock(&vp->v_interlock);
1794 	return (VOCALL (spec_vnodeop_p, VOFFSET(vop_close), ap));
1795 }
1796 
1797 /*
1798  * Read wrapper for fifo's
1799  */
1800 int
1801 ufsfifo_read(void *v)
1802 {
1803 	struct vop_read_args /* {
1804 		struct vnode	*a_vp;
1805 		struct uio	*a_uio;
1806 		int		a_ioflag;
1807 		struct ucred	*a_cred;
1808 	} */ *ap = v;
1809 
1810 	/*
1811 	 * Set access flag.
1812 	 */
1813 	VTOI(ap->a_vp)->i_flag |= IN_ACCESS;
1814 	return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_read), ap));
1815 }
1816 
1817 /*
1818  * Write wrapper for fifo's.
1819  */
1820 int
1821 ufsfifo_write(void *v)
1822 {
1823 	struct vop_write_args /* {
1824 		struct vnode	*a_vp;
1825 		struct uio	*a_uio;
1826 		int		a_ioflag;
1827 		struct ucred	*a_cred;
1828 	} */ *ap = v;
1829 
1830 	/*
1831 	 * Set update and change flags.
1832 	 */
1833 	VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
1834 	return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_write), ap));
1835 }
1836 
1837 /*
1838  * Close wrapper for fifo's.
1839  *
1840  * Update the times on the inode then do device close.
1841  */
1842 int
1843 ufsfifo_close(void *v)
1844 {
1845 	struct vop_close_args /* {
1846 		struct vnode	*a_vp;
1847 		int		a_fflag;
1848 		struct ucred	*a_cred;
1849 		struct proc	*a_p;
1850 	} */ *ap = v;
1851 	struct vnode	*vp;
1852 	struct inode	*ip;
1853 	struct timespec	ts;
1854 
1855 	vp = ap->a_vp;
1856 	ip = VTOI(vp);
1857 	simple_lock(&vp->v_interlock);
1858 	if (ap->a_vp->v_usecount > 1) {
1859 		TIMEVAL_TO_TIMESPEC(&time, &ts);
1860 		ITIMES(ip, &ts, &ts, &ts);
1861 	}
1862 	simple_unlock(&vp->v_interlock);
1863 	return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_close), ap));
1864 }
1865 
1866 /*
1867  * Return POSIX pathconf information applicable to ufs filesystems.
1868  */
1869 int
1870 ufs_pathconf(void *v)
1871 {
1872 	struct vop_pathconf_args /* {
1873 		struct vnode	*a_vp;
1874 		int		a_name;
1875 		register_t	*a_retval;
1876 	} */ *ap = v;
1877 
1878 	switch (ap->a_name) {
1879 	case _PC_LINK_MAX:
1880 		*ap->a_retval = LINK_MAX;
1881 		return (0);
1882 	case _PC_NAME_MAX:
1883 		*ap->a_retval = NAME_MAX;
1884 		return (0);
1885 	case _PC_PATH_MAX:
1886 		*ap->a_retval = PATH_MAX;
1887 		return (0);
1888 	case _PC_PIPE_BUF:
1889 		*ap->a_retval = PIPE_BUF;
1890 		return (0);
1891 	case _PC_CHOWN_RESTRICTED:
1892 		*ap->a_retval = 1;
1893 		return (0);
1894 	case _PC_NO_TRUNC:
1895 		*ap->a_retval = 1;
1896 		return (0);
1897 	case _PC_SYNC_IO:
1898 		*ap->a_retval = 1;
1899 		return (0);
1900 	case _PC_FILESIZEBITS:
1901 		*ap->a_retval = 42;
1902 		return (0);
1903 	default:
1904 		return (EINVAL);
1905 	}
1906 	/* NOTREACHED */
1907 }
1908 
1909 /*
1910  * Advisory record locking support
1911  */
1912 int
1913 ufs_advlock(void *v)
1914 {
1915 	struct vop_advlock_args /* {
1916 		struct vnode	*a_vp;
1917 		caddr_t		a_id;
1918 		int		a_op;
1919 		struct flock	*a_fl;
1920 		int		a_flags;
1921 	} */ *ap = v;
1922 	struct inode *ip;
1923 
1924 	ip = VTOI(ap->a_vp);
1925 	return lf_advlock(ap, &ip->i_lockf, ip->i_ffs_size);
1926 }
1927 
1928 /*
1929  * Initialize the vnode associated with a new inode, handle aliased
1930  * vnodes.
1931  */
1932 void
1933 ufs_vinit(struct mount *mntp, int (**specops)(void *), int (**fifoops)(void *),
1934 	struct vnode **vpp)
1935 {
1936 	struct inode	*ip;
1937 	struct vnode	*vp, *nvp;
1938 
1939 	vp = *vpp;
1940 	ip = VTOI(vp);
1941 	switch(vp->v_type = IFTOVT(ip->i_ffs_mode)) {
1942 	case VCHR:
1943 	case VBLK:
1944 		vp->v_op = specops;
1945 		if ((nvp = checkalias(vp,
1946 			ufs_rw32(ip->i_ffs_rdev, UFS_MPNEEDSWAP(vp->v_mount)),
1947 			mntp)) != NULL) {
1948 			/*
1949 			 * Discard unneeded vnode, but save its inode.
1950 			 */
1951 			nvp->v_data = vp->v_data;
1952 			vp->v_data = NULL;
1953 			/* XXX spec_vnodeops has no locking, do it explicitly */
1954 			VOP_UNLOCK(vp, 0);
1955 			vp->v_op = spec_vnodeop_p;
1956 			vrele(vp);
1957 			vgone(vp);
1958 			lockmgr(&nvp->v_lock, LK_EXCLUSIVE, &nvp->v_interlock);
1959 			/*
1960 			 * Reinitialize aliased inode.
1961 			 */
1962 			vp = nvp;
1963 			ip->i_vnode = vp;
1964 		}
1965 		break;
1966 	case VFIFO:
1967 		vp->v_op = fifoops;
1968 		break;
1969 	case VNON:
1970 	case VBAD:
1971 	case VSOCK:
1972 	case VLNK:
1973 	case VDIR:
1974 	case VREG:
1975 		break;
1976 	}
1977 	if (ip->i_number == ROOTINO)
1978                 vp->v_flag |= VROOT;
1979 	/*
1980 	 * Initialize modrev times
1981 	 */
1982 	SETHIGH(ip->i_modrev, mono_time.tv_sec);
1983 	SETLOW(ip->i_modrev, mono_time.tv_usec * 4294);
1984 	*vpp = vp;
1985 }
1986 
1987 /*
1988  * Allocate a new inode.
1989  */
1990 int
1991 ufs_makeinode(int mode, struct vnode *dvp, struct vnode **vpp,
1992 	struct componentname *cnp)
1993 {
1994 	struct inode	*ip, *pdir;
1995 	struct direct	newdir;
1996 	struct vnode	*tvp;
1997 	int		error;
1998 
1999 	pdir = VTOI(dvp);
2000 #ifdef DIAGNOSTIC
2001 	if ((cnp->cn_flags & HASBUF) == 0)
2002 		panic("ufs_makeinode: no name");
2003 #endif
2004 	*vpp = NULL;
2005 	if ((mode & IFMT) == 0)
2006 		mode |= IFREG;
2007 
2008 	if ((error = VOP_VALLOC(dvp, mode, cnp->cn_cred, &tvp)) != 0) {
2009 		PNBUF_PUT(cnp->cn_pnbuf);
2010 		vput(dvp);
2011 		return (error);
2012 	}
2013 	ip = VTOI(tvp);
2014 	ip->i_ffs_gid = pdir->i_ffs_gid;
2015 	ip->i_ffs_uid = cnp->cn_cred->cr_uid;
2016 #ifdef QUOTA
2017 	if ((error = getinoquota(ip)) ||
2018 	    (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
2019 		PNBUF_PUT(cnp->cn_pnbuf);
2020 		VOP_VFREE(tvp, ip->i_number, mode);
2021 		vput(tvp);
2022 		vput(dvp);
2023 		return (error);
2024 	}
2025 #endif
2026 	ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
2027 	ip->i_ffs_mode = mode;
2028 	tvp->v_type = IFTOVT(mode);	/* Rest init'd in getnewvnode(). */
2029 	ip->i_ffs_effnlink = 1;
2030 	ip->i_ffs_nlink = 1;
2031 	if (DOINGSOFTDEP(tvp))
2032 		softdep_change_linkcnt(ip);
2033 	if ((ip->i_ffs_mode & ISGID) &&
2034 		!groupmember(ip->i_ffs_gid, cnp->cn_cred) &&
2035 	    suser(cnp->cn_cred, NULL))
2036 		ip->i_ffs_mode &= ~ISGID;
2037 
2038 	if (cnp->cn_flags & ISWHITEOUT)
2039 		ip->i_ffs_flags |= UF_OPAQUE;
2040 
2041 	/*
2042 	 * Make sure inode goes to disk before directory entry.
2043 	 */
2044 	if ((error = VOP_UPDATE(tvp, NULL, NULL, UPDATE_DIROP)) != 0)
2045 		goto bad;
2046 	ufs_makedirentry(ip, cnp, &newdir);
2047 	if ((error = ufs_direnter(dvp, tvp, &newdir, cnp, NULL)) != 0)
2048 		goto bad;
2049 	if ((cnp->cn_flags & SAVESTART) == 0)
2050 		PNBUF_PUT(cnp->cn_pnbuf);
2051 	vput(dvp);
2052 	*vpp = tvp;
2053 	return (0);
2054 
2055  bad:
2056 	/*
2057 	 * Write error occurred trying to update the inode
2058 	 * or the directory so must deallocate the inode.
2059 	 */
2060 	PNBUF_PUT(cnp->cn_pnbuf);
2061 	vput(dvp);
2062 	ip->i_ffs_effnlink = 0;
2063 	ip->i_ffs_nlink = 0;
2064 	ip->i_flag |= IN_CHANGE;
2065 #ifdef LFS
2066 	/* If IN_ADIROP, account for it */
2067 	lfs_unmark_vnode(tvp);
2068 #endif
2069 	if (DOINGSOFTDEP(tvp))
2070 		softdep_change_linkcnt(ip);
2071 	tvp->v_type = VNON;
2072 	vput(tvp);
2073 	return (error);
2074 }
2075