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