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