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