xref: /original-bsd/sys/ufs/ffs/ufs_vnops.c (revision 7075c56d)
1 /*
2  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)ufs_vnops.c	7.85 (Berkeley) 04/21/92
8  */
9 
10 #include <sys/param.h>
11 #include <sys/systm.h>
12 #include <sys/namei.h>
13 #include <sys/resourcevar.h>
14 #include <sys/kernel.h>
15 #include <sys/file.h>
16 #include <sys/stat.h>
17 #include <sys/buf.h>
18 #include <sys/proc.h>
19 #include <sys/conf.h>
20 #include <sys/mount.h>
21 #include <sys/vnode.h>
22 #include <sys/specdev.h>
23 #include <sys/fifo.h>
24 #include <sys/malloc.h>
25 
26 #include <ufs/ufs/lockf.h>
27 #include <ufs/ufs/quota.h>
28 #include <ufs/ufs/inode.h>
29 #include <ufs/ufs/dir.h>
30 #include <ufs/ufs/ufsmount.h>
31 #include <ufs/ufs/ufs_extern.h>
32 
33 int ufs_chmod __P((struct vnode *, int, struct ucred *, struct proc *));
34 int ufs_chown
35 	__P((struct vnode *, u_int, u_int, struct ucred *, struct proc *));
36 
37 #ifdef _NOQUAD
38 #define	SETHIGH(q, h)	(q).val[_QUAD_HIGHWORD] = (h)
39 #define	SETLOW(q, l)	(q).val[_QUAD_LOWWORD] = (l)
40 #else /* QUAD */
41 union _qcvt {
42 	quad_t qcvt;
43 	long val[2];
44 };
45 #define SETHIGH(q, h) { \
46 	union _qcvt tmp; \
47 	tmp.qcvt = (q); \
48 	tmp.val[_QUAD_HIGHWORD] = (h); \
49 	(q) = tmp.qcvt; \
50 }
51 #define SETLOW(q, l) { \
52 	union _qcvt tmp; \
53 	tmp.qcvt = (q); \
54 	tmp.val[_QUAD_LOWWORD] = (l); \
55 	(q) = tmp.qcvt; \
56 }
57 #endif /* QUAD */
58 
59 /*
60  * Create a regular file
61  */
62 int
63 ufs_create(dvp, vpp, cnp, vap)
64 	struct vnode *dvp;
65 	struct vnode **vpp;
66 	struct componentname *cnp;
67 	struct vattr *vap;
68 {
69 	int error;
70 
71 	if (error =
72 	    ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode), dvp, vpp, cnp))
73 		return (error);
74 	return (0);
75 }
76 
77 /*
78  * Mknod vnode call
79  */
80 /* ARGSUSED */
81 int
82 ufs_mknod(dvp, vpp, cnp, vap)
83 	struct vnode *dvp;
84 	struct vnode **vpp;
85 	struct componentname *cnp;
86 	struct vattr *vap;
87 {
88 	register struct inode *ip;
89 	int error;
90 
91 	if (error =
92 	    ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode), dvp, vpp, cnp))
93 		return (error);
94 	ip = VTOI(*vpp);
95 	ip->i_flag |= IACC|IUPD|ICHG;
96 	if (vap->va_rdev != VNOVAL) {
97 		/*
98 		 * Want to be able to use this to make badblock
99 		 * inodes, so don't truncate the dev number.
100 		 */
101 		ip->i_rdev = vap->va_rdev;
102 	}
103 	/*
104 	 * Remove inode so that it will be reloaded by iget and
105 	 * checked to see if it is an alias of an existing entry
106 	 * in the inode cache.
107 	 */
108 	vput(*vpp);
109 	(*vpp)->v_type = VNON;
110 	vgone(*vpp);
111 	*vpp = 0;
112 	return (0);
113 }
114 
115 /*
116  * Open called.
117  *
118  * Nothing to do.
119  */
120 /* ARGSUSED */
121 int
122 ufs_open(vp, mode, cred, p)
123 	struct vnode *vp;
124 	int mode;
125 	struct ucred *cred;
126 	struct proc *p;
127 {
128 
129 	return (0);
130 }
131 
132 /*
133  * Close called
134  *
135  * Update the times on the inode.
136  */
137 /* ARGSUSED */
138 int
139 ufs_close(vp, fflag, cred, p)
140 	struct vnode *vp;
141 	int fflag;
142 	struct ucred *cred;
143 	struct proc *p;
144 {
145 	register struct inode *ip;
146 
147 	ip = VTOI(vp);
148 	if (vp->v_usecount > 1 && !(ip->i_flag & ILOCKED))
149 		ITIMES(ip, &time, &time);
150 	return (0);
151 }
152 
153 /*
154  * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
155  * The mode is shifted to select the owner/group/other fields. The
156  * super user is granted all permissions.
157  */
158 int
159 ufs_access(vp, mode, cred, p)
160 	struct vnode *vp;
161 	register int mode;
162 	struct ucred *cred;
163 	struct proc *p;
164 {
165 	register struct inode *ip = VTOI(vp);
166 	register gid_t *gp;
167 	int i, error;
168 
169 #ifdef DIAGNOSTIC
170 	if (!VOP_ISLOCKED(vp)) {
171 		vprint("ufs_access: not locked", vp);
172 		panic("ufs_access: not locked");
173 	}
174 #endif
175 #ifdef QUOTA
176 	if (mode & VWRITE) {
177 		switch (vp->v_type) {
178 		case VREG: case VDIR: case VLNK:
179 			if (error = getinoquota(ip))
180 				return (error);
181 		}
182 	}
183 #endif /* QUOTA */
184 	/*
185 	 * If you're the super-user, you always get access.
186 	 */
187 	if (cred->cr_uid == 0)
188 		return (0);
189 	/*
190 	 * Access check is based on only one of owner, group, public.
191 	 * If not owner, then check group. If not a member of the
192 	 * group, then check public access.
193 	 */
194 	if (cred->cr_uid != ip->i_uid) {
195 		mode >>= 3;
196 		gp = cred->cr_groups;
197 		for (i = 0; i < cred->cr_ngroups; i++, gp++)
198 			if (ip->i_gid == *gp)
199 				goto found;
200 		mode >>= 3;
201 found:
202 		;
203 	}
204 	if ((ip->i_mode & mode) != 0)
205 		return (0);
206 	return (EACCES);
207 }
208 
209 /* ARGSUSED */
210 int
211 ufs_getattr(vp, vap, cred, p)
212 	struct vnode *vp;
213 	register struct vattr *vap;
214 	struct ucred *cred;
215 	struct proc *p;
216 {
217 	register struct inode *ip;
218 
219 	ip = VTOI(vp);
220 	ITIMES(ip, &time, &time);
221 	/*
222 	 * Copy from inode table
223 	 */
224 	vap->va_fsid = ip->i_dev;
225 	vap->va_fileid = ip->i_number;
226 	vap->va_mode = ip->i_mode & ~IFMT;
227 	vap->va_nlink = ip->i_nlink;
228 	vap->va_uid = ip->i_uid;
229 	vap->va_gid = ip->i_gid;
230 	vap->va_rdev = (dev_t)ip->i_rdev;
231 #ifdef tahoe
232 	vap->va_size = ip->i_size;
233 	vap->va_size_rsv = 0;
234 #else
235 	vap->va_qsize = ip->i_din.di_qsize;
236 #endif
237 	vap->va_atime.tv_sec = ip->i_atime;
238 	vap->va_atime.tv_usec = 0;
239 	vap->va_mtime.tv_sec = ip->i_mtime;
240 	vap->va_mtime.tv_usec = 0;
241 	vap->va_ctime.tv_sec = ip->i_ctime;
242 	vap->va_ctime.tv_usec = 0;
243 	vap->va_flags = ip->i_flags;
244 	vap->va_gen = ip->i_gen;
245 	/* this doesn't belong here */
246 	if (vp->v_type == VBLK)
247 		vap->va_blocksize = BLKDEV_IOSIZE;
248 	else if (vp->v_type == VCHR)
249 		vap->va_blocksize = MAXBSIZE;
250 	else
251 		vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
252 	vap->va_bytes = dbtob(ip->i_blocks);
253 #ifdef _NOQUAD
254 	vap->va_bytes_rsv = 0;
255 #endif
256 	vap->va_type = vp->v_type;
257 	vap->va_filerev = ip->i_modrev;
258 	return (0);
259 }
260 
261 /*
262  * Set attribute vnode op. called from several syscalls
263  */
264 int
265 ufs_setattr(vp, vap, cred, p)
266 	register struct vnode *vp;
267 	register struct vattr *vap;
268 	register struct ucred *cred;
269 	struct proc *p;
270 {
271 	register struct inode *ip;
272 	int error;
273 
274 	/*
275 	 * Check for unsettable attributes.
276 	 */
277 	if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
278 	    (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
279 	    (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
280 	    ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
281 		return (EINVAL);
282 	}
283 	/*
284 	 * Go through the fields and update iff not VNOVAL.
285 	 */
286 	if (vap->va_uid != (u_short)VNOVAL || vap->va_gid != (u_short)VNOVAL)
287 		if (error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, p))
288 			return (error);
289 	if (vap->va_size != VNOVAL) {
290 		if (vp->v_type == VDIR)
291 			return (EISDIR);
292 		if (error = VOP_TRUNCATE(vp, vap->va_size, 0, cred))
293 			return (error);
294 	}
295 	ip = VTOI(vp);
296 	if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
297 		if (cred->cr_uid != ip->i_uid &&
298 		    (error = suser(cred, &p->p_acflag)))
299 			return (error);
300 		if (vap->va_atime.tv_sec != VNOVAL)
301 			ip->i_flag |= IACC;
302 		if (vap->va_mtime.tv_sec != VNOVAL)
303 			ip->i_flag |= IUPD;
304 		ip->i_flag |= ICHG;
305 		if (error = VOP_UPDATE(vp, &vap->va_atime, &vap->va_mtime, 1))
306 			return (error);
307 	}
308 	error = 0;
309 	if (vap->va_mode != (u_short)VNOVAL)
310 		error = ufs_chmod(vp, (int)vap->va_mode, cred, p);
311 	if (vap->va_flags != VNOVAL) {
312 		if (cred->cr_uid != ip->i_uid &&
313 		    (error = suser(cred, &p->p_acflag)))
314 			return (error);
315 		if (cred->cr_uid == 0) {
316 			ip->i_flags = vap->va_flags;
317 		} else {
318 			ip->i_flags &= 0xffff0000;
319 			ip->i_flags |= (vap->va_flags & 0xffff);
320 		}
321 		ip->i_flag |= ICHG;
322 	}
323 	return (error);
324 }
325 
326 /*
327  * Change the mode on a file.
328  * Inode must be locked before calling.
329  */
330 static int
331 ufs_chmod(vp, mode, cred, p)
332 	register struct vnode *vp;
333 	register int mode;
334 	register struct ucred *cred;
335 	struct proc *p;
336 {
337 	register struct inode *ip = VTOI(vp);
338 	int error;
339 
340 	if (cred->cr_uid != ip->i_uid &&
341 	    (error = suser(cred, &p->p_acflag)))
342 		return (error);
343 	if (cred->cr_uid) {
344 		if (vp->v_type != VDIR && (mode & ISVTX))
345 			return (EFTYPE);
346 		if (!groupmember(ip->i_gid, cred) && (mode & ISGID))
347 			return (EPERM);
348 	}
349 	ip->i_mode &= ~07777;
350 	ip->i_mode |= mode & 07777;
351 	ip->i_flag |= ICHG;
352 	if ((vp->v_flag & VTEXT) && (ip->i_mode & ISVTX) == 0)
353 		(void) vnode_pager_uncache(vp);
354 	return (0);
355 }
356 
357 /*
358  * Perform chown operation on inode ip;
359  * inode must be locked prior to call.
360  */
361 static int
362 ufs_chown(vp, uid, gid, cred, p)
363 	register struct vnode *vp;
364 	u_int uid;
365 	u_int gid;
366 	struct ucred *cred;
367 	struct proc *p;
368 {
369 	register struct inode *ip = VTOI(vp);
370 	uid_t ouid;
371 	gid_t ogid;
372 	int error = 0;
373 #ifdef QUOTA
374 	register int i;
375 	long change;
376 #endif
377 
378 	if (uid == (u_short)VNOVAL)
379 		uid = ip->i_uid;
380 	if (gid == (u_short)VNOVAL)
381 		gid = ip->i_gid;
382 	/*
383 	 * If we don't own the file, are trying to change the owner
384 	 * of the file, or are not a member of the target group,
385 	 * the caller must be superuser or the call fails.
386 	 */
387 	if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid ||
388 	    !groupmember((gid_t)gid, cred)) &&
389 	    (error = suser(cred, &p->p_acflag)))
390 		return (error);
391 	ouid = ip->i_uid;
392 	ogid = ip->i_gid;
393 #ifdef QUOTA
394 	if (error = getinoquota(ip))
395 		return (error);
396 	if (ouid == uid) {
397 		dqrele(vp, ip->i_dquot[USRQUOTA]);
398 		ip->i_dquot[USRQUOTA] = NODQUOT;
399 	}
400 	if (ogid == gid) {
401 		dqrele(vp, ip->i_dquot[GRPQUOTA]);
402 		ip->i_dquot[GRPQUOTA] = NODQUOT;
403 	}
404 	change = ip->i_blocks;
405 	(void) chkdq(ip, -change, cred, CHOWN);
406 	(void) chkiq(ip, -1, cred, CHOWN);
407 	for (i = 0; i < MAXQUOTAS; i++) {
408 		dqrele(vp, ip->i_dquot[i]);
409 		ip->i_dquot[i] = NODQUOT;
410 	}
411 #endif
412 	ip->i_uid = uid;
413 	ip->i_gid = gid;
414 #ifdef QUOTA
415 	if ((error = getinoquota(ip)) == 0) {
416 		if (ouid == uid) {
417 			dqrele(vp, ip->i_dquot[USRQUOTA]);
418 			ip->i_dquot[USRQUOTA] = NODQUOT;
419 		}
420 		if (ogid == gid) {
421 			dqrele(vp, ip->i_dquot[GRPQUOTA]);
422 			ip->i_dquot[GRPQUOTA] = NODQUOT;
423 		}
424 		if ((error = chkdq(ip, change, cred, CHOWN)) == 0) {
425 			if ((error = chkiq(ip, 1, cred, CHOWN)) == 0)
426 				goto good;
427 			else
428 				(void) chkdq(ip, -change, cred, CHOWN|FORCE);
429 		}
430 		for (i = 0; i < MAXQUOTAS; i++) {
431 			dqrele(vp, ip->i_dquot[i]);
432 			ip->i_dquot[i] = NODQUOT;
433 		}
434 	}
435 	ip->i_uid = ouid;
436 	ip->i_gid = ogid;
437 	if (getinoquota(ip) == 0) {
438 		if (ouid == uid) {
439 			dqrele(vp, ip->i_dquot[USRQUOTA]);
440 			ip->i_dquot[USRQUOTA] = NODQUOT;
441 		}
442 		if (ogid == gid) {
443 			dqrele(vp, ip->i_dquot[GRPQUOTA]);
444 			ip->i_dquot[GRPQUOTA] = NODQUOT;
445 		}
446 		(void) chkdq(ip, change, cred, FORCE|CHOWN);
447 		(void) chkiq(ip, 1, cred, FORCE|CHOWN);
448 		(void) getinoquota(ip);
449 	}
450 	return (error);
451 good:
452 	if (getinoquota(ip))
453 		panic("chown: lost quota");
454 #endif /* QUOTA */
455 	if (ouid != uid || ogid != gid)
456 		ip->i_flag |= ICHG;
457 	if (ouid != uid && cred->cr_uid != 0)
458 		ip->i_mode &= ~ISUID;
459 	if (ogid != gid && cred->cr_uid != 0)
460 		ip->i_mode &= ~ISGID;
461 	return (0);
462 }
463 
464 /* ARGSUSED */
465 int
466 ufs_ioctl(vp, com, data, fflag, cred, p)
467 	struct vnode *vp;
468 	int com;
469 	caddr_t data;
470 	int fflag;
471 	struct ucred *cred;
472 	struct proc *p;
473 {
474 
475 	return (ENOTTY);
476 }
477 
478 /* ARGSUSED */
479 int
480 ufs_select(vp, which, fflags, cred, p)
481 	struct vnode *vp;
482 	int which, fflags;
483 	struct ucred *cred;
484 	struct proc *p;
485 {
486 
487 	/*
488 	 * We should really check to see if I/O is possible.
489 	 */
490 	return (1);
491 }
492 
493 /*
494  * Mmap a file
495  *
496  * NB Currently unsupported.
497  */
498 /* ARGSUSED */
499 int
500 ufs_mmap(vp, fflags, cred, p)
501 	struct vnode *vp;
502 	int fflags;
503 	struct ucred *cred;
504 	struct proc *p;
505 {
506 
507 	return (EINVAL);
508 }
509 
510 /*
511  * Seek on a file
512  *
513  * Nothing to do, so just return.
514  */
515 /* ARGSUSED */
516 int
517 ufs_seek(vp, oldoff, newoff, cred)
518 	struct vnode *vp;
519 	off_t oldoff, newoff;
520 	struct ucred *cred;
521 {
522 
523 	return (0);
524 }
525 
526 /*
527  * ufs remove
528  * Hard to avoid races here, especially
529  * in unlinking directories.
530  */
531 int
532 ufs_remove(dvp, vp, cnp)
533 	struct vnode *dvp, *vp;
534 	struct componentname *cnp;
535 {
536 	register struct inode *ip, *dp;
537 	int error;
538 
539 	ip = VTOI(vp);
540 	dp = VTOI(dvp);
541 	error = ufs_dirremove(dvp, cnp);
542 	if (!error) {
543 		ip->i_nlink--;
544 		ip->i_flag |= ICHG;
545 	}
546 	if (dp == ip)
547 		vrele(ITOV(ip));
548 	else
549 		ufs_iput(ip);
550 	ufs_iput(dp);
551 	return (error);
552 }
553 
554 /*
555  * link vnode call
556  */
557 int
558 ufs_link(tdvp, vp, cnp)
559 	struct vnode *tdvp;
560 	register struct vnode *vp;   /* source vnode */
561 	struct componentname *cnp;
562 {
563 	register struct inode *ip;
564 	int error;
565 
566 #ifdef DIANOSTIC
567 	if ((cnp->cn_flags & HASBUF) == 0)
568 		panic("ufs_link: no name");
569 #endif
570 	ip = VTOI(vp);
571 	if ((unsigned short)ip->i_nlink >= LINK_MAX) {
572 		free(cnp->cn_pnbuf, M_NAMEI);
573 		return (EMLINK);
574 	}
575 	if (tdvp != vp)
576 		ILOCK(ip);
577 	ip->i_nlink++;
578 	ip->i_flag |= ICHG;
579 	error = VOP_UPDATE(vp, &time, &time, 1);
580 	if (!error)
581 		error = ufs_direnter(ip, tdvp, cnp);
582 	if (tdvp != vp)
583 		IUNLOCK(ip);
584 	FREE(cnp->cn_pnbuf, M_NAMEI);
585 	vput(tdvp);
586 	if (error) {
587 		ip->i_nlink--;
588 		ip->i_flag |= ICHG;
589 	}
590 	return (error);
591 }
592 
593 
594 
595 /*
596  * relookup - lookup a path name component
597  *    Used by lookup to re-aquire things.
598  */
599 int
600 relookup(dvp, vpp, cnp)
601 	struct vnode *dvp, **vpp;
602 	struct componentname *cnp;
603 {
604 	register struct vnode *dp = 0;	/* the directory we are searching */
605 	struct vnode *tdp;		/* saved dp */
606 	struct mount *mp;		/* mount table entry */
607 	int docache;			/* == 0 do not cache last component */
608 	int wantparent;			/* 1 => wantparent or lockparent flag */
609 	int rdonly;			/* lookup read-only flag bit */
610 	char *cp;			/* DEBUG: check name ptr/len */
611 	int newhash;			/* DEBUG: check name hash */
612 	int error = 0;
613 
614 	/*
615 	 * Setup: break out flag bits into variables.
616 	 */
617 	wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT);
618 	docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE;
619 	if (cnp->cn_nameiop == DELETE ||
620 	    (wantparent && cnp->cn_nameiop != CREATE))
621 		docache = 0;
622 	rdonly = cnp->cn_flags & RDONLY;
623 	cnp->cn_flags &= ~ISSYMLINK;
624 	dp = dvp;
625 	VOP_LOCK(dp);
626 
627 /* dirloop: */
628 	/*
629 	 * Search a new directory.
630 	 *
631 	 * The cn_hash value is for use by vfs_cache.
632 	 * The last component of the filename is left accessible via
633 	 * cnp->cn_nameptr for callers that need the name. Callers needing
634 	 * the name set the SAVENAME flag. When done, they assume
635 	 * responsibility for freeing the pathname buffer.
636 	 */
637 #ifdef NAMEI_DIAGNOSTIC
638 	for (newhash = 0, cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++)
639 		newhash += (unsigned char)*cp;
640 	if (newhash != cnp->cn_hash)
641 		panic("relookup: bad hash");
642 	if (cnp->cn_namelen != cp - cnp->cn_nameptr)
643 		panic ("relookup: bad len");
644 	if (*cp != 0)
645 		panic("relookup: not last component");
646 	printf("{%s}: ", cnp->cn_nameptr);
647 #endif
648 
649 	/*
650 	 * Check for degenerate name (e.g. / or "")
651 	 * which is a way of talking about a directory,
652 	 * e.g. like "/." or ".".
653 	 */
654 	if (cnp->cn_nameptr[0] == '\0') {
655 		if (cnp->cn_nameiop != LOOKUP || wantparent) {
656 			error = EISDIR;
657 			goto bad;
658 		}
659 		if (dp->v_type != VDIR) {
660 			error = ENOTDIR;
661 			goto bad;
662 		}
663 		if (!(cnp->cn_flags & LOCKLEAF))
664 			VOP_UNLOCK(dp);
665 		*vpp = dp;
666 		if (cnp->cn_flags & SAVESTART)
667 			panic("lookup: SAVESTART");
668 		return (0);
669 	}
670 
671 	if (cnp->cn_flags & ISDOTDOT)
672 		panic ("relookup: lookup on dot-dot");
673 
674 	/*
675 	 * We now have a segment name to search for, and a directory to search.
676 	 */
677 	if (error = VOP_LOOKUP(dp, vpp, cnp)) {
678 #ifdef DIAGNOSTIC
679 		if (*vpp != NULL)
680 			panic("leaf should be empty");
681 #endif
682 		if (error != EJUSTRETURN)
683 			goto bad;
684 		/*
685 		 * If creating and at end of pathname, then can consider
686 		 * allowing file to be created.
687 		 */
688 		if (rdonly || (dvp->v_mount->mnt_flag & MNT_RDONLY)) {
689 			error = EROFS;
690 			goto bad;
691 		}
692 		/* ASSERT(dvp == ndp->ni_startdir) */
693 		if (cnp->cn_flags & SAVESTART)
694 			VREF(dvp);
695 		/*
696 		 * We return with ni_vp NULL to indicate that the entry
697 		 * doesn't currently exist, leaving a pointer to the
698 		 * (possibly locked) directory inode in ndp->ni_dvp.
699 		 */
700 		return (0);
701 	}
702 	dp = *vpp;
703 
704 #ifdef DIAGNOSTIC
705 	/*
706 	 * Check for symbolic link
707 	 */
708 	if (dp->v_type == VLNK && (cnp->cn_flags & FOLLOW))
709 		panic ("relookup: symlink found.\n");
710 #endif
711 
712 nextname:
713 	/*
714 	 * Check for read-only file systems.
715 	 */
716 	if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) {
717 		/*
718 		 * Disallow directory write attempts on read-only
719 		 * file systems.
720 		 */
721 		if (rdonly || (dp->v_mount->mnt_flag & MNT_RDONLY) ||
722 		    (wantparent &&
723 		     (dvp->v_mount->mnt_flag & MNT_RDONLY))) {
724 			error = EROFS;
725 			goto bad2;
726 		}
727 	}
728 	/* ASSERT(dvp == ndp->ni_startdir) */
729 	if (cnp->cn_flags & SAVESTART)
730 		VREF(dvp);
731 
732 	if (!wantparent)
733 		vrele(dvp);
734 	if ((cnp->cn_flags & LOCKLEAF) == 0)
735 		VOP_UNLOCK(dp);
736 	return (0);
737 
738 bad2:
739 	if ((cnp->cn_flags & LOCKPARENT) && (cnp->cn_flags & ISLASTCN))
740 		VOP_UNLOCK(dvp);
741 	vrele(dvp);
742 bad:
743 	vput(dp);
744 	*vpp = NULL;
745 	return (error);
746 }
747 
748 
749 /*
750  * Rename system call.
751  * 	rename("foo", "bar");
752  * is essentially
753  *	unlink("bar");
754  *	link("foo", "bar");
755  *	unlink("foo");
756  * but ``atomically''.  Can't do full commit without saving state in the
757  * inode on disk which isn't feasible at this time.  Best we can do is
758  * always guarantee the target exists.
759  *
760  * Basic algorithm is:
761  *
762  * 1) Bump link count on source while we're linking it to the
763  *    target.  This also ensure the inode won't be deleted out
764  *    from underneath us while we work (it may be truncated by
765  *    a concurrent `trunc' or `open' for creation).
766  * 2) Link source to destination.  If destination already exists,
767  *    delete it first.
768  * 3) Unlink source reference to inode if still around. If a
769  *    directory was moved and the parent of the destination
770  *    is different from the source, patch the ".." entry in the
771  *    directory.
772  */
773 int
774 ufs_rename(fdvp, fvp, fcnp,
775 	   tdvp, tvp, tcnp)
776 	struct vnode *fdvp, *fvp;
777 	struct componentname *fcnp;
778 	struct vnode *tdvp, *tvp;
779 	struct componentname *tcnp;
780 {
781 	register struct inode *ip, *xp, *dp;
782 	struct dirtemplate dirbuf;
783 	int doingdirectory = 0, oldparent = 0, newparent = 0;
784 	int error = 0;
785 	int fdvpneedsrele = 1, tdvpneedsrele = 1;
786 
787 #ifdef DIANOSTIC
788 	if ((tcnp->cn_flags & HASBUF) == 0 ||
789 	    (fcnp->cn_flags & HASBUF) == 0)
790 		panic("ufs_rename: no name");
791 #endif
792 	dp = VTOI(fdvp);
793 	ip = VTOI(fvp);
794 	/*
795 	 * Check if just deleting a link name.
796 	 */
797 	if (fvp == tvp) {
798 		VOP_ABORTOP(tdvp, tcnp);
799 		vput(tdvp);
800 		vput(tvp);
801 		vrele(fdvp);
802 		if ((ip->i_mode&IFMT) == IFDIR) {
803 			VOP_ABORTOP(fdvp, fcnp);
804 			vrele(fvp);
805 			return (EINVAL);
806 		}
807 		doingdirectory = 0;
808 		goto unlinkit;
809 	}
810 	ILOCK(ip);
811 	if ((ip->i_mode&IFMT) == IFDIR) {
812 		/*
813 		 * Avoid ".", "..", and aliases of "." for obvious reasons.
814 		 */
815 		if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
816 		    dp == ip || (fcnp->cn_flags&ISDOTDOT) || (ip->i_flag & IRENAME)) {
817 			VOP_ABORTOP(tdvp, tcnp);
818 			vput(tdvp);
819 			if (tvp)
820 				vput(tvp);
821 			VOP_ABORTOP(fdvp, fcnp);
822 			vrele(fdvp);
823 			vput(fvp);
824 			return (EINVAL);
825 		}
826 		ip->i_flag |= IRENAME;
827 		oldparent = dp->i_number;
828 		doingdirectory++;
829 	}
830 	vrele(fdvp);
831 
832 	/*
833 	 * 1) Bump link count while we're moving stuff
834 	 *    around.  If we crash somewhere before
835 	 *    completing our work, the link count
836 	 *    may be wrong, but correctable.
837 	 */
838 	ip->i_nlink++;
839 	ip->i_flag |= ICHG;
840 	error = VOP_UPDATE(fvp, &time, &time, 1);
841 	IUNLOCK(ip);
842 
843 	/*
844 	 * When the target exists, both the directory
845 	 * and target vnodes are returned locked.
846 	 */
847 	dp = VTOI(tdvp);
848 	xp = NULL;
849 	if (tvp)
850 		xp = VTOI(tvp);
851 	/*
852 	 * If ".." must be changed (ie the directory gets a new
853 	 * parent) then the source directory must not be in the
854 	 * directory heirarchy above the target, as this would
855 	 * orphan everything below the source directory. Also
856 	 * the user must have write permission in the source so
857 	 * as to be able to change "..". We must repeat the call
858 	 * to namei, as the parent directory is unlocked by the
859 	 * call to checkpath().
860 	 */
861 	if (oldparent != dp->i_number)
862 		newparent = dp->i_number;
863 	if (doingdirectory && newparent) {
864 		VOP_LOCK(fvp);
865 		error = ufs_access(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_proc);
866 		VOP_UNLOCK(fvp);
867 		if (error)
868 			goto bad;
869 		if (xp != NULL)
870 			ufs_iput(xp);
871 		if (error = ufs_checkpath(ip, dp, tcnp->cn_cred))
872 			goto out;
873 		if ((tcnp->cn_flags & SAVESTART) == 0)
874 			panic("ufs_rename: lost to startdir");
875 		if (error = relookup(tdvp, &tvp, tcnp))
876 			goto out;
877 		dp = VTOI(tdvp);
878 		xp = NULL;
879 		if (tvp)
880 			xp = VTOI(tvp);
881 	}
882 	/*
883 	 * 2) If target doesn't exist, link the target
884 	 *    to the source and unlink the source.
885 	 *    Otherwise, rewrite the target directory
886 	 *    entry to reference the source inode and
887 	 *    expunge the original entry's existence.
888 	 */
889 	if (xp == NULL) {
890 		if (dp->i_dev != ip->i_dev)
891 			panic("rename: EXDEV");
892 		/*
893 		 * Account for ".." in new directory.
894 		 * When source and destination have the same
895 		 * parent we don't fool with the link count.
896 		 */
897 		if (doingdirectory && newparent) {
898 			if ((unsigned short)dp->i_nlink >= LINK_MAX) {
899 				error = EMLINK;
900 				goto bad;
901 			}
902 			dp->i_nlink++;
903 			dp->i_flag |= ICHG;
904 			if (error = VOP_UPDATE(ITOV(dp), &time, &time, 1))
905 				goto bad;
906 		}
907 		if (error = ufs_direnter(ip, tdvp, tcnp)) {
908 			if (doingdirectory && newparent) {
909 				dp->i_nlink--;
910 				dp->i_flag |= ICHG;
911 				(void)VOP_UPDATE(ITOV(dp), &time, &time, 1);
912 			}
913 			goto bad;
914 		}
915 		ufs_iput(dp);
916 	} else {
917 		if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev)
918 			panic("rename: EXDEV");
919 		/*
920 		 * Short circuit rename(foo, foo).
921 		 */
922 		if (xp->i_number == ip->i_number)
923 			panic("rename: same file");
924 		/*
925 		 * If the parent directory is "sticky", then the user must
926 		 * own the parent directory, or the destination of the rename,
927 		 * otherwise the destination may not be changed (except by
928 		 * root). This implements append-only directories.
929 		 */
930 		if ((dp->i_mode & ISVTX) && tcnp->cn_cred->cr_uid != 0 &&
931 		    tcnp->cn_cred->cr_uid != dp->i_uid &&
932 		    xp->i_uid != tcnp->cn_cred->cr_uid) {
933 			error = EPERM;
934 			goto bad;
935 		}
936 		/*
937 		 * Target must be empty if a directory and have no links
938 		 * to it. Also, ensure source and target are compatible
939 		 * (both directories, or both not directories).
940 		 */
941 		if ((xp->i_mode&IFMT) == IFDIR) {
942 			if (!ufs_dirempty(xp, dp->i_number, tcnp->cn_cred) ||
943 			    xp->i_nlink > 2) {
944 				error = ENOTEMPTY;
945 				goto bad;
946 			}
947 			if (!doingdirectory) {
948 				error = ENOTDIR;
949 				goto bad;
950 			}
951 			cache_purge(ITOV(dp));
952 		} else if (doingdirectory) {
953 			error = EISDIR;
954 			goto bad;
955 		}
956 		if (error = ufs_dirrewrite(dp, ip, tcnp))
957 			goto bad;
958 		/*
959 		 * If the target directory is in the same
960 		 * directory as the source directory,
961 		 * decrement the link count on the parent
962 		 * of the target directory.
963 		 */
964 		 if (doingdirectory && !newparent) {
965 			dp->i_nlink--;
966 			dp->i_flag |= ICHG;
967 		}
968 		ufs_iput(dp);
969 		/*
970 		 * Adjust the link count of the target to
971 		 * reflect the dirrewrite above.  If this is
972 		 * a directory it is empty and there are
973 		 * no links to it, so we can squash the inode and
974 		 * any space associated with it.  We disallowed
975 		 * renaming over top of a directory with links to
976 		 * it above, as the remaining link would point to
977 		 * a directory without "." or ".." entries.
978 		 */
979 		xp->i_nlink--;
980 		if (doingdirectory) {
981 			if (--xp->i_nlink != 0)
982 				panic("rename: linked directory");
983 			error = VOP_TRUNCATE(ITOV(xp), (off_t)0, IO_SYNC,
984 			    tcnp->cn_cred);
985 		}
986 		xp->i_flag |= ICHG;
987 		ufs_iput(xp);
988 		xp = NULL;
989 	}
990 
991 	/*
992 	 * 3) Unlink the source.
993 	 */
994 unlinkit:
995 	fcnp->cn_flags &= ~MODMASK;
996 	fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
997 	if ((fcnp->cn_flags & SAVESTART) == 0)
998 		panic("ufs_rename: lost from startdir");
999 	(void) relookup(fdvp, &fvp, fcnp);
1000 	if (fvp != NULL) {
1001 		xp = VTOI(fvp);
1002 		dp = VTOI(fdvp);
1003 	} else {
1004 		/*
1005 		 * From name has disappeared.
1006 		 */
1007 		if (doingdirectory)
1008 			panic("rename: lost dir entry");
1009 		vrele(ITOV(ip));
1010 		return (0);
1011 	}
1012 	/*
1013 	 * Ensure that the directory entry still exists and has not
1014 	 * changed while the new name has been entered. If the source is
1015 	 * a file then the entry may have been unlinked or renamed. In
1016 	 * either case there is no further work to be done. If the source
1017 	 * is a directory then it cannot have been rmdir'ed; its link
1018 	 * count of three would cause a rmdir to fail with ENOTEMPTY.
1019 	 * The IRENAME flag ensures that it cannot be moved by another
1020 	 * rename.
1021 	 */
1022 	if (xp != ip) {
1023 		if (doingdirectory)
1024 			panic("rename: lost dir entry");
1025 	} else {
1026 		/*
1027 		 * If the source is a directory with a
1028 		 * new parent, the link count of the old
1029 		 * parent directory must be decremented
1030 		 * and ".." set to point to the new parent.
1031 		 */
1032 		if (doingdirectory && newparent) {
1033 			dp->i_nlink--;
1034 			dp->i_flag |= ICHG;
1035 			error = vn_rdwr(UIO_READ, ITOV(xp), (caddr_t)&dirbuf,
1036 				sizeof (struct dirtemplate), (off_t)0,
1037 				UIO_SYSSPACE, IO_NODELOCKED,
1038 				tcnp->cn_cred, (int *)0, (struct proc *)0);
1039 			if (error == 0) {
1040 				if (dirbuf.dotdot_namlen != 2 ||
1041 				    dirbuf.dotdot_name[0] != '.' ||
1042 				    dirbuf.dotdot_name[1] != '.') {
1043 					ufs_dirbad(xp, (doff_t)12,
1044 					    "rename: mangled dir");
1045 				} else {
1046 					dirbuf.dotdot_ino = newparent;
1047 					(void) vn_rdwr(UIO_WRITE, ITOV(xp),
1048 					    (caddr_t)&dirbuf,
1049 					    sizeof (struct dirtemplate),
1050 					    (off_t)0, UIO_SYSSPACE,
1051 					    IO_NODELOCKED|IO_SYNC,
1052 					    tcnp->cn_cred, (int *)0,
1053 					    (struct proc *)0);
1054 					cache_purge(ITOV(dp));
1055 				}
1056 			}
1057 		}
1058 		error = ufs_dirremove(fdvp, fcnp);
1059 		if (!error) {
1060 			xp->i_nlink--;
1061 			xp->i_flag |= ICHG;
1062 		}
1063 		xp->i_flag &= ~IRENAME;
1064 	}
1065 	if (dp)
1066 		vput(ITOV(dp));
1067 	if (xp)
1068 		vput(ITOV(xp));
1069 	vrele(ITOV(ip));
1070 	return (error);
1071 
1072 bad:
1073 	if (xp)
1074 		vput(ITOV(xp));
1075 	vput(ITOV(dp));
1076 out:
1077 	ip->i_nlink--;
1078 	ip->i_flag |= ICHG;
1079 	vrele(ITOV(ip));
1080 	return (error);
1081 }
1082 
1083 /*
1084  * A virgin directory (no blushing please).
1085  */
1086 static struct dirtemplate mastertemplate = {
1087 	0, 12, 1, ".",
1088 	0, DIRBLKSIZ - 12, 2, ".."
1089 };
1090 
1091 /*
1092  * Mkdir system call
1093  */
1094 int
1095 ufs_mkdir(dvp, vpp, cnp, vap)
1096 	struct vnode *dvp;
1097 	struct vnode **vpp;
1098 	struct componentname *cnp;
1099 	struct vattr *vap;
1100 {
1101 	register struct inode *ip, *dp;
1102 	struct vnode *tvp;
1103 	struct dirtemplate dirtemplate;
1104 	int error;
1105 	int dmode;
1106 
1107 #ifdef DIANOSTIC
1108 	if ((cnp->cn_flags & HASBUF) == 0)
1109 		panic("ufs_mkdir: no name");
1110 #endif
1111 	dp = VTOI(dvp);
1112 	if ((unsigned short)dp->i_nlink >= LINK_MAX) {
1113 		free(cnp->cn_pnbuf, M_NAMEI);
1114 		ufs_iput(dp);
1115 		return (EMLINK);
1116 	}
1117 	dmode = vap->va_mode&0777;
1118 	dmode |= IFDIR;
1119 	/*
1120 	 * Must simulate part of maknode here to acquire the inode, but
1121 	 * not have it entered in the parent directory. The entry is made
1122 	 * later after writing "." and ".." entries.
1123 	 */
1124 	if (error = VOP_VALLOC(dvp, dmode, cnp->cn_cred, &tvp)) {
1125 		free(cnp->cn_pnbuf, M_NAMEI);
1126 		ufs_iput(dp);
1127 		return (error);
1128 	}
1129 	ip = VTOI(tvp);
1130 	ip->i_uid = cnp->cn_cred->cr_uid;
1131 	ip->i_gid = dp->i_gid;
1132 #ifdef QUOTA
1133 	if ((error = getinoquota(ip)) ||
1134 	    (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
1135 		free(cnp->cn_pnbuf, M_NAMEI);
1136 		VOP_VFREE(tvp, ip->i_number, dmode);
1137 		ufs_iput(ip);
1138 		ufs_iput(dp);
1139 		return (error);
1140 	}
1141 #endif
1142 	ip->i_flag |= IACC|IUPD|ICHG;
1143 	ip->i_mode = dmode;
1144 	ITOV(ip)->v_type = VDIR;	/* Rest init'd in iget() */
1145 	ip->i_nlink = 2;
1146 	error = VOP_UPDATE(ITOV(ip), &time, &time, 1);
1147 
1148 	/*
1149 	 * Bump link count in parent directory
1150 	 * to reflect work done below.  Should
1151 	 * be done before reference is created
1152 	 * so reparation is possible if we crash.
1153 	 */
1154 	dp->i_nlink++;
1155 	dp->i_flag |= ICHG;
1156 	if (error = VOP_UPDATE(ITOV(dp), &time, &time, 1))
1157 		goto bad;
1158 
1159 	/* Initialize directory with "." and ".." from static template. */
1160 	dirtemplate = mastertemplate;
1161 	dirtemplate.dot_ino = ip->i_number;
1162 	dirtemplate.dotdot_ino = dp->i_number;
1163 	error = vn_rdwr(UIO_WRITE, ITOV(ip), (caddr_t)&dirtemplate,
1164 	    sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE,
1165 	    IO_NODELOCKED|IO_SYNC, cnp->cn_cred, (int *)0, (struct proc *)0);
1166 	if (error) {
1167 		dp->i_nlink--;
1168 		dp->i_flag |= ICHG;
1169 		goto bad;
1170 	}
1171 	if (DIRBLKSIZ > VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
1172 		panic("ufs_mkdir: blksize"); /* XXX should grow with balloc() */
1173 	else {
1174 		ip->i_size = DIRBLKSIZ;
1175 		ip->i_flag |= ICHG;
1176 	}
1177 
1178 	/* Directory set up, now install it's entry in the parent directory. */
1179 	if (error = ufs_direnter(ip, dvp, cnp)) {
1180 		dp->i_nlink--;
1181 		dp->i_flag |= ICHG;
1182 	}
1183 bad:
1184 	/*
1185 	 * No need to do an explicit VOP_TRUNCATE here, vrele will do this
1186 	 * for us because we set the link count to 0.
1187 	 */
1188 	if (error) {
1189 		ip->i_nlink = 0;
1190 		ip->i_flag |= ICHG;
1191 		ufs_iput(ip);
1192 	} else
1193 		*vpp = ITOV(ip);
1194 	FREE(cnp->cn_pnbuf, M_NAMEI);
1195 	ufs_iput(dp);
1196 	return (error);
1197 }
1198 
1199 /*
1200  * Rmdir system call.
1201  */
1202 int
1203 ufs_rmdir(dvp, vp, cnp)
1204 	struct vnode *dvp;
1205 	struct vnode *vp;
1206 	struct componentname *cnp;
1207 {
1208 	register struct inode *ip, *dp;
1209 	int error;
1210 
1211 	ip = VTOI(vp);
1212 	dp = VTOI(dvp);
1213 	/*
1214 	 * No rmdir "." please.
1215 	 */
1216 	if (dp == ip) {
1217 		vrele(dvp);
1218 		ufs_iput(ip);
1219 		return (EINVAL);
1220 	}
1221 	/*
1222 	 * Verify the directory is empty (and valid).
1223 	 * (Rmdir ".." won't be valid since
1224 	 *  ".." will contain a reference to
1225 	 *  the current directory and thus be
1226 	 *  non-empty.)
1227 	 */
1228 	error = 0;
1229 	if (ip->i_nlink != 2 ||
1230 	    !ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) {
1231 		error = ENOTEMPTY;
1232 		goto out;
1233 	}
1234 	/*
1235 	 * Delete reference to directory before purging
1236 	 * inode.  If we crash in between, the directory
1237 	 * will be reattached to lost+found,
1238 	 */
1239 	if (error = ufs_dirremove(dvp, cnp))
1240 		goto out;
1241 	dp->i_nlink--;
1242 	dp->i_flag |= ICHG;
1243 	cache_purge(dvp);
1244 	ufs_iput(dp);
1245 	dvp = NULL;
1246 	/*
1247 	 * Truncate inode.  The only stuff left
1248 	 * in the directory is "." and "..".  The
1249 	 * "." reference is inconsequential since
1250 	 * we're quashing it.  The ".." reference
1251 	 * has already been adjusted above.  We've
1252 	 * removed the "." reference and the reference
1253 	 * in the parent directory, but there may be
1254 	 * other hard links so decrement by 2 and
1255 	 * worry about them later.
1256 	 */
1257 	ip->i_nlink -= 2;
1258 	error = VOP_TRUNCATE(vp, (off_t)0, IO_SYNC, cnp->cn_cred);
1259 	cache_purge(ITOV(ip));
1260 out:
1261 	if (dvp)
1262 		ufs_iput(dp);
1263 	ufs_iput(ip);
1264 	return (error);
1265 }
1266 
1267 /*
1268  * symlink -- make a symbolic link
1269  */
1270 int
1271 ufs_symlink(dvp, vpp, cnp, vap, target)
1272 	struct vnode *dvp;
1273 	struct vnode **vpp;
1274 	struct componentname *cnp;
1275 	struct vattr *vap;
1276 	char *target;
1277 {
1278 	int error;
1279 
1280 	if (error = ufs_makeinode(IFLNK | vap->va_mode, dvp, vpp, cnp))
1281 		return (error);
1282 	error = vn_rdwr(UIO_WRITE, *vpp, target, strlen(target), (off_t)0,
1283 		UIO_SYSSPACE, IO_NODELOCKED, cnp->cn_cred, (int *)0,
1284 		(struct proc *)0);
1285 	vput(*vpp);
1286 	return (error);
1287 }
1288 
1289 /*
1290  * Vnode op for reading directories.
1291  *
1292  * The routine below assumes that the on-disk format of a directory
1293  * is the same as that defined by <sys/dirent.h>. If the on-disk
1294  * format changes, then it will be necessary to do a conversion
1295  * from the on-disk format that read returns to the format defined
1296  * by <sys/dirent.h>.
1297  */
1298 int
1299 ufs_readdir(vp, uio, cred, eofflagp)
1300 	struct vnode *vp;
1301 	register struct uio *uio;
1302 	struct ucred *cred;
1303 	int *eofflagp;
1304 {
1305 	int count, lost, error;
1306 
1307 	count = uio->uio_resid;
1308 	count &= ~(DIRBLKSIZ - 1);
1309 	lost = uio->uio_resid - count;
1310 	if (count < DIRBLKSIZ || (uio->uio_offset & (DIRBLKSIZ -1)))
1311 		return (EINVAL);
1312 	uio->uio_resid = count;
1313 	uio->uio_iov->iov_len = count;
1314 	error = VOP_READ(vp, uio, 0, cred);
1315 	uio->uio_resid += lost;
1316 	if ((VTOI(vp)->i_size - uio->uio_offset) <= 0)
1317 		*eofflagp = 1;
1318 	else
1319 		*eofflagp = 0;
1320 	return (error);
1321 }
1322 
1323 /*
1324  * Return target name of a symbolic link
1325  */
1326 int
1327 ufs_readlink(vp, uiop, cred)
1328 	struct vnode *vp;
1329 	struct uio *uiop;
1330 	struct ucred *cred;
1331 {
1332 
1333 	return (VOP_READ(vp, uiop, 0, cred));
1334 }
1335 
1336 /*
1337  * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually
1338  * done. If a buffer has been saved in anticipation of a CREATE, delete it.
1339  */
1340 /* ARGSUSED */
1341 int
1342 ufs_abortop(dvp, cnp)
1343 	struct vnode *dvp;
1344 	struct componentname *cnp;
1345 {
1346 	if ((cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
1347 		FREE(cnp->cn_pnbuf, M_NAMEI);
1348 	return (0);
1349 }
1350 
1351 /*
1352  * Lock an inode.
1353  */
1354 int
1355 ufs_lock(vp)
1356 	struct vnode *vp;
1357 {
1358 	register struct inode *ip = VTOI(vp);
1359 
1360 	ILOCK(ip);
1361 	return (0);
1362 }
1363 
1364 /*
1365  * Unlock an inode.
1366  */
1367 int
1368 ufs_unlock(vp)
1369 	struct vnode *vp;
1370 {
1371 	register struct inode *ip = VTOI(vp);
1372 
1373 	if (!(ip->i_flag & ILOCKED))
1374 		panic("ufs_unlock NOT LOCKED");
1375 	IUNLOCK(ip);
1376 	return (0);
1377 }
1378 
1379 /*
1380  * Check for a locked inode.
1381  */
1382 int
1383 ufs_islocked(vp)
1384 	struct vnode *vp;
1385 {
1386 
1387 	if (VTOI(vp)->i_flag & ILOCKED)
1388 		return (1);
1389 	return (0);
1390 }
1391 
1392 /*
1393  * Calculate the logical to physical mapping if not done already,
1394  * then call the device strategy routine.
1395  */
1396 int
1397 ufs_strategy(bp)
1398 	register struct buf *bp;
1399 {
1400 	register struct inode *ip;
1401 	struct vnode *vp;
1402 	int error;
1403 
1404 	ip = VTOI(bp->b_vp);
1405 	if (bp->b_vp->v_type == VBLK || bp->b_vp->v_type == VCHR)
1406 		panic("ufs_strategy: spec");
1407 	if (bp->b_blkno == bp->b_lblkno) {
1408 		if (error =
1409 		    VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_blkno)) {
1410 			bp->b_error = error;
1411 			bp->b_flags |= B_ERROR;
1412 			biodone(bp);
1413 			return (error);
1414 		}
1415 		if ((long)bp->b_blkno == -1)
1416 			clrbuf(bp);
1417 	}
1418 	if ((long)bp->b_blkno == -1) {
1419 		biodone(bp);
1420 		return (0);
1421 	}
1422 	vp = ip->i_devvp;
1423 	bp->b_dev = vp->v_rdev;
1424 	(vp->v_op->vop_strategy)(bp);
1425 	return (0);
1426 }
1427 
1428 /*
1429  * Print out the contents of an inode.
1430  */
1431 int
1432 ufs_print(vp)
1433 	struct vnode *vp;
1434 {
1435 	register struct inode *ip = VTOI(vp);
1436 
1437 	printf("tag VT_UFS, ino %d, on dev %d, %d", ip->i_number,
1438 		major(ip->i_dev), minor(ip->i_dev));
1439 #ifdef FIFO
1440 	if (vp->v_type == VFIFO)
1441 		fifo_printinfo(vp);
1442 #endif /* FIFO */
1443 	printf("%s\n", (ip->i_flag & ILOCKED) ? " (LOCKED)" : "");
1444 	if (ip->i_lockholder == 0)
1445 		return (0);
1446 	printf("\towner pid %d", ip->i_lockholder);
1447 	if (ip->i_lockwaiter)
1448 		printf(" waiting pid %d", ip->i_lockwaiter);
1449 	printf("\n");
1450 	return (0);
1451 }
1452 
1453 /*
1454  * Read wrapper for special devices.
1455  */
1456 int
1457 ufsspec_read(vp, uio, ioflag, cred)
1458 	struct vnode *vp;
1459 	struct uio *uio;
1460 	int ioflag;
1461 	struct ucred *cred;
1462 {
1463 
1464 	/*
1465 	 * Set access flag.
1466 	 */
1467 	VTOI(vp)->i_flag |= IACC;
1468 	return (spec_read(vp, uio, ioflag, cred));
1469 }
1470 
1471 /*
1472  * Write wrapper for special devices.
1473  */
1474 int
1475 ufsspec_write(vp, uio, ioflag, cred)
1476 	struct vnode *vp;
1477 	struct uio *uio;
1478 	int ioflag;
1479 	struct ucred *cred;
1480 {
1481 
1482 	/*
1483 	 * Set update and change flags.
1484 	 */
1485 	VTOI(vp)->i_flag |= IUPD|ICHG;
1486 	return (spec_write(vp, uio, ioflag, cred));
1487 }
1488 
1489 /*
1490  * Close wrapper for special devices.
1491  *
1492  * Update the times on the inode then do device close.
1493  */
1494 int
1495 ufsspec_close(vp, fflag, cred, p)
1496 	struct vnode *vp;
1497 	int fflag;
1498 	struct ucred *cred;
1499 	struct proc *p;
1500 {
1501 	register struct inode *ip = VTOI(vp);
1502 
1503 	if (vp->v_usecount > 1 && !(ip->i_flag & ILOCKED))
1504 		ITIMES(ip, &time, &time);
1505 	return (spec_close(vp, fflag, cred, p));
1506 }
1507 
1508 #ifdef FIFO
1509 /*
1510  * Read wrapper for fifo's
1511  */
1512 int
1513 ufsfifo_read(vp, uio, ioflag, cred)
1514 	struct vnode *vp;
1515 	struct uio *uio;
1516 	int ioflag;
1517 	struct ucred *cred;
1518 {
1519 
1520 	/*
1521 	 * Set access flag.
1522 	 */
1523 	VTOI(vp)->i_flag |= IACC;
1524 	return (fifo_read(vp, uio, ioflag, cred));
1525 }
1526 
1527 /*
1528  * Write wrapper for fifo's.
1529  */
1530 int
1531 ufsfifo_write(vp, uio, ioflag, cred)
1532 	struct vnode *vp;
1533 	struct uio *uio;
1534 	int ioflag;
1535 	struct ucred *cred;
1536 {
1537 
1538 	/*
1539 	 * Set update and change flags.
1540 	 */
1541 	VTOI(vp)->i_flag |= IUPD|ICHG;
1542 	return (fifo_write(vp, uio, ioflag, cred));
1543 }
1544 
1545 /*
1546  * Close wrapper for fifo's.
1547  *
1548  * Update the times on the inode then do device close.
1549  */
1550 ufsfifo_close(vp, fflag, cred, p)
1551 	struct vnode *vp;
1552 	int fflag;
1553 	struct ucred *cred;
1554 	struct proc *p;
1555 {
1556 	register struct inode *ip = VTOI(vp);
1557 
1558 	if (vp->v_usecount > 1 && !(ip->i_flag & ILOCKED))
1559 		ITIMES(ip, &time, &time);
1560 	return (fifo_close(vp, fflag, cred, p));
1561 }
1562 #endif /* FIFO */
1563 
1564 /*
1565  * Advisory record locking support
1566  */
1567 int
1568 ufs_advlock(vp, id, op, fl, flags)
1569 	struct vnode *vp;
1570 	caddr_t id;
1571 	int op;
1572 	register struct flock *fl;
1573 	int flags;
1574 {
1575 	register struct inode *ip = VTOI(vp);
1576 	register struct lockf *lock;
1577 	off_t start, end;
1578 	int error;
1579 
1580 	/*
1581 	 * Avoid the common case of unlocking when inode has no locks.
1582 	 */
1583 	if (ip->i_lockf == (struct lockf *)0) {
1584 		if (op != F_SETLK) {
1585 			fl->l_type = F_UNLCK;
1586 			return (0);
1587 		}
1588 	}
1589 	/*
1590 	 * Convert the flock structure into a start and end.
1591 	 */
1592 	switch (fl->l_whence) {
1593 
1594 	case SEEK_SET:
1595 	case SEEK_CUR:
1596 		/*
1597 		 * Caller is responsible for adding any necessary offset
1598 		 * when SEEK_CUR is used.
1599 		 */
1600 		start = fl->l_start;
1601 		break;
1602 
1603 	case SEEK_END:
1604 		start = ip->i_size + fl->l_start;
1605 		break;
1606 
1607 	default:
1608 		return (EINVAL);
1609 	}
1610 	if (start < 0)
1611 		return (EINVAL);
1612 	if (fl->l_len == 0)
1613 		end = -1;
1614 	else
1615 		end = start + fl->l_len - 1;
1616 	/*
1617 	 * Create the lockf structure
1618 	 */
1619 	MALLOC(lock, struct lockf *, sizeof *lock, M_LOCKF, M_WAITOK);
1620 	lock->lf_start = start;
1621 	lock->lf_end = end;
1622 	lock->lf_id = id;
1623 	lock->lf_inode = ip;
1624 	lock->lf_type = fl->l_type;
1625 	lock->lf_next = (struct lockf *)0;
1626 	lock->lf_block = (struct lockf *)0;
1627 	lock->lf_flags = flags;
1628 	/*
1629 	 * Do the requested operation.
1630 	 */
1631 	switch(op) {
1632 	case F_SETLK:
1633 		return (lf_setlock(lock));
1634 
1635 	case F_UNLCK:
1636 		error = lf_clearlock(lock);
1637 		FREE(lock, M_LOCKF);
1638 		return (error);
1639 
1640 	case F_GETLK:
1641 		error = lf_getlock(lock, fl);
1642 		FREE(lock, M_LOCKF);
1643 		return (error);
1644 
1645 	default:
1646 		free(lock, M_LOCKF);
1647 		return (EINVAL);
1648 	}
1649 	/* NOTREACHED */
1650 }
1651 
1652 /*
1653  * Initialize the vnode associated with a new inode, handle aliased
1654  * vnodes.
1655  */
1656 int
1657 ufs_vinit(mntp, specops, fifoops, vpp)
1658 	struct mount *mntp;
1659 	struct vnodeops *specops, *fifoops;
1660 	struct vnode **vpp;
1661 {
1662 	struct inode *ip, *nip;
1663 	struct vnode *vp, *nvp;
1664 	extern struct vnodeops spec_vnodeops;
1665 
1666 	vp = *vpp;
1667 	ip = VTOI(vp);
1668 	switch(vp->v_type = IFTOVT(ip->i_mode)) {
1669 	case VCHR:
1670 	case VBLK:
1671 		vp->v_op = specops;
1672 		if (nvp = checkalias(vp, ip->i_rdev, mntp)) {
1673 			/*
1674 			 * Discard unneeded vnode, but save its inode.
1675 			 */
1676 			remque(ip);
1677 			IUNLOCK(ip);
1678 			nvp->v_data = vp->v_data;
1679 			vp->v_data = NULL;
1680 			vp->v_op = &spec_vnodeops;
1681 			vrele(vp);
1682 			vgone(vp);
1683 			/*
1684 			 * Reinitialize aliased inode.
1685 			 */
1686 			vp = nvp;
1687 			ip->i_vnode = vp;
1688 			ufs_ihashins(ip);
1689 		}
1690 		break;
1691 	case VFIFO:
1692 #ifdef FIFO
1693 		vp->v_op = fifoops;
1694 		break;
1695 #else
1696 		return (EOPNOTSUPP);
1697 #endif
1698 	}
1699 	if (ip->i_number == ROOTINO)
1700                 vp->v_flag |= VROOT;
1701 	/*
1702 	 * Initialize modrev times
1703 	 */
1704 	SETHIGH(ip->i_modrev, mono_time.tv_sec);
1705 	SETLOW(ip->i_modrev, mono_time.tv_usec * 4294);
1706 	*vpp = vp;
1707 	return (0);
1708 }
1709 
1710 /*
1711  * Allocate a new inode.
1712  */
1713 int
1714 ufs_makeinode(mode, dvp, vpp, cnp)
1715 	int mode;
1716 	struct vnode *dvp;
1717 	struct vnode **vpp;
1718 	struct componentname *cnp;
1719 {
1720 	register struct inode *ip, *pdir;
1721 	struct vnode *tvp;
1722 	int error;
1723 
1724 	pdir = VTOI(dvp);
1725 #ifdef DIANOSTIC
1726 	if ((cnp->cn_flags & HASBUF) == 0)
1727 		panic("ufs_makeinode: no name");
1728 #endif
1729 	*vpp = NULL;
1730 	if ((mode & IFMT) == 0)
1731 		mode |= IFREG;
1732 
1733 	if (error = VOP_VALLOC(dvp, mode, cnp->cn_cred, &tvp)) {
1734 		free(cnp->cn_pnbuf, M_NAMEI);
1735 		ufs_iput(pdir);
1736 		return (error);
1737 	}
1738 	ip = VTOI(tvp);
1739 	ip->i_uid = cnp->cn_cred->cr_uid;
1740 	ip->i_gid = pdir->i_gid;
1741 #ifdef QUOTA
1742 	if ((error = getinoquota(ip)) ||
1743 	    (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
1744 		free(cnp->cn_pnbuf, M_NAMEI);
1745 		VOP_VFREE(tvp, ip->i_number, mode);
1746 		ufs_iput(ip);
1747 		ufs_iput(pdir);
1748 		return (error);
1749 	}
1750 #endif
1751 	ip->i_flag |= IACC|IUPD|ICHG;
1752 	ip->i_mode = mode;
1753 	tvp->v_type = IFTOVT(mode);	/* Rest init'd in iget() */
1754 	ip->i_nlink = 1;
1755 	if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
1756 	    suser(cnp->cn_cred, NULL))
1757 		ip->i_mode &= ~ISGID;
1758 
1759 	/*
1760 	 * Make sure inode goes to disk before directory entry.
1761 	 */
1762 	if (error = VOP_UPDATE(tvp, &time, &time, 1))
1763 		goto bad;
1764 	if (error = ufs_direnter(ip, dvp, cnp))
1765 		goto bad;
1766 	if ((cnp->cn_flags & SAVESTART) == 0)
1767 		FREE(cnp->cn_pnbuf, M_NAMEI);
1768 	ufs_iput(pdir);
1769 	*vpp = tvp;
1770 	return (0);
1771 
1772 bad:
1773 	/*
1774 	 * Write error occurred trying to update the inode
1775 	 * or the directory so must deallocate the inode.
1776 	 */
1777 	free(cnp->cn_pnbuf, M_NAMEI);
1778 	ufs_iput(pdir);
1779 	ip->i_nlink = 0;
1780 	ip->i_flag |= ICHG;
1781 	ufs_iput(ip);
1782 	return (error);
1783 }
1784