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