xref: /original-bsd/sys/ufs/ffs/ufs_vnops.c (revision c289d8ba)
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.48 (Berkeley) 12/14/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 	if (cred->cr_uid) {
465 		if (vp->v_type != VDIR && mode & ISVTX)
466 			return (EFTYPE);
467 		if (!groupmember(ip->i_gid, cred) && mode & ISGID)
468 			return (EPERM);
469 	}
470 	ip->i_mode &= ~07777;
471 	ip->i_mode |= mode & 07777;
472 	ip->i_flag |= ICHG;
473 	if ((vp->v_flag & VTEXT) && (ip->i_mode & ISVTX) == 0)
474 		(void) vnode_pager_uncache(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 n, on, flags;
657 	int 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 			vnode_pager_setsize(vp, ip->i_size);
711 		}
712 		size = blksize(fs, ip, lbn);
713 		(void) vnode_pager_uncache(vp);
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 		/*
1040 		 * If the target directory is in the same
1041 		 * directory as the source directory,
1042 		 * decrement the link count on the parent
1043 		 * of the target directory.
1044 		 */
1045 		 if (doingdirectory && !newparent) {
1046 			dp->i_nlink--;
1047 			dp->i_flag |= ICHG;
1048 		}
1049 		vput(ITOV(dp));
1050 		/*
1051 		 * Adjust the link count of the target to
1052 		 * reflect the dirrewrite above.  If this is
1053 		 * a directory it is empty and there are
1054 		 * no links to it, so we can squash the inode and
1055 		 * any space associated with it.  We disallowed
1056 		 * renaming over top of a directory with links to
1057 		 * it above, as the remaining link would point to
1058 		 * a directory without "." or ".." entries.
1059 		 */
1060 		xp->i_nlink--;
1061 		if (doingdirectory) {
1062 			if (--xp->i_nlink != 0)
1063 				panic("rename: linked directory");
1064 			error = itrunc(xp, (u_long)0, IO_SYNC);
1065 		}
1066 		xp->i_flag |= ICHG;
1067 		iput(xp);
1068 		xp = NULL;
1069 	}
1070 
1071 	/*
1072 	 * 3) Unlink the source.
1073 	 */
1074 	fndp->ni_nameiop = DELETE | LOCKPARENT | LOCKLEAF;
1075 	(void)namei(fndp);
1076 	if (fndp->ni_vp != NULL) {
1077 		xp = VTOI(fndp->ni_vp);
1078 		dp = VTOI(fndp->ni_dvp);
1079 	} else {
1080 		if (fndp->ni_dvp != NULL)
1081 			vput(fndp->ni_dvp);
1082 		xp = NULL;
1083 		dp = NULL;
1084 	}
1085 	/*
1086 	 * Ensure that the directory entry still exists and has not
1087 	 * changed while the new name has been entered. If the source is
1088 	 * a file then the entry may have been unlinked or renamed. In
1089 	 * either case there is no further work to be done. If the source
1090 	 * is a directory then it cannot have been rmdir'ed; its link
1091 	 * count of three would cause a rmdir to fail with ENOTEMPTY.
1092 	 * The IRENAME flag ensures that it cannot be moved by another
1093 	 * rename.
1094 	 */
1095 	if (xp != ip) {
1096 		if (doingdirectory)
1097 			panic("rename: lost dir entry");
1098 	} else {
1099 		/*
1100 		 * If the source is a directory with a
1101 		 * new parent, the link count of the old
1102 		 * parent directory must be decremented
1103 		 * and ".." set to point to the new parent.
1104 		 */
1105 		if (doingdirectory && newparent) {
1106 			dp->i_nlink--;
1107 			dp->i_flag |= ICHG;
1108 			error = vn_rdwr(UIO_READ, ITOV(xp), (caddr_t)&dirbuf,
1109 				sizeof (struct dirtemplate), (off_t)0,
1110 				UIO_SYSSPACE, IO_NODELOCKED,
1111 				tndp->ni_cred, (int *)0);
1112 			if (error == 0) {
1113 				if (dirbuf.dotdot_namlen != 2 ||
1114 				    dirbuf.dotdot_name[0] != '.' ||
1115 				    dirbuf.dotdot_name[1] != '.') {
1116 					dirbad(xp, 12, "rename: mangled dir");
1117 				} else {
1118 					dirbuf.dotdot_ino = newparent;
1119 					(void) vn_rdwr(UIO_WRITE, ITOV(xp),
1120 					    (caddr_t)&dirbuf,
1121 					    sizeof (struct dirtemplate),
1122 					    (off_t)0, UIO_SYSSPACE,
1123 					    IO_NODELOCKED|IO_SYNC,
1124 					    tndp->ni_cred, (int *)0);
1125 					cache_purge(ITOV(dp));
1126 				}
1127 			}
1128 		}
1129 		error = dirremove(fndp);
1130 		if (!error) {
1131 			xp->i_nlink--;
1132 			xp->i_flag |= ICHG;
1133 		}
1134 		xp->i_flag &= ~IRENAME;
1135 	}
1136 	if (dp)
1137 		vput(ITOV(dp));
1138 	if (xp)
1139 		vput(ITOV(xp));
1140 	vrele(ITOV(ip));
1141 	return (error);
1142 
1143 bad:
1144 	if (xp)
1145 		vput(ITOV(xp));
1146 	vput(ITOV(dp));
1147 out:
1148 	ip->i_nlink--;
1149 	ip->i_flag |= ICHG;
1150 	vrele(ITOV(ip));
1151 	return (error);
1152 }
1153 
1154 /*
1155  * A virgin directory (no blushing please).
1156  */
1157 struct dirtemplate mastertemplate = {
1158 	0, 12, 1, ".",
1159 	0, DIRBLKSIZ - 12, 2, ".."
1160 };
1161 
1162 /*
1163  * Mkdir system call
1164  */
1165 ufs_mkdir(ndp, vap)
1166 	struct nameidata *ndp;
1167 	struct vattr *vap;
1168 {
1169 	register struct inode *ip, *dp;
1170 	struct inode *tip;
1171 	struct vnode *dvp;
1172 	struct dirtemplate dirtemplate;
1173 	int error;
1174 	int dmode;
1175 
1176 	dvp = ndp->ni_dvp;
1177 	dp = VTOI(dvp);
1178 	dmode = vap->va_mode&0777;
1179 	dmode |= IFDIR;
1180 	/*
1181 	 * Must simulate part of maknode here
1182 	 * in order to acquire the inode, but
1183 	 * not have it entered in the parent
1184 	 * directory.  The entry is made later
1185 	 * after writing "." and ".." entries out.
1186 	 */
1187 	if (error = ialloc(dp, dirpref(dp->i_fs), dmode, ndp->ni_cred, &tip)) {
1188 		iput(dp);
1189 		return (error);
1190 	}
1191 	ip = tip;
1192 	ip->i_uid = ndp->ni_cred->cr_uid;
1193 	ip->i_gid = dp->i_gid;
1194 #ifdef QUOTA
1195 	if ((error = getinoquota(ip)) ||
1196 	    (error = chkiq(ip, 1, ndp->ni_cred, 0))) {
1197 		ifree(ip, ip->i_number, dmode);
1198 		iput(ip);
1199 		iput(dp);
1200 		return (error);
1201 	}
1202 #endif
1203 	ip->i_flag |= IACC|IUPD|ICHG;
1204 	ip->i_mode = dmode;
1205 	ITOV(ip)->v_type = VDIR;	/* Rest init'd in iget() */
1206 	ip->i_nlink = 2;
1207 	error = iupdat(ip, &time, &time, 1);
1208 
1209 	/*
1210 	 * Bump link count in parent directory
1211 	 * to reflect work done below.  Should
1212 	 * be done before reference is created
1213 	 * so reparation is possible if we crash.
1214 	 */
1215 	dp->i_nlink++;
1216 	dp->i_flag |= ICHG;
1217 	error = iupdat(dp, &time, &time, 1);
1218 
1219 	/*
1220 	 * Initialize directory with "."
1221 	 * and ".." from static template.
1222 	 */
1223 	dirtemplate = mastertemplate;
1224 	dirtemplate.dot_ino = ip->i_number;
1225 	dirtemplate.dotdot_ino = dp->i_number;
1226 	error = vn_rdwr(UIO_WRITE, ITOV(ip), (caddr_t)&dirtemplate,
1227 		sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE,
1228 		IO_NODELOCKED|IO_SYNC, ndp->ni_cred, (int *)0);
1229 	if (error) {
1230 		dp->i_nlink--;
1231 		dp->i_flag |= ICHG;
1232 		goto bad;
1233 	}
1234 	if (DIRBLKSIZ > dp->i_fs->fs_fsize) {
1235 		panic("mkdir: blksize");     /* XXX - should grow w/balloc() */
1236 	} else {
1237 		ip->i_size = DIRBLKSIZ;
1238 		ip->i_flag |= ICHG;
1239 	}
1240 	/*
1241 	 * Directory all set up, now
1242 	 * install the entry for it in
1243 	 * the parent directory.
1244 	 */
1245 	error = direnter(ip, ndp);
1246 	dp = NULL;
1247 	if (error) {
1248 		ndp->ni_nameiop = LOOKUP | NOCACHE;
1249 		error = namei(ndp);
1250 		if (!error) {
1251 			dp = VTOI(ndp->ni_vp);
1252 			dp->i_nlink--;
1253 			dp->i_flag |= ICHG;
1254 		}
1255 	}
1256 bad:
1257 	/*
1258 	 * No need to do an explicit itrunc here,
1259 	 * vrele will do this for us because we set
1260 	 * the link count to 0.
1261 	 */
1262 	if (error) {
1263 		ip->i_nlink = 0;
1264 		ip->i_flag |= ICHG;
1265 		iput(ip);
1266 	} else
1267 		ndp->ni_vp = ITOV(ip);
1268 	if (dp)
1269 		iput(dp);
1270 	return (error);
1271 }
1272 
1273 /*
1274  * Rmdir system call.
1275  */
1276 ufs_rmdir(ndp)
1277 	register struct nameidata *ndp;
1278 {
1279 	register struct inode *ip, *dp;
1280 	int error = 0;
1281 
1282 	ip = VTOI(ndp->ni_vp);
1283 	dp = VTOI(ndp->ni_dvp);
1284 	/*
1285 	 * No rmdir "." please.
1286 	 */
1287 	if (dp == ip) {
1288 		vrele(ITOV(dp));
1289 		iput(ip);
1290 		return (EINVAL);
1291 	}
1292 	/*
1293 	 * Verify the directory is empty (and valid).
1294 	 * (Rmdir ".." won't be valid since
1295 	 *  ".." will contain a reference to
1296 	 *  the current directory and thus be
1297 	 *  non-empty.)
1298 	 */
1299 	if (ip->i_nlink != 2 || !dirempty(ip, dp->i_number, ndp->ni_cred)) {
1300 		error = ENOTEMPTY;
1301 		goto out;
1302 	}
1303 	/*
1304 	 * Delete reference to directory before purging
1305 	 * inode.  If we crash in between, the directory
1306 	 * will be reattached to lost+found,
1307 	 */
1308 	if (error = dirremove(ndp))
1309 		goto out;
1310 	dp->i_nlink--;
1311 	dp->i_flag |= ICHG;
1312 	cache_purge(ITOV(dp));
1313 	iput(dp);
1314 	ndp->ni_dvp = NULL;
1315 	/*
1316 	 * Truncate inode.  The only stuff left
1317 	 * in the directory is "." and "..".  The
1318 	 * "." reference is inconsequential since
1319 	 * we're quashing it.  The ".." reference
1320 	 * has already been adjusted above.  We've
1321 	 * removed the "." reference and the reference
1322 	 * in the parent directory, but there may be
1323 	 * other hard links so decrement by 2 and
1324 	 * worry about them later.
1325 	 */
1326 	ip->i_nlink -= 2;
1327 	error = itrunc(ip, (u_long)0, IO_SYNC);
1328 	cache_purge(ITOV(ip));
1329 out:
1330 	if (ndp->ni_dvp)
1331 		iput(dp);
1332 	iput(ip);
1333 	return (error);
1334 }
1335 
1336 /*
1337  * symlink -- make a symbolic link
1338  */
1339 ufs_symlink(ndp, vap, target)
1340 	struct nameidata *ndp;
1341 	struct vattr *vap;
1342 	char *target;
1343 {
1344 	struct inode *ip;
1345 	int error;
1346 
1347 	error = maknode(IFLNK | vap->va_mode, ndp, &ip);
1348 	if (error)
1349 		return (error);
1350 	error = vn_rdwr(UIO_WRITE, ITOV(ip), target, strlen(target), (off_t)0,
1351 		UIO_SYSSPACE, IO_NODELOCKED, ndp->ni_cred, (int *)0);
1352 	iput(ip);
1353 	return (error);
1354 }
1355 
1356 /*
1357  * Vnode op for read and write
1358  */
1359 ufs_readdir(vp, uio, cred, eofflagp)
1360 	struct vnode *vp;
1361 	register struct uio *uio;
1362 	struct ucred *cred;
1363 	int *eofflagp;
1364 {
1365 	int count, lost, error;
1366 
1367 	count = uio->uio_resid;
1368 	count &= ~(DIRBLKSIZ - 1);
1369 	lost = uio->uio_resid - count;
1370 	if (count < DIRBLKSIZ || (uio->uio_offset & (DIRBLKSIZ -1)))
1371 		return (EINVAL);
1372 	uio->uio_resid = count;
1373 	uio->uio_iov->iov_len = count;
1374 	error = ufs_read(vp, uio, 0, cred);
1375 	uio->uio_resid += lost;
1376 	if ((VTOI(vp)->i_size - uio->uio_offset) <= 0)
1377 		*eofflagp = 1;
1378 	else
1379 		*eofflagp = 0;
1380 	return (error);
1381 }
1382 
1383 /*
1384  * Return target name of a symbolic link
1385  */
1386 ufs_readlink(vp, uiop, cred)
1387 	struct vnode *vp;
1388 	struct uio *uiop;
1389 	struct ucred *cred;
1390 {
1391 
1392 	return (ufs_read(vp, uiop, 0, cred));
1393 }
1394 
1395 /*
1396  * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually
1397  * done. Nothing to do at the moment.
1398  */
1399 /* ARGSUSED */
1400 ufs_abortop(ndp)
1401 	struct nameidata *ndp;
1402 {
1403 
1404 	return (0);
1405 }
1406 
1407 /*
1408  * Lock an inode.
1409  */
1410 ufs_lock(vp)
1411 	struct vnode *vp;
1412 {
1413 	register struct inode *ip = VTOI(vp);
1414 
1415 	ILOCK(ip);
1416 	return (0);
1417 }
1418 
1419 /*
1420  * Unlock an inode.
1421  */
1422 ufs_unlock(vp)
1423 	struct vnode *vp;
1424 {
1425 	register struct inode *ip = VTOI(vp);
1426 
1427 	if (!(ip->i_flag & ILOCKED))
1428 		panic("ufs_unlock NOT LOCKED");
1429 	IUNLOCK(ip);
1430 	return (0);
1431 }
1432 
1433 /*
1434  * Check for a locked inode.
1435  */
1436 ufs_islocked(vp)
1437 	struct vnode *vp;
1438 {
1439 
1440 	if (VTOI(vp)->i_flag & ILOCKED)
1441 		return (1);
1442 	return (0);
1443 }
1444 
1445 /*
1446  * Get access to bmap
1447  */
1448 ufs_bmap(vp, bn, vpp, bnp)
1449 	struct vnode *vp;
1450 	daddr_t bn;
1451 	struct vnode **vpp;
1452 	daddr_t *bnp;
1453 {
1454 	struct inode *ip = VTOI(vp);
1455 
1456 	if (vpp != NULL)
1457 		*vpp = ip->i_devvp;
1458 	if (bnp == NULL)
1459 		return (0);
1460 	return (bmap(ip, bn, bnp));
1461 }
1462 
1463 /*
1464  * Calculate the logical to physical mapping if not done already,
1465  * then call the device strategy routine.
1466  */
1467 int checkoverlap = 0;
1468 
1469 ufs_strategy(bp)
1470 	register struct buf *bp;
1471 {
1472 	register struct inode *ip = VTOI(bp->b_vp);
1473 	struct vnode *vp;
1474 	int error;
1475 
1476 	if (bp->b_vp->v_type == VBLK || bp->b_vp->v_type == VCHR)
1477 		panic("ufs_strategy: spec");
1478 	if (bp->b_blkno == bp->b_lblkno) {
1479 		if (error = bmap(ip, bp->b_lblkno, &bp->b_blkno))
1480 			return (error);
1481 		if ((long)bp->b_blkno == -1)
1482 			clrbuf(bp);
1483 	}
1484 	if ((long)bp->b_blkno == -1) {
1485 		biodone(bp);
1486 		return (0);
1487 	}
1488 #ifdef DIAGNOSTIC
1489 	if (checkoverlap) {
1490 		register struct buf *ep;
1491 		struct buf *ebp;
1492 		daddr_t start, last;
1493 
1494 		ebp = &buf[nbuf];
1495 		start = bp->b_blkno;
1496 		last = start + btodb(bp->b_bcount) - 1;
1497 		for (ep = buf; ep < ebp; ep++) {
1498 			if (ep == bp || (ep->b_flags & B_INVAL) ||
1499 			    ep->b_vp == NULLVP)
1500 				continue;
1501 			if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0))
1502 				continue;
1503 			if (vp != ip->i_devvp)
1504 				continue;
1505 			/* look for overlap */
1506 			if (ep->b_bcount == 0 || ep->b_blkno > last ||
1507 			    ep->b_blkno + btodb(ep->b_bcount) <= start)
1508 				continue;
1509 			vprint("Disk overlap", vp);
1510 			printf("\tstart %d, end %d overlap start %d, end %d\n",
1511 				start, last, ep->b_blkno,
1512 				ep->b_blkno + btodb(ep->b_bcount) - 1);
1513 			panic("Disk buffer overlap");
1514 		}
1515 	}
1516 #endif /* DIAGNOSTIC */
1517 	vp = ip->i_devvp;
1518 	bp->b_dev = vp->v_rdev;
1519 	(*(vp->v_op->vn_strategy))(bp);
1520 	return (0);
1521 }
1522 
1523 /*
1524  * Print out the contents of an inode.
1525  */
1526 ufs_print(vp)
1527 	struct vnode *vp;
1528 {
1529 	register struct inode *ip = VTOI(vp);
1530 
1531 	printf("tag VT_UFS, ino %d, on dev %d, %d", ip->i_number,
1532 		major(ip->i_dev), minor(ip->i_dev));
1533 #ifdef FIFO
1534 	if (vp->v_type == VFIFO)
1535 		fifo_printinfo(vp);
1536 #endif /* FIFO */
1537 	printf("%s\n", (ip->i_flag & ILOCKED) ? " (LOCKED)" : "");
1538 	if (ip->i_spare0 == 0)
1539 		return;
1540 	printf("\towner pid %d", ip->i_spare0);
1541 	if (ip->i_spare1)
1542 		printf(" waiting pid %d", ip->i_spare1);
1543 	printf("\n");
1544 }
1545 
1546 /*
1547  * Read wrapper for special devices.
1548  */
1549 ufsspec_read(vp, uio, ioflag, cred)
1550 	struct vnode *vp;
1551 	struct uio *uio;
1552 	int ioflag;
1553 	struct ucred *cred;
1554 {
1555 
1556 	/*
1557 	 * Set access flag.
1558 	 */
1559 	VTOI(vp)->i_flag |= IACC;
1560 	return (spec_read(vp, uio, ioflag, cred));
1561 }
1562 
1563 /*
1564  * Write wrapper for special devices.
1565  */
1566 ufsspec_write(vp, uio, ioflag, cred)
1567 	struct vnode *vp;
1568 	struct uio *uio;
1569 	int ioflag;
1570 	struct ucred *cred;
1571 {
1572 
1573 	/*
1574 	 * Set update and change flags.
1575 	 */
1576 	VTOI(vp)->i_flag |= IUPD|ICHG;
1577 	return (spec_write(vp, uio, ioflag, cred));
1578 }
1579 
1580 /*
1581  * Close wrapper for special devices.
1582  *
1583  * Update the times on the inode then do device close.
1584  */
1585 ufsspec_close(vp, fflag, cred)
1586 	struct vnode *vp;
1587 	int fflag;
1588 	struct ucred *cred;
1589 {
1590 	register struct inode *ip = VTOI(vp);
1591 
1592 	if (vp->v_usecount > 1 && !(ip->i_flag & ILOCKED))
1593 		ITIMES(ip, &time, &time);
1594 	return (spec_close(vp, fflag, cred));
1595 }
1596 
1597 #ifdef FIFO
1598 /*
1599  * Read wrapper for fifo's
1600  */
1601 ufsfifo_read(vp, uio, ioflag, cred)
1602 	struct vnode *vp;
1603 	struct uio *uio;
1604 	int ioflag;
1605 	struct ucred *cred;
1606 {
1607 
1608 	/*
1609 	 * Set access flag.
1610 	 */
1611 	VTOI(vp)->i_flag |= IACC;
1612 	return (fifo_read(vp, uio, ioflag, cred));
1613 }
1614 
1615 /*
1616  * Write wrapper for fifo's.
1617  */
1618 ufsfifo_write(vp, uio, ioflag, cred)
1619 	struct vnode *vp;
1620 	struct uio *uio;
1621 	int ioflag;
1622 	struct ucred *cred;
1623 {
1624 
1625 	/*
1626 	 * Set update and change flags.
1627 	 */
1628 	VTOI(vp)->i_flag |= IUPD|ICHG;
1629 	return (fifo_write(vp, uio, ioflag, cred));
1630 }
1631 
1632 /*
1633  * Close wrapper for fifo's.
1634  *
1635  * Update the times on the inode then do device close.
1636  */
1637 ufsfifo_close(vp, fflag, cred)
1638 	struct vnode *vp;
1639 	int fflag;
1640 	struct ucred *cred;
1641 {
1642 	register struct inode *ip = VTOI(vp);
1643 
1644 	if (vp->v_usecount > 1 && !(ip->i_flag & ILOCKED))
1645 		ITIMES(ip, &time, &time);
1646 	return (fifo_close(vp, fflag, cred));
1647 }
1648 #endif /* FIFO */
1649 
1650 /*
1651  * Make a new file.
1652  */
1653 maknode(mode, ndp, ipp)
1654 	int mode;
1655 	register struct nameidata *ndp;
1656 	struct inode **ipp;
1657 {
1658 	register struct inode *ip;
1659 	struct inode *tip;
1660 	register struct inode *pdir = VTOI(ndp->ni_dvp);
1661 	ino_t ipref;
1662 	int error;
1663 
1664 	*ipp = 0;
1665 	if ((mode & IFMT) == 0)
1666 		mode |= IFREG;
1667 	if ((mode & IFMT) == IFDIR)
1668 		ipref = dirpref(pdir->i_fs);
1669 	else
1670 		ipref = pdir->i_number;
1671 	if (error = ialloc(pdir, ipref, mode, ndp->ni_cred, &tip)) {
1672 		iput(pdir);
1673 		return (error);
1674 	}
1675 	ip = tip;
1676 	ip->i_uid = ndp->ni_cred->cr_uid;
1677 	ip->i_gid = pdir->i_gid;
1678 #ifdef QUOTA
1679 	if ((error = getinoquota(ip)) ||
1680 	    (error = chkiq(ip, 1, ndp->ni_cred, 0))) {
1681 		ifree(ip, ip->i_number, mode);
1682 		iput(ip);
1683 		iput(pdir);
1684 		return (error);
1685 	}
1686 #endif
1687 	ip->i_flag |= IACC|IUPD|ICHG;
1688 	ip->i_mode = mode;
1689 	ITOV(ip)->v_type = IFTOVT(mode);	/* Rest init'd in iget() */
1690 	ip->i_nlink = 1;
1691 	if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, ndp->ni_cred) &&
1692 	    suser(ndp->ni_cred, NULL))
1693 		ip->i_mode &= ~ISGID;
1694 
1695 	/*
1696 	 * Make sure inode goes to disk before directory entry.
1697 	 */
1698 	if (error = iupdat(ip, &time, &time, 1))
1699 		goto bad;
1700 	if (error = direnter(ip, ndp)) {
1701 		pdir = NULL;
1702 		goto bad;
1703 	}
1704 	*ipp = ip;
1705 	return (0);
1706 
1707 bad:
1708 	/*
1709 	 * Write error occurred trying to update the inode
1710 	 * or the directory so must deallocate the inode.
1711 	 */
1712 	if (pdir)
1713 		iput(pdir);
1714 	ip->i_nlink = 0;
1715 	ip->i_flag |= ICHG;
1716 	iput(ip);
1717 	return (error);
1718 }
1719