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