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