xref: /original-bsd/sys/ufs/ffs/ufs_vnops.c (revision c0290416)
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.94 (Berkeley) 06/18/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 		return (EXDEV);
555 	}
556 
557 #ifdef DIAGNOSTIC
558 	if ((cnp->cn_flags & HASBUF) == 0)
559 		panic("ufs_link: no name");
560 #endif
561 	ip = VTOI(tdvp);
562 	if ((nlink_t)ip->i_nlink >= LINK_MAX) {
563 		free(cnp->cn_pnbuf, M_NAMEI);
564 		return (EMLINK);
565 	}
566 	if (vp != tdvp)
567 		ILOCK(ip);
568 	ip->i_nlink++;
569 	ip->i_flag |= ICHG;
570 	error = VOP_UPDATE(tdvp, &time, &time, 1);
571 	if (!error)
572 		error = ufs_direnter(ip, vp, cnp);
573 	if (vp != tdvp)
574 		IUNLOCK(ip);
575 	FREE(cnp->cn_pnbuf, M_NAMEI);
576 	vput(vp);
577 	if (error) {
578 		ip->i_nlink--;
579 		ip->i_flag |= ICHG;
580 	}
581 	return (error);
582 }
583 
584 
585 
586 /*
587  * relookup - lookup a path name component
588  *    Used by lookup to re-aquire things.
589  */
590 int
591 relookup(dvp, vpp, cnp)
592 	struct vnode *dvp, **vpp;
593 	struct componentname *cnp;
594 {
595 	USES_VOP_LOCK;
596 	USES_VOP_LOOKUP;
597 	USES_VOP_UNLOCK;
598 	register struct vnode *dp = 0;	/* the directory we are searching */
599 	struct vnode *tdp;		/* saved dp */
600 	struct mount *mp;		/* mount table entry */
601 	int docache;			/* == 0 do not cache last component */
602 	int wantparent;			/* 1 => wantparent or lockparent flag */
603 	int rdonly;			/* lookup read-only flag bit */
604 	char *cp;			/* DEBUG: check name ptr/len */
605 	int newhash;			/* DEBUG: check name hash */
606 	int error = 0;
607 
608 	/*
609 	 * Setup: break out flag bits into variables.
610 	 */
611 	wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT);
612 	docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE;
613 	if (cnp->cn_nameiop == DELETE ||
614 	    (wantparent && cnp->cn_nameiop != CREATE))
615 		docache = 0;
616 	rdonly = cnp->cn_flags & RDONLY;
617 	cnp->cn_flags &= ~ISSYMLINK;
618 	dp = dvp;
619 	VOP_LOCK(dp);
620 
621 /* dirloop: */
622 	/*
623 	 * Search a new directory.
624 	 *
625 	 * The cn_hash value is for use by vfs_cache.
626 	 * The last component of the filename is left accessible via
627 	 * cnp->cn_nameptr for callers that need the name. Callers needing
628 	 * the name set the SAVENAME flag. When done, they assume
629 	 * responsibility for freeing the pathname buffer.
630 	 */
631 #ifdef NAMEI_DIAGNOSTIC
632 	for (newhash = 0, cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++)
633 		newhash += (unsigned char)*cp;
634 	if (newhash != cnp->cn_hash)
635 		panic("relookup: bad hash");
636 	if (cnp->cn_namelen != cp - cnp->cn_nameptr)
637 		panic ("relookup: bad len");
638 	if (*cp != 0)
639 		panic("relookup: not last component");
640 	printf("{%s}: ", cnp->cn_nameptr);
641 #endif
642 
643 	/*
644 	 * Check for degenerate name (e.g. / or "")
645 	 * which is a way of talking about a directory,
646 	 * e.g. like "/." or ".".
647 	 */
648 	if (cnp->cn_nameptr[0] == '\0') {
649 		if (cnp->cn_nameiop != LOOKUP || wantparent) {
650 			error = EISDIR;
651 			goto bad;
652 		}
653 		if (dp->v_type != VDIR) {
654 			error = ENOTDIR;
655 			goto bad;
656 		}
657 		if (!(cnp->cn_flags & LOCKLEAF))
658 			VOP_UNLOCK(dp);
659 		*vpp = dp;
660 		if (cnp->cn_flags & SAVESTART)
661 			panic("lookup: SAVESTART");
662 		return (0);
663 	}
664 
665 	if (cnp->cn_flags & ISDOTDOT)
666 		panic ("relookup: lookup on dot-dot");
667 
668 	/*
669 	 * We now have a segment name to search for, and a directory to search.
670 	 */
671 	if (error = VOP_LOOKUP(dp, vpp, cnp)) {
672 #ifdef DIAGNOSTIC
673 		if (*vpp != NULL)
674 			panic("leaf should be empty");
675 #endif
676 		if (error != EJUSTRETURN)
677 			goto bad;
678 		/*
679 		 * If creating and at end of pathname, then can consider
680 		 * allowing file to be created.
681 		 */
682 		if (rdonly || (dvp->v_mount->mnt_flag & MNT_RDONLY)) {
683 			error = EROFS;
684 			goto bad;
685 		}
686 		/* ASSERT(dvp == ndp->ni_startdir) */
687 		if (cnp->cn_flags & SAVESTART)
688 			VREF(dvp);
689 		/*
690 		 * We return with ni_vp NULL to indicate that the entry
691 		 * doesn't currently exist, leaving a pointer to the
692 		 * (possibly locked) directory inode in ndp->ni_dvp.
693 		 */
694 		return (0);
695 	}
696 	dp = *vpp;
697 
698 #ifdef DIAGNOSTIC
699 	/*
700 	 * Check for symbolic link
701 	 */
702 	if (dp->v_type == VLNK && (cnp->cn_flags & FOLLOW))
703 		panic ("relookup: symlink found.\n");
704 #endif
705 
706 nextname:
707 	/*
708 	 * Check for read-only file systems.
709 	 */
710 	if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) {
711 		/*
712 		 * Disallow directory write attempts on read-only
713 		 * file systems.
714 		 */
715 		if (rdonly || (dp->v_mount->mnt_flag & MNT_RDONLY) ||
716 		    (wantparent &&
717 		     (dvp->v_mount->mnt_flag & MNT_RDONLY))) {
718 			error = EROFS;
719 			goto bad2;
720 		}
721 	}
722 	/* ASSERT(dvp == ndp->ni_startdir) */
723 	if (cnp->cn_flags & SAVESTART)
724 		VREF(dvp);
725 
726 	if (!wantparent)
727 		vrele(dvp);
728 	if ((cnp->cn_flags & LOCKLEAF) == 0)
729 		VOP_UNLOCK(dp);
730 	return (0);
731 
732 bad2:
733 	if ((cnp->cn_flags & LOCKPARENT) && (cnp->cn_flags & ISLASTCN))
734 		VOP_UNLOCK(dvp);
735 	vrele(dvp);
736 bad:
737 	vput(dp);
738 	*vpp = NULL;
739 	return (error);
740 }
741 
742 
743 /*
744  * Rename system call.
745  * 	rename("foo", "bar");
746  * is essentially
747  *	unlink("bar");
748  *	link("foo", "bar");
749  *	unlink("foo");
750  * but ``atomically''.  Can't do full commit without saving state in the
751  * inode on disk which isn't feasible at this time.  Best we can do is
752  * always guarantee the target exists.
753  *
754  * Basic algorithm is:
755  *
756  * 1) Bump link count on source while we're linking it to the
757  *    target.  This also ensure the inode won't be deleted out
758  *    from underneath us while we work (it may be truncated by
759  *    a concurrent `trunc' or `open' for creation).
760  * 2) Link source to destination.  If destination already exists,
761  *    delete it first.
762  * 3) Unlink source reference to inode if still around. If a
763  *    directory was moved and the parent of the destination
764  *    is different from the source, patch the ".." entry in the
765  *    directory.
766  */
767 int
768 ufs_rename(ap)
769 	struct vop_rename_args *ap;
770 {
771 	USES_VOP_ABORTOP;
772 	USES_VOP_ACCESS;
773 	USES_VOP_LOCK;
774 	USES_VOP_TRUNCATE;
775 	USES_VOP_UNLOCK;
776 	USES_VOP_UPDATE;
777 	struct vnode *tvp = ap->a_tvp;
778 	register struct vnode *tdvp = ap->a_tdvp;
779 	struct vnode *fvp = ap->a_fvp;
780 	register struct vnode *fdvp = ap->a_fdvp;
781 	register struct componentname *tcnp = ap->a_tcnp;
782 	register struct componentname *fcnp = ap->a_fcnp;
783 	register struct inode *ip, *xp, *dp;
784 	struct dirtemplate dirbuf;
785 	int doingdirectory = 0, oldparent = 0, newparent = 0;
786 	int error = 0;
787 	int fdvpneedsrele = 1, tdvpneedsrele = 1;
788 
789 	/* Check for cross-device rename */
790 	if ((fvp->v_mount != tdvp->v_mount) ||
791 	    (tvp && (fvp->v_mount != tvp->v_mount))) {
792 		VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
793 		if (tdvp == tvp)
794 			vrele(tdvp);
795 		else
796 			vput(tdvp);
797 		if (tvp)
798 			vput(tvp);
799 		VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
800 		vrele(fdvp);
801 		vrele(fvp);
802 		return (EXDEV);
803 	}
804 
805 #ifdef DIAGNOSTIC
806 	if ((tcnp->cn_flags & HASBUF) == 0 ||
807 	    (fcnp->cn_flags & HASBUF) == 0)
808 		panic("ufs_rename: no name");
809 #endif
810 	dp = VTOI(fdvp);
811 	ip = VTOI(fvp);
812 	/*
813 	 * Check if just deleting a link name.
814 	 */
815 	if (fvp == tvp) {
816 		VOP_ABORTOP(tdvp, tcnp);
817 		vput(tdvp);
818 		vput(tvp);
819 		vrele(fdvp);
820 		if ((ip->i_mode&IFMT) == IFDIR) {
821 			VOP_ABORTOP(fdvp, fcnp);
822 			vrele(fvp);
823 			return (EINVAL);
824 		}
825 		doingdirectory = 0;
826 		goto unlinkit;
827 	}
828 	ILOCK(ip);
829 	if ((ip->i_mode&IFMT) == IFDIR) {
830 		/*
831 		 * Avoid ".", "..", and aliases of "." for obvious reasons.
832 		 */
833 		if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
834 		    dp == ip || (fcnp->cn_flags&ISDOTDOT) ||
835 		    (ip->i_flag & IRENAME)) {
836 			VOP_ABORTOP(tdvp, tcnp);
837 			vput(tdvp);
838 			if (tvp)
839 				vput(tvp);
840 			VOP_ABORTOP(fdvp, fcnp);
841 			vrele(fdvp);
842 			vput(fvp);
843 			return (EINVAL);
844 		}
845 		ip->i_flag |= IRENAME;
846 		oldparent = dp->i_number;
847 		doingdirectory++;
848 	}
849 	vrele(fdvp);
850 
851 	/*
852 	 * 1) Bump link count while we're moving stuff
853 	 *    around.  If we crash somewhere before
854 	 *    completing our work, the link count
855 	 *    may be wrong, but correctable.
856 	 */
857 	ip->i_nlink++;
858 	ip->i_flag |= ICHG;
859 	error = VOP_UPDATE(fvp, &time, &time, 1);
860 	IUNLOCK(ip);
861 
862 	/*
863 	 * When the target exists, both the directory
864 	 * and target vnodes are returned locked.
865 	 */
866 	dp = VTOI(tdvp);
867 	xp = NULL;
868 	if (tvp)
869 		xp = VTOI(tvp);
870 	/*
871 	 * If ".." must be changed (ie the directory gets a new
872 	 * parent) then the source directory must not be in the
873 	 * directory heirarchy above the target, as this would
874 	 * orphan everything below the source directory. Also
875 	 * the user must have write permission in the source so
876 	 * as to be able to change "..". We must repeat the call
877 	 * to namei, as the parent directory is unlocked by the
878 	 * call to checkpath().
879 	 */
880 	if (oldparent != dp->i_number)
881 		newparent = dp->i_number;
882 	if (doingdirectory && newparent) {
883 		VOP_LOCK(fvp);
884 		error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_proc);
885 		VOP_UNLOCK(fvp);
886 		if (error)
887 			goto bad;
888 		if (xp != NULL)
889 			ufs_iput(xp);
890 		if (error = ufs_checkpath(ip, dp, tcnp->cn_cred))
891 			goto out;
892 		if ((tcnp->cn_flags & SAVESTART) == 0)
893 			panic("ufs_rename: lost to startdir");
894 		if (error = relookup(tdvp, &tvp, tcnp))
895 			goto out;
896 		dp = VTOI(tdvp);
897 		xp = NULL;
898 		if (tvp)
899 			xp = VTOI(tvp);
900 	}
901 	/*
902 	 * 2) If target doesn't exist, link the target
903 	 *    to the source and unlink the source.
904 	 *    Otherwise, rewrite the target directory
905 	 *    entry to reference the source inode and
906 	 *    expunge the original entry's existence.
907 	 */
908 	if (xp == NULL) {
909 		if (dp->i_dev != ip->i_dev)
910 			panic("rename: EXDEV");
911 		/*
912 		 * Account for ".." in new directory.
913 		 * When source and destination have the same
914 		 * parent we don't fool with the link count.
915 		 */
916 		if (doingdirectory && newparent) {
917 			if ((nlink_t)dp->i_nlink >= LINK_MAX) {
918 				error = EMLINK;
919 				goto bad;
920 			}
921 			dp->i_nlink++;
922 			dp->i_flag |= ICHG;
923 			if (error = VOP_UPDATE(ITOV(dp), &time, &time, 1))
924 				goto bad;
925 		}
926 		if (error = ufs_direnter(ip, tdvp, tcnp)) {
927 			if (doingdirectory && newparent) {
928 				dp->i_nlink--;
929 				dp->i_flag |= ICHG;
930 				(void)VOP_UPDATE(ITOV(dp), &time, &time, 1);
931 			}
932 			goto bad;
933 		}
934 		ufs_iput(dp);
935 	} else {
936 		if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev)
937 			panic("rename: EXDEV");
938 		/*
939 		 * Short circuit rename(foo, foo).
940 		 */
941 		if (xp->i_number == ip->i_number)
942 			panic("rename: same file");
943 		/*
944 		 * If the parent directory is "sticky", then the user must
945 		 * own the parent directory, or the destination of the rename,
946 		 * otherwise the destination may not be changed (except by
947 		 * root). This implements append-only directories.
948 		 */
949 		if ((dp->i_mode & ISVTX) && tcnp->cn_cred->cr_uid != 0 &&
950 		    tcnp->cn_cred->cr_uid != dp->i_uid &&
951 		    xp->i_uid != tcnp->cn_cred->cr_uid) {
952 			error = EPERM;
953 			goto bad;
954 		}
955 		/*
956 		 * Target must be empty if a directory and have no links
957 		 * to it. Also, ensure source and target are compatible
958 		 * (both directories, or both not directories).
959 		 */
960 		if ((xp->i_mode&IFMT) == IFDIR) {
961 			if (!ufs_dirempty(xp, dp->i_number, tcnp->cn_cred) ||
962 			    xp->i_nlink > 2) {
963 				error = ENOTEMPTY;
964 				goto bad;
965 			}
966 			if (!doingdirectory) {
967 				error = ENOTDIR;
968 				goto bad;
969 			}
970 			cache_purge(ITOV(dp));
971 		} else if (doingdirectory) {
972 			error = EISDIR;
973 			goto bad;
974 		}
975 		if (error = ufs_dirrewrite(dp, ip, tcnp))
976 			goto bad;
977 		/*
978 		 * If the target directory is in the same
979 		 * directory as the source directory,
980 		 * decrement the link count on the parent
981 		 * of the target directory.
982 		 */
983 		 if (doingdirectory && !newparent) {
984 			dp->i_nlink--;
985 			dp->i_flag |= ICHG;
986 		}
987 		ufs_iput(dp);
988 		/*
989 		 * Adjust the link count of the target to
990 		 * reflect the dirrewrite above.  If this is
991 		 * a directory it is empty and there are
992 		 * no links to it, so we can squash the inode and
993 		 * any space associated with it.  We disallowed
994 		 * renaming over top of a directory with links to
995 		 * it above, as the remaining link would point to
996 		 * a directory without "." or ".." entries.
997 		 */
998 		xp->i_nlink--;
999 		if (doingdirectory) {
1000 			if (--xp->i_nlink != 0)
1001 				panic("rename: linked directory");
1002 			error = VOP_TRUNCATE(ITOV(xp), (off_t)0, IO_SYNC,
1003 			    tcnp->cn_cred);
1004 		}
1005 		xp->i_flag |= ICHG;
1006 		ufs_iput(xp);
1007 		xp = NULL;
1008 	}
1009 
1010 	/*
1011 	 * 3) Unlink the source.
1012 	 */
1013 unlinkit:
1014 	fcnp->cn_flags &= ~MODMASK;
1015 	fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
1016 	if ((fcnp->cn_flags & SAVESTART) == 0)
1017 		panic("ufs_rename: lost from startdir");
1018 	(void) relookup(fdvp, &fvp, fcnp);
1019 	if (fvp != NULL) {
1020 		xp = VTOI(fvp);
1021 		dp = VTOI(fdvp);
1022 	} else {
1023 		/*
1024 		 * From name has disappeared.
1025 		 */
1026 		if (doingdirectory)
1027 			panic("rename: lost dir entry");
1028 		vrele(ITOV(ip));
1029 		return (0);
1030 	}
1031 	/*
1032 	 * Ensure that the directory entry still exists and has not
1033 	 * changed while the new name has been entered. If the source is
1034 	 * a file then the entry may have been unlinked or renamed. In
1035 	 * either case there is no further work to be done. If the source
1036 	 * is a directory then it cannot have been rmdir'ed; its link
1037 	 * count of three would cause a rmdir to fail with ENOTEMPTY.
1038 	 * The IRENAME flag ensures that it cannot be moved by another
1039 	 * rename.
1040 	 */
1041 	if (xp != ip) {
1042 		if (doingdirectory)
1043 			panic("rename: lost dir entry");
1044 	} else {
1045 		/*
1046 		 * If the source is a directory with a
1047 		 * new parent, the link count of the old
1048 		 * parent directory must be decremented
1049 		 * and ".." set to point to the new parent.
1050 		 */
1051 		if (doingdirectory && newparent) {
1052 			dp->i_nlink--;
1053 			dp->i_flag |= ICHG;
1054 			error = vn_rdwr(UIO_READ, ITOV(xp), (caddr_t)&dirbuf,
1055 				sizeof (struct dirtemplate), (off_t)0,
1056 				UIO_SYSSPACE, IO_NODELOCKED,
1057 				tcnp->cn_cred, (int *)0, (struct proc *)0);
1058 			if (error == 0) {
1059 				if (dirbuf.dotdot_namlen != 2 ||
1060 				    dirbuf.dotdot_name[0] != '.' ||
1061 				    dirbuf.dotdot_name[1] != '.') {
1062 					ufs_dirbad(xp, (doff_t)12,
1063 					    "rename: mangled dir");
1064 				} else {
1065 					dirbuf.dotdot_ino = newparent;
1066 					(void) vn_rdwr(UIO_WRITE, ITOV(xp),
1067 					    (caddr_t)&dirbuf,
1068 					    sizeof (struct dirtemplate),
1069 					    (off_t)0, UIO_SYSSPACE,
1070 					    IO_NODELOCKED|IO_SYNC,
1071 					    tcnp->cn_cred, (int *)0,
1072 					    (struct proc *)0);
1073 					cache_purge(ITOV(dp));
1074 				}
1075 			}
1076 		}
1077 		error = ufs_dirremove(fdvp, fcnp);
1078 		if (!error) {
1079 			xp->i_nlink--;
1080 			xp->i_flag |= ICHG;
1081 		}
1082 		xp->i_flag &= ~IRENAME;
1083 	}
1084 	if (dp)
1085 		vput(ITOV(dp));
1086 	if (xp)
1087 		vput(ITOV(xp));
1088 	vrele(ITOV(ip));
1089 	return (error);
1090 
1091 bad:
1092 	if (xp)
1093 		vput(ITOV(xp));
1094 	vput(ITOV(dp));
1095 out:
1096 	ip->i_nlink--;
1097 	ip->i_flag |= ICHG;
1098 	vrele(ITOV(ip));
1099 	return (error);
1100 }
1101 
1102 /*
1103  * A virgin directory (no blushing please).
1104  */
1105 static struct dirtemplate mastertemplate = {
1106 	0, 12, 1, ".",
1107 	0, DIRBLKSIZ - 12, 2, ".."
1108 };
1109 
1110 /*
1111  * Mkdir system call
1112  */
1113 int
1114 ufs_mkdir(ap)
1115 	struct vop_mkdir_args *ap;
1116 {
1117 	USES_VOP_TRUNCATE;
1118 	USES_VOP_UPDATE;
1119 	USES_VOP_VALLOC;
1120 	USES_VOP_VFREE;
1121 	register struct vnode *dvp = ap->a_dvp;
1122 	register struct vattr *vap = ap->a_vap;
1123 	register struct componentname *cnp = ap->a_cnp;
1124 	register struct inode *ip, *dp;
1125 	struct vnode *tvp;
1126 	struct dirtemplate dirtemplate;
1127 	int error;
1128 	int dmode;
1129 
1130 #ifdef DIAGNOSTIC
1131 	if ((cnp->cn_flags & HASBUF) == 0)
1132 		panic("ufs_mkdir: no name");
1133 #endif
1134 	dp = VTOI(dvp);
1135 	if ((nlink_t)dp->i_nlink >= LINK_MAX) {
1136 		free(cnp->cn_pnbuf, M_NAMEI);
1137 		ufs_iput(dp);
1138 		return (EMLINK);
1139 	}
1140 	dmode = vap->va_mode&0777;
1141 	dmode |= IFDIR;
1142 	/*
1143 	 * Must simulate part of maknode here to acquire the inode, but
1144 	 * not have it entered in the parent directory. The entry is made
1145 	 * later after writing "." and ".." entries.
1146 	 */
1147 	if (error = VOP_VALLOC(dvp, dmode, cnp->cn_cred, &tvp)) {
1148 		free(cnp->cn_pnbuf, M_NAMEI);
1149 		ufs_iput(dp);
1150 		return (error);
1151 	}
1152 	ip = VTOI(tvp);
1153 	ip->i_uid = cnp->cn_cred->cr_uid;
1154 	ip->i_gid = dp->i_gid;
1155 #ifdef QUOTA
1156 	if ((error = getinoquota(ip)) ||
1157 	    (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
1158 		free(cnp->cn_pnbuf, M_NAMEI);
1159 		VOP_VFREE(tvp, ip->i_number, dmode);
1160 		ufs_iput(ip);
1161 		ufs_iput(dp);
1162 		return (error);
1163 	}
1164 #endif
1165 	ip->i_flag |= IACC|IUPD|ICHG;
1166 	ip->i_mode = dmode;
1167 	ITOV(ip)->v_type = VDIR;	/* Rest init'd in iget() */
1168 	ip->i_nlink = 2;
1169 	error = VOP_UPDATE(ITOV(ip), &time, &time, 1);
1170 
1171 	/*
1172 	 * Bump link count in parent directory
1173 	 * to reflect work done below.  Should
1174 	 * be done before reference is created
1175 	 * so reparation is possible if we crash.
1176 	 */
1177 	dp->i_nlink++;
1178 	dp->i_flag |= ICHG;
1179 	if (error = VOP_UPDATE(ITOV(dp), &time, &time, 1))
1180 		goto bad;
1181 
1182 	/* Initialize directory with "." and ".." from static template. */
1183 	dirtemplate = mastertemplate;
1184 	dirtemplate.dot_ino = ip->i_number;
1185 	dirtemplate.dotdot_ino = dp->i_number;
1186 	error = vn_rdwr(UIO_WRITE, ITOV(ip), (caddr_t)&dirtemplate,
1187 	    sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE,
1188 	    IO_NODELOCKED|IO_SYNC, cnp->cn_cred, (int *)0, (struct proc *)0);
1189 	if (error) {
1190 		dp->i_nlink--;
1191 		dp->i_flag |= ICHG;
1192 		goto bad;
1193 	}
1194 	if (DIRBLKSIZ > VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
1195 		panic("ufs_mkdir: blksize"); /* XXX should grow with balloc() */
1196 	else {
1197 		ip->i_size = DIRBLKSIZ;
1198 		ip->i_flag |= ICHG;
1199 	}
1200 
1201 	/* Directory set up, now install it's entry in the parent directory. */
1202 	if (error = ufs_direnter(ip, dvp, cnp)) {
1203 		dp->i_nlink--;
1204 		dp->i_flag |= ICHG;
1205 	}
1206 bad:
1207 	/*
1208 	 * No need to do an explicit VOP_TRUNCATE here, vrele will do this
1209 	 * for us because we set the link count to 0.
1210 	 */
1211 	if (error) {
1212 		ip->i_nlink = 0;
1213 		ip->i_flag |= ICHG;
1214 		ufs_iput(ip);
1215 	} else
1216 		*ap->a_vpp = ITOV(ip);
1217 	FREE(cnp->cn_pnbuf, M_NAMEI);
1218 	ufs_iput(dp);
1219 	return (error);
1220 }
1221 
1222 /*
1223  * Rmdir system call.
1224  */
1225 int
1226 ufs_rmdir(ap)
1227 	struct vop_rmdir_args *ap;
1228 {
1229 	USES_VOP_TRUNCATE;
1230 	register struct vnode *dvp = ap->a_dvp;
1231 	register struct componentname *cnp = ap->a_cnp;
1232 	register struct inode *ip, *dp;
1233 	int error;
1234 
1235 	ip = VTOI(ap->a_vp);
1236 	dp = VTOI(dvp);
1237 	/*
1238 	 * No rmdir "." please.
1239 	 */
1240 	if (dp == ip) {
1241 		vrele(dvp);
1242 		ufs_iput(ip);
1243 		return (EINVAL);
1244 	}
1245 	/*
1246 	 * Verify the directory is empty (and valid).
1247 	 * (Rmdir ".." won't be valid since
1248 	 *  ".." will contain a reference to
1249 	 *  the current directory and thus be
1250 	 *  non-empty.)
1251 	 */
1252 	error = 0;
1253 	if (ip->i_nlink != 2 ||
1254 	    !ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) {
1255 		error = ENOTEMPTY;
1256 		goto out;
1257 	}
1258 	/*
1259 	 * Delete reference to directory before purging
1260 	 * inode.  If we crash in between, the directory
1261 	 * will be reattached to lost+found,
1262 	 */
1263 	if (error = ufs_dirremove(dvp, cnp))
1264 		goto out;
1265 	dp->i_nlink--;
1266 	dp->i_flag |= ICHG;
1267 	cache_purge(dvp);
1268 	ufs_iput(dp);
1269 	dvp = NULL;
1270 	/*
1271 	 * Truncate inode.  The only stuff left
1272 	 * in the directory is "." and "..".  The
1273 	 * "." reference is inconsequential since
1274 	 * we're quashing it.  The ".." reference
1275 	 * has already been adjusted above.  We've
1276 	 * removed the "." reference and the reference
1277 	 * in the parent directory, but there may be
1278 	 * other hard links so decrement by 2 and
1279 	 * worry about them later.
1280 	 */
1281 	ip->i_nlink -= 2;
1282 	error = VOP_TRUNCATE(ap->a_vp, (off_t)0, IO_SYNC, cnp->cn_cred);
1283 	cache_purge(ITOV(ip));
1284 out:
1285 	if (dvp)
1286 		ufs_iput(dp);
1287 	ufs_iput(ip);
1288 	return (error);
1289 }
1290 
1291 /*
1292  * symlink -- make a symbolic link
1293  */
1294 int
1295 ufs_symlink(ap)
1296 	struct vop_symlink_args *ap;
1297 {
1298 	register struct vnode **vpp = ap->a_vpp;
1299 	int error;
1300 
1301 	if (error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
1302 	    vpp, ap->a_cnp))
1303 		return (error);
1304 	error = vn_rdwr(UIO_WRITE, *vpp, ap->a_target, strlen(ap->a_target),
1305 	    (off_t)0, UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred,
1306 	    (int *)0, (struct proc *)0);
1307 	vput(*vpp);
1308 	return (error);
1309 }
1310 
1311 /*
1312  * Vnode op for reading directories.
1313  *
1314  * The routine below assumes that the on-disk format of a directory
1315  * is the same as that defined by <sys/dirent.h>. If the on-disk
1316  * format changes, then it will be necessary to do a conversion
1317  * from the on-disk format that read returns to the format defined
1318  * by <sys/dirent.h>.
1319  */
1320 int
1321 ufs_readdir(ap)
1322 	struct vop_readdir_args *ap;
1323 {
1324 	USES_VOP_READ;
1325 	register struct uio *uio = ap->a_uio;
1326 	int count, lost, error;
1327 
1328 	count = uio->uio_resid;
1329 	count &= ~(DIRBLKSIZ - 1);
1330 	lost = uio->uio_resid - count;
1331 	if (count < DIRBLKSIZ || (uio->uio_offset & (DIRBLKSIZ -1)))
1332 		return (EINVAL);
1333 	uio->uio_resid = count;
1334 	uio->uio_iov->iov_len = count;
1335 	error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
1336 	uio->uio_resid += lost;
1337 	if ((VTOI(ap->a_vp)->i_size - uio->uio_offset) <= 0)
1338 		*ap->a_eofflagp = 1;
1339 	else
1340 		*ap->a_eofflagp = 0;
1341 	return (error);
1342 }
1343 
1344 /*
1345  * Return target name of a symbolic link
1346  */
1347 int
1348 ufs_readlink(ap)
1349 	struct vop_readlink_args *ap;
1350 {
1351 	USES_VOP_READ;
1352 
1353 	return (VOP_READ(ap->a_vp, ap->a_uio, 0, ap->a_cred));
1354 }
1355 
1356 /*
1357  * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually
1358  * done. If a buffer has been saved in anticipation of a CREATE, delete it.
1359  */
1360 /* ARGSUSED */
1361 int
1362 ufs_abortop(ap)
1363 	struct vop_abortop_args *ap;
1364 {
1365 	if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
1366 		FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
1367 	return (0);
1368 }
1369 
1370 /*
1371  * Lock an inode.
1372  */
1373 int
1374 ufs_lock(ap)
1375 	struct vop_lock_args *ap;
1376 {
1377 	register struct inode *ip = VTOI(ap->a_vp);
1378 
1379 	ILOCK(ip);
1380 	return (0);
1381 }
1382 
1383 /*
1384  * Unlock an inode.
1385  */
1386 int
1387 ufs_unlock(ap)
1388 	struct vop_unlock_args *ap;
1389 {
1390 	register struct inode *ip = VTOI(ap->a_vp);
1391 
1392 	if (!(ip->i_flag & ILOCKED))
1393 		panic("ufs_unlock NOT LOCKED");
1394 	IUNLOCK(ip);
1395 	return (0);
1396 }
1397 
1398 /*
1399  * Check for a locked inode.
1400  */
1401 int
1402 ufs_islocked(ap)
1403 	struct vop_islocked_args *ap;
1404 {
1405 
1406 	if (VTOI(ap->a_vp)->i_flag & ILOCKED)
1407 		return (1);
1408 	return (0);
1409 }
1410 
1411 /*
1412  * Calculate the logical to physical mapping if not done already,
1413  * then call the device strategy routine.
1414  */
1415 int
1416 ufs_strategy(ap)
1417 	struct vop_strategy_args *ap;
1418 {
1419 	USES_VOP_BMAP;
1420 	register struct buf *bp = ap->a_bp;
1421 	register struct vnode *vp = bp->b_vp;
1422 	register struct inode *ip;
1423 	int error;
1424 
1425 	ip = VTOI(vp);
1426 	if (vp->v_type == VBLK || vp->v_type == VCHR)
1427 		panic("ufs_strategy: spec");
1428 	if (bp->b_blkno == bp->b_lblkno) {
1429 		if (error =
1430 		    VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno)) {
1431 			bp->b_error = error;
1432 			bp->b_flags |= B_ERROR;
1433 			biodone(bp);
1434 			return (error);
1435 		}
1436 		if ((long)bp->b_blkno == -1)
1437 			clrbuf(bp);
1438 	}
1439 	if ((long)bp->b_blkno == -1) {
1440 		biodone(bp);
1441 		return (0);
1442 	}
1443 	vp = ip->i_devvp;
1444 	bp->b_dev = vp->v_rdev;
1445 	VOCALL (vp->v_op, VOFFSET(vop_strategy), ap);
1446 	return (0);
1447 }
1448 
1449 /*
1450  * Print out the contents of an inode.
1451  */
1452 int
1453 ufs_print(ap)
1454 	struct vop_print_args *ap;
1455 {
1456 	register struct vnode *vp = ap->a_vp;
1457 	register struct inode *ip = VTOI(vp);
1458 
1459 	printf("tag VT_UFS, ino %d, on dev %d, %d", ip->i_number,
1460 		major(ip->i_dev), minor(ip->i_dev));
1461 #ifdef FIFO
1462 	if (vp->v_type == VFIFO)
1463 		fifo_printinfo(vp);
1464 #endif /* FIFO */
1465 	printf("%s\n", (ip->i_flag & ILOCKED) ? " (LOCKED)" : "");
1466 	if (ip->i_lockholder == 0)
1467 		return (0);
1468 	printf("\towner pid %d", ip->i_lockholder);
1469 	if (ip->i_lockwaiter)
1470 		printf(" waiting pid %d", ip->i_lockwaiter);
1471 	printf("\n");
1472 	return (0);
1473 }
1474 
1475 /*
1476  * Read wrapper for special devices.
1477  */
1478 int
1479 ufsspec_read(ap)
1480 	struct vop_read_args *ap;
1481 {
1482 	extern int (**spec_vnodeop_p)();
1483 
1484 	/*
1485 	 * Set access flag.
1486 	 */
1487 	VTOI(ap->a_vp)->i_flag |= IACC;
1488 	return (VOCALL (spec_vnodeop_p, VOFFSET(vop_read), ap));
1489 }
1490 
1491 /*
1492  * Write wrapper for special devices.
1493  */
1494 int
1495 ufsspec_write(ap)
1496 	struct vop_write_args *ap;
1497 {
1498 	extern int (**spec_vnodeop_p)();
1499 
1500 	/*
1501 	 * Set update and change flags.
1502 	 */
1503 	VTOI(ap->a_vp)->i_flag |= IUPD|ICHG;
1504 	return (VOCALL (spec_vnodeop_p, VOFFSET(vop_write), ap));
1505 }
1506 
1507 /*
1508  * Close wrapper for special devices.
1509  *
1510  * Update the times on the inode then do device close.
1511  */
1512 int
1513 ufsspec_close(ap)
1514 	struct vop_close_args *ap;
1515 {
1516 	extern int (**spec_vnodeop_p)();
1517 	register struct inode *ip = VTOI(ap->a_vp);
1518 
1519 	if (ap->a_vp->v_usecount > 1 && !(ip->i_flag & ILOCKED))
1520 		ITIMES(ip, &time, &time);
1521 	return (VOCALL (spec_vnodeop_p, VOFFSET(vop_close), ap));
1522 }
1523 
1524 #ifdef FIFO
1525 /*
1526  * Read wrapper for fifo's
1527  */
1528 int
1529 ufsfifo_read(ap)
1530 	struct vop_read_args *ap;
1531 {
1532 	extern int (**fifo_vnodeop_p)();
1533 
1534 	/*
1535 	 * Set access flag.
1536 	 */
1537 	VTOI(ap->a_vp)->i_flag |= IACC;
1538 	return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_read), ap));
1539 }
1540 
1541 /*
1542  * Write wrapper for fifo's.
1543  */
1544 int
1545 ufsfifo_write(ap)
1546 	struct vop_write_args *ap;
1547 {
1548 	extern int (**fifo_vnodeop_p)();
1549 
1550 	/*
1551 	 * Set update and change flags.
1552 	 */
1553 	VTOI(ap->a_vp)->i_flag |= IUPD|ICHG;
1554 	return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_write), ap));
1555 }
1556 
1557 /*
1558  * Close wrapper for fifo's.
1559  *
1560  * Update the times on the inode then do device close.
1561  */
1562 ufsfifo_close(ap)
1563 	struct vop_close_args *ap;
1564 {
1565 	extern int (**fifo_vnodeop_p)();
1566 	register struct inode *ip = VTOI(ap->a_vp);
1567 
1568 	if (ap->a_vp->v_usecount > 1 && !(ip->i_flag & ILOCKED))
1569 		ITIMES(ip, &time, &time);
1570 	return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_close), ap));
1571 }
1572 #endif /* FIFO */
1573 
1574 /*
1575  * Advisory record locking support
1576  */
1577 int
1578 ufs_advlock(ap)
1579 	struct vop_advlock_args *ap;
1580 {
1581 	register struct inode *ip = VTOI(ap->a_vp);
1582 	register struct flock *fl = ap->a_fl;
1583 	register struct lockf *lock;
1584 	off_t start, end;
1585 	int error;
1586 
1587 	/*
1588 	 * Avoid the common case of unlocking when inode has no locks.
1589 	 */
1590 	if (ip->i_lockf == (struct lockf *)0) {
1591 		if (ap->a_op != F_SETLK) {
1592 			fl->l_type = F_UNLCK;
1593 			return (0);
1594 		}
1595 	}
1596 	/*
1597 	 * Convert the flock structure into a start and end.
1598 	 */
1599 	switch (fl->l_whence) {
1600 
1601 	case SEEK_SET:
1602 	case SEEK_CUR:
1603 		/*
1604 		 * Caller is responsible for adding any necessary offset
1605 		 * when SEEK_CUR is used.
1606 		 */
1607 		start = fl->l_start;
1608 		break;
1609 
1610 	case SEEK_END:
1611 		start = ip->i_size + fl->l_start;
1612 		break;
1613 
1614 	default:
1615 		return (EINVAL);
1616 	}
1617 	if (start < 0)
1618 		return (EINVAL);
1619 	if (fl->l_len == 0)
1620 		end = -1;
1621 	else
1622 		end = start + fl->l_len - 1;
1623 	/*
1624 	 * Create the lockf structure
1625 	 */
1626 	MALLOC(lock, struct lockf *, sizeof *lock, M_LOCKF, M_WAITOK);
1627 	lock->lf_start = start;
1628 	lock->lf_end = end;
1629 	lock->lf_id = ap->a_id;
1630 	lock->lf_inode = ip;
1631 	lock->lf_type = fl->l_type;
1632 	lock->lf_next = (struct lockf *)0;
1633 	lock->lf_block = (struct lockf *)0;
1634 	lock->lf_flags = ap->a_flags;
1635 	/*
1636 	 * Do the requested operation.
1637 	 */
1638 	switch(ap->a_op) {
1639 	case F_SETLK:
1640 		return (lf_setlock(lock));
1641 
1642 	case F_UNLCK:
1643 		error = lf_clearlock(lock);
1644 		FREE(lock, M_LOCKF);
1645 		return (error);
1646 
1647 	case F_GETLK:
1648 		error = lf_getlock(lock, fl);
1649 		FREE(lock, M_LOCKF);
1650 		return (error);
1651 
1652 	default:
1653 		free(lock, M_LOCKF);
1654 		return (EINVAL);
1655 	}
1656 	/* NOTREACHED */
1657 }
1658 
1659 /*
1660  * Initialize the vnode associated with a new inode, handle aliased
1661  * vnodes.
1662  */
1663 int
1664 ufs_vinit(mntp, specops, fifoops, vpp)
1665 	struct mount *mntp;
1666 	int (**specops)();
1667 	int (**fifoops)();
1668 	struct vnode **vpp;
1669 {
1670 	struct inode *ip, *nip;
1671 	struct vnode *vp, *nvp;
1672 	extern int (**spec_vnodeop_p)();
1673 
1674 	vp = *vpp;
1675 	ip = VTOI(vp);
1676 	switch(vp->v_type = IFTOVT(ip->i_mode)) {
1677 	case VCHR:
1678 	case VBLK:
1679 		vp->v_op = specops;
1680 		if (nvp = checkalias(vp, ip->i_rdev, mntp)) {
1681 			/*
1682 			 * Discard unneeded vnode, but save its inode.
1683 			 */
1684 			remque(ip);
1685 			IUNLOCK(ip);
1686 			nvp->v_data = vp->v_data;
1687 			vp->v_data = NULL;
1688 			vp->v_op = spec_vnodeop_p;
1689 			vrele(vp);
1690 			vgone(vp);
1691 			/*
1692 			 * Reinitialize aliased inode.
1693 			 */
1694 			vp = nvp;
1695 			ip->i_vnode = vp;
1696 			ufs_ihashins(ip);
1697 		}
1698 		break;
1699 	case VFIFO:
1700 #ifdef FIFO
1701 		vp->v_op = fifoops;
1702 		break;
1703 #else
1704 		return (EOPNOTSUPP);
1705 #endif
1706 	}
1707 	if (ip->i_number == ROOTINO)
1708                 vp->v_flag |= VROOT;
1709 	/*
1710 	 * Initialize modrev times
1711 	 */
1712 	SETHIGH(ip->i_modrev, mono_time.tv_sec);
1713 	SETLOW(ip->i_modrev, mono_time.tv_usec * 4294);
1714 	*vpp = vp;
1715 	return (0);
1716 }
1717 
1718 /*
1719  * Allocate a new inode.
1720  */
1721 int
1722 ufs_makeinode(mode, dvp, vpp, cnp)
1723 	int mode;
1724 	struct vnode *dvp;
1725 	struct vnode **vpp;
1726 	struct componentname *cnp;
1727 {
1728 	USES_VOP_UPDATE;
1729 	USES_VOP_VALLOC;
1730 	USES_VOP_VFREE;
1731 	register struct inode *ip, *pdir;
1732 	struct vnode *tvp;
1733 	int error;
1734 
1735 	pdir = VTOI(dvp);
1736 #ifdef DIAGNOSTIC
1737 	if ((cnp->cn_flags & HASBUF) == 0)
1738 		panic("ufs_makeinode: no name");
1739 #endif
1740 	*vpp = NULL;
1741 	if ((mode & IFMT) == 0)
1742 		mode |= IFREG;
1743 
1744 	if (error = VOP_VALLOC(dvp, mode, cnp->cn_cred, &tvp)) {
1745 		free(cnp->cn_pnbuf, M_NAMEI);
1746 		ufs_iput(pdir);
1747 		return (error);
1748 	}
1749 	ip = VTOI(tvp);
1750 	ip->i_uid = cnp->cn_cred->cr_uid;
1751 	ip->i_gid = pdir->i_gid;
1752 #ifdef QUOTA
1753 	if ((error = getinoquota(ip)) ||
1754 	    (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
1755 		free(cnp->cn_pnbuf, M_NAMEI);
1756 		VOP_VFREE(tvp, ip->i_number, mode);
1757 		ufs_iput(ip);
1758 		ufs_iput(pdir);
1759 		return (error);
1760 	}
1761 #endif
1762 	ip->i_flag |= IACC|IUPD|ICHG;
1763 	ip->i_mode = mode;
1764 	tvp->v_type = IFTOVT(mode);	/* Rest init'd in iget() */
1765 	ip->i_nlink = 1;
1766 	if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
1767 	    suser(cnp->cn_cred, NULL))
1768 		ip->i_mode &= ~ISGID;
1769 
1770 	/*
1771 	 * Make sure inode goes to disk before directory entry.
1772 	 */
1773 	if (error = VOP_UPDATE(tvp, &time, &time, 1))
1774 		goto bad;
1775 	if (error = ufs_direnter(ip, dvp, cnp))
1776 		goto bad;
1777 	if ((cnp->cn_flags & SAVESTART) == 0)
1778 		FREE(cnp->cn_pnbuf, M_NAMEI);
1779 	ufs_iput(pdir);
1780 	*vpp = tvp;
1781 	return (0);
1782 
1783 bad:
1784 	/*
1785 	 * Write error occurred trying to update the inode
1786 	 * or the directory so must deallocate the inode.
1787 	 */
1788 	free(cnp->cn_pnbuf, M_NAMEI);
1789 	ufs_iput(pdir);
1790 	ip->i_nlink = 0;
1791 	ip->i_flag |= ICHG;
1792 	ufs_iput(ip);
1793 	return (error);
1794 }
1795