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