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