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