xref: /dragonfly/sys/vfs/ufs/ufs_vnops.c (revision 984263bc)
1 /*
2  * Copyright (c) 1982, 1986, 1989, 1993, 1995
3  *	The Regents of the University of California.  All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the University of
21  *	California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  *	@(#)ufs_vnops.c	8.27 (Berkeley) 5/27/95
39  * $FreeBSD: src/sys/ufs/ufs/ufs_vnops.c,v 1.131.2.8 2003/01/02 17:26:19 bde Exp $
40  */
41 
42 #include "opt_quota.h"
43 #include "opt_suiddir.h"
44 #include "opt_ufs.h"
45 
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/namei.h>
49 #include <sys/kernel.h>
50 #include <sys/fcntl.h>
51 #include <sys/stat.h>
52 #include <sys/buf.h>
53 #include <sys/proc.h>
54 #include <sys/mount.h>
55 #include <sys/unistd.h>
56 #include <sys/vnode.h>
57 #include <sys/malloc.h>
58 #include <sys/dirent.h>
59 #include <sys/lockf.h>
60 #include <sys/event.h>
61 #include <sys/conf.h>
62 
63 #include <sys/file.h>		/* XXX */
64 
65 #include <vm/vm.h>
66 #include <vm/vm_extern.h>
67 
68 #include <miscfs/fifofs/fifo.h>
69 
70 #include <ufs/ufs/quota.h>
71 #include <ufs/ufs/inode.h>
72 #include <ufs/ufs/dir.h>
73 #include <ufs/ufs/ufsmount.h>
74 #include <ufs/ufs/ufs_extern.h>
75 #ifdef UFS_DIRHASH
76 #include <ufs/ufs/dirhash.h>
77 #endif
78 
79 static int ufs_access __P((struct vop_access_args *));
80 static int ufs_advlock __P((struct vop_advlock_args *));
81 static int ufs_chmod __P((struct vnode *, int, struct ucred *, struct proc *));
82 static int ufs_chown __P((struct vnode *, uid_t, gid_t, struct ucred *, struct proc *));
83 static int ufs_close __P((struct vop_close_args *));
84 static int ufs_create __P((struct vop_create_args *));
85 static int ufs_getattr __P((struct vop_getattr_args *));
86 static int ufs_link __P((struct vop_link_args *));
87 static int ufs_makeinode __P((int mode, struct vnode *, struct vnode **, struct componentname *));
88 static int ufs_missingop __P((struct vop_generic_args *ap));
89 static int ufs_mkdir __P((struct vop_mkdir_args *));
90 static int ufs_mknod __P((struct vop_mknod_args *));
91 static int ufs_mmap __P((struct vop_mmap_args *));
92 static int ufs_open __P((struct vop_open_args *));
93 static int ufs_pathconf __P((struct vop_pathconf_args *));
94 static int ufs_print __P((struct vop_print_args *));
95 static int ufs_readdir __P((struct vop_readdir_args *));
96 static int ufs_readlink __P((struct vop_readlink_args *));
97 static int ufs_remove __P((struct vop_remove_args *));
98 static int ufs_rename __P((struct vop_rename_args *));
99 static int ufs_rmdir __P((struct vop_rmdir_args *));
100 static int ufs_setattr __P((struct vop_setattr_args *));
101 static int ufs_strategy __P((struct vop_strategy_args *));
102 static int ufs_symlink __P((struct vop_symlink_args *));
103 static int ufs_whiteout __P((struct vop_whiteout_args *));
104 static int ufsfifo_close __P((struct vop_close_args *));
105 static int ufsfifo_kqfilter __P((struct vop_kqfilter_args *));
106 static int ufsfifo_read __P((struct vop_read_args *));
107 static int ufsfifo_write __P((struct vop_write_args *));
108 static int ufsspec_close __P((struct vop_close_args *));
109 static int ufsspec_read __P((struct vop_read_args *));
110 static int ufsspec_write __P((struct vop_write_args *));
111 static int filt_ufsread __P((struct knote *kn, long hint));
112 static int filt_ufswrite __P((struct knote *kn, long hint));
113 static int filt_ufsvnode __P((struct knote *kn, long hint));
114 static void filt_ufsdetach __P((struct knote *kn));
115 static int ufs_kqfilter __P((struct vop_kqfilter_args *ap));
116 
117 union _qcvt {
118 	int64_t qcvt;
119 	int32_t val[2];
120 };
121 #define SETHIGH(q, h) { \
122 	union _qcvt tmp; \
123 	tmp.qcvt = (q); \
124 	tmp.val[_QUAD_HIGHWORD] = (h); \
125 	(q) = tmp.qcvt; \
126 }
127 #define SETLOW(q, l) { \
128 	union _qcvt tmp; \
129 	tmp.qcvt = (q); \
130 	tmp.val[_QUAD_LOWWORD] = (l); \
131 	(q) = tmp.qcvt; \
132 }
133 #define VN_KNOTE(vp, b) \
134 	KNOTE(&vp->v_pollinfo.vpi_selinfo.si_note, (b))
135 
136 /*
137  * A virgin directory (no blushing please).
138  */
139 static struct dirtemplate mastertemplate = {
140 	0, 12, DT_DIR, 1, ".",
141 	0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
142 };
143 static struct odirtemplate omastertemplate = {
144 	0, 12, 1, ".",
145 	0, DIRBLKSIZ - 12, 2, ".."
146 };
147 
148 void
149 ufs_itimes(vp)
150 	struct vnode *vp;
151 {
152 	struct inode *ip;
153 	struct timespec ts;
154 
155 	ip = VTOI(vp);
156 	if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0)
157 		return;
158 	if ((vp->v_type == VBLK || vp->v_type == VCHR) && !DOINGSOFTDEP(vp))
159 		ip->i_flag |= IN_LAZYMOD;
160 	else
161 		ip->i_flag |= IN_MODIFIED;
162 	if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
163 		vfs_timestamp(&ts);
164 		if (ip->i_flag & IN_ACCESS) {
165 			ip->i_atime = ts.tv_sec;
166 			ip->i_atimensec = ts.tv_nsec;
167 		}
168 		if (ip->i_flag & IN_UPDATE) {
169 			ip->i_mtime = ts.tv_sec;
170 			ip->i_mtimensec = ts.tv_nsec;
171 			ip->i_modrev++;
172 		}
173 		if (ip->i_flag & IN_CHANGE) {
174 			ip->i_ctime = ts.tv_sec;
175 			ip->i_ctimensec = ts.tv_nsec;
176 		}
177 	}
178 	ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE);
179 }
180 
181 /*
182  * Create a regular file
183  */
184 int
185 ufs_create(ap)
186 	struct vop_create_args /* {
187 		struct vnode *a_dvp;
188 		struct vnode **a_vpp;
189 		struct componentname *a_cnp;
190 		struct vattr *a_vap;
191 	} */ *ap;
192 {
193 	int error;
194 
195 	error =
196 	    ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode),
197 	    ap->a_dvp, ap->a_vpp, ap->a_cnp);
198 	if (error)
199 		return (error);
200 	VN_KNOTE(ap->a_dvp, NOTE_WRITE);
201 	return (0);
202 }
203 
204 /*
205  * Mknod vnode call
206  */
207 /* ARGSUSED */
208 int
209 ufs_mknod(ap)
210 	struct vop_mknod_args /* {
211 		struct vnode *a_dvp;
212 		struct vnode **a_vpp;
213 		struct componentname *a_cnp;
214 		struct vattr *a_vap;
215 	} */ *ap;
216 {
217 	struct vattr *vap = ap->a_vap;
218 	struct vnode **vpp = ap->a_vpp;
219 	struct inode *ip;
220 	ino_t ino;
221 	int error;
222 
223 	error = ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
224 	    ap->a_dvp, vpp, ap->a_cnp);
225 	if (error)
226 		return (error);
227 	VN_KNOTE(ap->a_dvp, NOTE_WRITE);
228 	ip = VTOI(*vpp);
229 	ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
230 	if (vap->va_rdev != VNOVAL) {
231 		/*
232 		 * Want to be able to use this to make badblock
233 		 * inodes, so don't truncate the dev number.
234 		 */
235 		ip->i_rdev = vap->va_rdev;
236 	}
237 	/*
238 	 * Remove inode, then reload it through VFS_VGET so it is
239 	 * checked to see if it is an alias of an existing entry in
240 	 * the inode cache.
241 	 */
242 	vput(*vpp);
243 	(*vpp)->v_type = VNON;
244 	ino = ip->i_number;	/* Save this before vgone() invalidates ip. */
245 	vgone(*vpp);
246 	error = VFS_VGET(ap->a_dvp->v_mount, ino, vpp);
247 	if (error) {
248 		*vpp = NULL;
249 		return (error);
250 	}
251 	return (0);
252 }
253 
254 /*
255  * Open called.
256  *
257  * Nothing to do.
258  */
259 /* ARGSUSED */
260 int
261 ufs_open(ap)
262 	struct vop_open_args /* {
263 		struct vnode *a_vp;
264 		int  a_mode;
265 		struct ucred *a_cred;
266 		struct proc *a_p;
267 	} */ *ap;
268 {
269 
270 	/*
271 	 * Files marked append-only must be opened for appending.
272 	 */
273 	if ((VTOI(ap->a_vp)->i_flags & APPEND) &&
274 	    (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE)
275 		return (EPERM);
276 	return (0);
277 }
278 
279 /*
280  * Close called.
281  *
282  * Update the times on the inode.
283  */
284 /* ARGSUSED */
285 int
286 ufs_close(ap)
287 	struct vop_close_args /* {
288 		struct vnode *a_vp;
289 		int  a_fflag;
290 		struct ucred *a_cred;
291 		struct proc *a_p;
292 	} */ *ap;
293 {
294 	register struct vnode *vp = ap->a_vp;
295 
296 	simple_lock(&vp->v_interlock);
297 	if (vp->v_usecount > 1)
298 		ufs_itimes(vp);
299 	simple_unlock(&vp->v_interlock);
300 	return (0);
301 }
302 
303 int
304 ufs_access(ap)
305 	struct vop_access_args /* {
306 		struct vnode *a_vp;
307 		int  a_mode;
308 		struct ucred *a_cred;
309 		struct proc *a_p;
310 	} */ *ap;
311 {
312 	struct vnode *vp = ap->a_vp;
313 	struct inode *ip = VTOI(vp);
314 	struct ucred *cred = ap->a_cred;
315 	mode_t mask, mode = ap->a_mode;
316 	register gid_t *gp;
317 	int i;
318 #ifdef QUOTA
319 	int error;
320 #endif
321 
322 	/*
323 	 * Disallow write attempts on read-only file systems;
324 	 * unless the file is a socket, fifo, or a block or
325 	 * character device resident on the file system.
326 	 */
327 	if (mode & VWRITE) {
328 		switch (vp->v_type) {
329 		case VDIR:
330 		case VLNK:
331 		case VREG:
332 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
333 				return (EROFS);
334 #ifdef QUOTA
335 			if ((error = getinoquota(ip)) != 0)
336 				return (error);
337 #endif
338 			break;
339 		default:
340 			break;
341 		}
342 	}
343 
344 	/* If immutable bit set, nobody gets to write it. */
345 	if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE))
346 		return (EPERM);
347 
348 	/* Otherwise, user id 0 always gets access. */
349 	if (cred->cr_uid == 0)
350 		return (0);
351 
352 	mask = 0;
353 
354 	/* Otherwise, check the owner. */
355 	if (cred->cr_uid == ip->i_uid) {
356 		if (mode & VEXEC)
357 			mask |= S_IXUSR;
358 		if (mode & VREAD)
359 			mask |= S_IRUSR;
360 		if (mode & VWRITE)
361 			mask |= S_IWUSR;
362 		return ((ip->i_mode & mask) == mask ? 0 : EACCES);
363 	}
364 
365 	/* Otherwise, check the groups. */
366 	for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
367 		if (ip->i_gid == *gp) {
368 			if (mode & VEXEC)
369 				mask |= S_IXGRP;
370 			if (mode & VREAD)
371 				mask |= S_IRGRP;
372 			if (mode & VWRITE)
373 				mask |= S_IWGRP;
374 			return ((ip->i_mode & mask) == mask ? 0 : EACCES);
375 		}
376 
377 	/* Otherwise, check everyone else. */
378 	if (mode & VEXEC)
379 		mask |= S_IXOTH;
380 	if (mode & VREAD)
381 		mask |= S_IROTH;
382 	if (mode & VWRITE)
383 		mask |= S_IWOTH;
384 	return ((ip->i_mode & mask) == mask ? 0 : EACCES);
385 }
386 
387 /* ARGSUSED */
388 int
389 ufs_getattr(ap)
390 	struct vop_getattr_args /* {
391 		struct vnode *a_vp;
392 		struct vattr *a_vap;
393 		struct ucred *a_cred;
394 		struct proc *a_p;
395 	} */ *ap;
396 {
397 	register struct vnode *vp = ap->a_vp;
398 	register struct inode *ip = VTOI(vp);
399 	register struct vattr *vap = ap->a_vap;
400 
401 	ufs_itimes(vp);
402 	/*
403 	 * Copy from inode table
404 	 */
405 	vap->va_fsid = dev2udev(ip->i_dev);
406 	vap->va_fileid = ip->i_number;
407 	vap->va_mode = ip->i_mode & ~IFMT;
408 	vap->va_nlink = VFSTOUFS(vp->v_mount)->um_i_effnlink_valid ?
409 	    ip->i_effnlink : ip->i_nlink;
410 	vap->va_uid = ip->i_uid;
411 	vap->va_gid = ip->i_gid;
412 	vap->va_rdev = ip->i_rdev;
413 	vap->va_size = ip->i_din.di_size;
414 	vap->va_atime.tv_sec = ip->i_atime;
415 	vap->va_atime.tv_nsec = ip->i_atimensec;
416 	vap->va_mtime.tv_sec = ip->i_mtime;
417 	vap->va_mtime.tv_nsec = ip->i_mtimensec;
418 	vap->va_ctime.tv_sec = ip->i_ctime;
419 	vap->va_ctime.tv_nsec = ip->i_ctimensec;
420 	vap->va_flags = ip->i_flags;
421 	vap->va_gen = ip->i_gen;
422 	vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
423 	vap->va_bytes = dbtob((u_quad_t)ip->i_blocks);
424 	vap->va_type = IFTOVT(ip->i_mode);
425 	vap->va_filerev = ip->i_modrev;
426 	return (0);
427 }
428 
429 /*
430  * Set attribute vnode op. called from several syscalls
431  */
432 int
433 ufs_setattr(ap)
434 	struct vop_setattr_args /* {
435 		struct vnode *a_vp;
436 		struct vattr *a_vap;
437 		struct ucred *a_cred;
438 		struct proc *a_p;
439 	} */ *ap;
440 {
441 	struct vattr *vap = ap->a_vap;
442 	struct vnode *vp = ap->a_vp;
443 	struct inode *ip = VTOI(vp);
444 	struct ucred *cred = ap->a_cred;
445 	struct proc *p = ap->a_p;
446 	int error;
447 
448 	/*
449 	 * Check for unsettable attributes.
450 	 */
451 	if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
452 	    (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
453 	    (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
454 	    ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
455 		return (EINVAL);
456 	}
457 	if (vap->va_flags != VNOVAL) {
458 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
459 			return (EROFS);
460 		if (cred->cr_uid != ip->i_uid &&
461 		    (error = suser_xxx(cred, p, PRISON_ROOT)))
462 			return (error);
463 		if ((cred->cr_uid == 0) && (p->p_prison == NULL)) {
464 			if ((ip->i_flags
465 			    & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) &&
466 			    securelevel > 0)
467 				return (EPERM);
468 			ip->i_flags = vap->va_flags;
469 		} else {
470 			if (ip->i_flags
471 			    & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND) ||
472 			    (vap->va_flags & UF_SETTABLE) != vap->va_flags)
473 				return (EPERM);
474 			ip->i_flags &= SF_SETTABLE;
475 			ip->i_flags |= (vap->va_flags & UF_SETTABLE);
476 		}
477 		ip->i_flag |= IN_CHANGE;
478 		if (vap->va_flags & (IMMUTABLE | APPEND))
479 			return (0);
480 	}
481 	if (ip->i_flags & (IMMUTABLE | APPEND))
482 		return (EPERM);
483 	/*
484 	 * Go through the fields and update iff not VNOVAL.
485 	 */
486 	if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
487 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
488 			return (EROFS);
489 		if ((error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, p)) != 0)
490 			return (error);
491 	}
492 	if (vap->va_size != VNOVAL) {
493 		/*
494 		 * Disallow write attempts on read-only file systems;
495 		 * unless the file is a socket, fifo, or a block or
496 		 * character device resident on the file system.
497 		 */
498 		switch (vp->v_type) {
499 		case VDIR:
500 			return (EISDIR);
501 		case VLNK:
502 		case VREG:
503 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
504 				return (EROFS);
505 			break;
506 		default:
507 			break;
508 		}
509 		if ((error = UFS_TRUNCATE(vp, vap->va_size, 0, cred, p)) != 0)
510 			return (error);
511 	}
512 	ip = VTOI(vp);
513 	if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
514 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
515 			return (EROFS);
516 		if (cred->cr_uid != ip->i_uid &&
517 		    (error = suser_xxx(cred, p, PRISON_ROOT)) &&
518 		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
519 		    (error = VOP_ACCESS(vp, VWRITE, cred, p))))
520 			return (error);
521 		if (vap->va_atime.tv_sec != VNOVAL)
522 			ip->i_flag |= IN_ACCESS;
523 		if (vap->va_mtime.tv_sec != VNOVAL)
524 			ip->i_flag |= IN_CHANGE | IN_UPDATE;
525 		ufs_itimes(vp);
526 		if (vap->va_atime.tv_sec != VNOVAL) {
527 			ip->i_atime = vap->va_atime.tv_sec;
528 			ip->i_atimensec = vap->va_atime.tv_nsec;
529 		}
530 		if (vap->va_mtime.tv_sec != VNOVAL) {
531 			ip->i_mtime = vap->va_mtime.tv_sec;
532 			ip->i_mtimensec = vap->va_mtime.tv_nsec;
533 		}
534 		error = UFS_UPDATE(vp, 0);
535 		if (error)
536 			return (error);
537 	}
538 	error = 0;
539 	if (vap->va_mode != (mode_t)VNOVAL) {
540 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
541 			return (EROFS);
542 		error = ufs_chmod(vp, (int)vap->va_mode, cred, p);
543 	}
544 	VN_KNOTE(vp, NOTE_ATTRIB);
545 	return (error);
546 }
547 
548 /*
549  * Change the mode on a file.
550  * Inode must be locked before calling.
551  */
552 static int
553 ufs_chmod(vp, mode, cred, p)
554 	register struct vnode *vp;
555 	register int mode;
556 	register struct ucred *cred;
557 	struct proc *p;
558 {
559 	register struct inode *ip = VTOI(vp);
560 	int error;
561 
562 	if (cred->cr_uid != ip->i_uid) {
563 	    error = suser_xxx(cred, p, PRISON_ROOT);
564 	    if (error)
565 		return (error);
566 	}
567 	if (cred->cr_uid) {
568 		if (vp->v_type != VDIR && (mode & S_ISTXT))
569 			return (EFTYPE);
570 		if (!groupmember(ip->i_gid, cred) && (mode & ISGID))
571 			return (EPERM);
572 	}
573 	ip->i_mode &= ~ALLPERMS;
574 	ip->i_mode |= (mode & ALLPERMS);
575 	ip->i_flag |= IN_CHANGE;
576 	return (0);
577 }
578 
579 /*
580  * Perform chown operation on inode ip;
581  * inode must be locked prior to call.
582  */
583 static int
584 ufs_chown(vp, uid, gid, cred, p)
585 	register struct vnode *vp;
586 	uid_t uid;
587 	gid_t gid;
588 	struct ucred *cred;
589 	struct proc *p;
590 {
591 	register struct inode *ip = VTOI(vp);
592 	uid_t ouid;
593 	gid_t ogid;
594 	int error = 0;
595 #ifdef QUOTA
596 	register int i;
597 	long change;
598 #endif
599 
600 	if (uid == (uid_t)VNOVAL)
601 		uid = ip->i_uid;
602 	if (gid == (gid_t)VNOVAL)
603 		gid = ip->i_gid;
604 	/*
605 	 * If we don't own the file, are trying to change the owner
606 	 * of the file, or are not a member of the target group,
607 	 * the caller must be superuser or the call fails.
608 	 */
609 	if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid ||
610 	    (gid != ip->i_gid && !groupmember((gid_t)gid, cred))) &&
611 	    (error = suser_xxx(cred, p, PRISON_ROOT)))
612 		return (error);
613 	ogid = ip->i_gid;
614 	ouid = ip->i_uid;
615 #ifdef QUOTA
616 	if ((error = getinoquota(ip)) != 0)
617 		return (error);
618 	if (ouid == uid) {
619 		dqrele(vp, ip->i_dquot[USRQUOTA]);
620 		ip->i_dquot[USRQUOTA] = NODQUOT;
621 	}
622 	if (ogid == gid) {
623 		dqrele(vp, ip->i_dquot[GRPQUOTA]);
624 		ip->i_dquot[GRPQUOTA] = NODQUOT;
625 	}
626 	change = ip->i_blocks;
627 	(void) chkdq(ip, -change, cred, CHOWN);
628 	(void) chkiq(ip, -1, cred, CHOWN);
629 	for (i = 0; i < MAXQUOTAS; i++) {
630 		dqrele(vp, ip->i_dquot[i]);
631 		ip->i_dquot[i] = NODQUOT;
632 	}
633 #endif
634 	ip->i_gid = gid;
635 	ip->i_uid = uid;
636 #ifdef QUOTA
637 	if ((error = getinoquota(ip)) == 0) {
638 		if (ouid == uid) {
639 			dqrele(vp, ip->i_dquot[USRQUOTA]);
640 			ip->i_dquot[USRQUOTA] = NODQUOT;
641 		}
642 		if (ogid == gid) {
643 			dqrele(vp, ip->i_dquot[GRPQUOTA]);
644 			ip->i_dquot[GRPQUOTA] = NODQUOT;
645 		}
646 		if ((error = chkdq(ip, change, cred, CHOWN)) == 0) {
647 			if ((error = chkiq(ip, 1, cred, CHOWN)) == 0)
648 				goto good;
649 			else
650 				(void) chkdq(ip, -change, cred, CHOWN|FORCE);
651 		}
652 		for (i = 0; i < MAXQUOTAS; i++) {
653 			dqrele(vp, ip->i_dquot[i]);
654 			ip->i_dquot[i] = NODQUOT;
655 		}
656 	}
657 	ip->i_gid = ogid;
658 	ip->i_uid = ouid;
659 	if (getinoquota(ip) == 0) {
660 		if (ouid == uid) {
661 			dqrele(vp, ip->i_dquot[USRQUOTA]);
662 			ip->i_dquot[USRQUOTA] = NODQUOT;
663 		}
664 		if (ogid == gid) {
665 			dqrele(vp, ip->i_dquot[GRPQUOTA]);
666 			ip->i_dquot[GRPQUOTA] = NODQUOT;
667 		}
668 		(void) chkdq(ip, change, cred, FORCE|CHOWN);
669 		(void) chkiq(ip, 1, cred, FORCE|CHOWN);
670 		(void) getinoquota(ip);
671 	}
672 	return (error);
673 good:
674 	if (getinoquota(ip))
675 		panic("ufs_chown: lost quota");
676 #endif /* QUOTA */
677 	ip->i_flag |= IN_CHANGE;
678 	if (cred->cr_uid != 0 && (ouid != uid || ogid != gid))
679 		ip->i_mode &= ~(ISUID | ISGID);
680 	return (0);
681 }
682 
683 /*
684  * Mmap a file
685  *
686  * NB Currently unsupported.
687  */
688 /* ARGSUSED */
689 int
690 ufs_mmap(ap)
691 	struct vop_mmap_args /* {
692 		struct vnode *a_vp;
693 		int  a_fflags;
694 		struct ucred *a_cred;
695 		struct proc *a_p;
696 	} */ *ap;
697 {
698 
699 	return (EINVAL);
700 }
701 
702 int
703 ufs_remove(ap)
704 	struct vop_remove_args /* {
705 		struct vnode *a_dvp;
706 		struct vnode *a_vp;
707 		struct componentname *a_cnp;
708 	} */ *ap;
709 {
710 	struct inode *ip;
711 	struct vnode *vp = ap->a_vp;
712 	struct vnode *dvp = ap->a_dvp;
713 	int error;
714 
715 	ip = VTOI(vp);
716 	if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
717 	    (VTOI(dvp)->i_flags & APPEND)) {
718 		error = EPERM;
719 		goto out;
720 	}
721 	error = ufs_dirremove(dvp, ip, ap->a_cnp->cn_flags, 0);
722 	VN_KNOTE(vp, NOTE_DELETE);
723 	VN_KNOTE(dvp, NOTE_WRITE);
724 out:
725 	return (error);
726 }
727 
728 /*
729  * link vnode call
730  */
731 int
732 ufs_link(ap)
733 	struct vop_link_args /* {
734 		struct vnode *a_tdvp;
735 		struct vnode *a_vp;
736 		struct componentname *a_cnp;
737 	} */ *ap;
738 {
739 	struct vnode *vp = ap->a_vp;
740 	struct vnode *tdvp = ap->a_tdvp;
741 	struct componentname *cnp = ap->a_cnp;
742 	struct proc *p = cnp->cn_proc;
743 	struct inode *ip;
744 	struct direct newdir;
745 	int error;
746 
747 #ifdef DIAGNOSTIC
748 	if ((cnp->cn_flags & HASBUF) == 0)
749 		panic("ufs_link: no name");
750 #endif
751 	if (tdvp->v_mount != vp->v_mount) {
752 		error = EXDEV;
753 		goto out2;
754 	}
755 	if (tdvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE, p))) {
756 		goto out2;
757 	}
758 	ip = VTOI(vp);
759 	if ((nlink_t)ip->i_nlink >= LINK_MAX) {
760 		error = EMLINK;
761 		goto out1;
762 	}
763 	if (ip->i_flags & (IMMUTABLE | APPEND)) {
764 		error = EPERM;
765 		goto out1;
766 	}
767 	ip->i_effnlink++;
768 	ip->i_nlink++;
769 	ip->i_flag |= IN_CHANGE;
770 	if (DOINGSOFTDEP(vp))
771 		softdep_change_linkcnt(ip);
772 	error = UFS_UPDATE(vp, !(DOINGSOFTDEP(vp) | DOINGASYNC(vp)));
773 	if (!error) {
774 		ufs_makedirentry(ip, cnp, &newdir);
775 		error = ufs_direnter(tdvp, vp, &newdir, cnp, NULL);
776 	}
777 
778 	if (error) {
779 		ip->i_effnlink--;
780 		ip->i_nlink--;
781 		ip->i_flag |= IN_CHANGE;
782 		if (DOINGSOFTDEP(vp))
783 			softdep_change_linkcnt(ip);
784 	}
785 out1:
786 	if (tdvp != vp)
787 		VOP_UNLOCK(vp, 0, p);
788 out2:
789 	VN_KNOTE(vp, NOTE_LINK);
790 	VN_KNOTE(tdvp, NOTE_WRITE);
791 	return (error);
792 }
793 
794 /*
795  * whiteout vnode call
796  */
797 int
798 ufs_whiteout(ap)
799 	struct vop_whiteout_args /* {
800 		struct vnode *a_dvp;
801 		struct componentname *a_cnp;
802 		int a_flags;
803 	} */ *ap;
804 {
805 	struct vnode *dvp = ap->a_dvp;
806 	struct componentname *cnp = ap->a_cnp;
807 	struct direct newdir;
808 	int error = 0;
809 
810 	switch (ap->a_flags) {
811 	case LOOKUP:
812 		/* 4.4 format directories support whiteout operations */
813 		if (dvp->v_mount->mnt_maxsymlinklen > 0)
814 			return (0);
815 		return (EOPNOTSUPP);
816 
817 	case CREATE:
818 		/* create a new directory whiteout */
819 #ifdef DIAGNOSTIC
820 		if ((cnp->cn_flags & SAVENAME) == 0)
821 			panic("ufs_whiteout: missing name");
822 		if (dvp->v_mount->mnt_maxsymlinklen <= 0)
823 			panic("ufs_whiteout: old format filesystem");
824 #endif
825 
826 		newdir.d_ino = WINO;
827 		newdir.d_namlen = cnp->cn_namelen;
828 		bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1);
829 		newdir.d_type = DT_WHT;
830 		error = ufs_direnter(dvp, NULL, &newdir, cnp, NULL);
831 		break;
832 
833 	case DELETE:
834 		/* remove an existing directory whiteout */
835 #ifdef DIAGNOSTIC
836 		if (dvp->v_mount->mnt_maxsymlinklen <= 0)
837 			panic("ufs_whiteout: old format filesystem");
838 #endif
839 
840 		cnp->cn_flags &= ~DOWHITEOUT;
841 		error = ufs_dirremove(dvp, NULL, cnp->cn_flags, 0);
842 		break;
843 	default:
844 		panic("ufs_whiteout: unknown op");
845 	}
846 	return (error);
847 }
848 
849 /*
850  * Rename system call.
851  * 	rename("foo", "bar");
852  * is essentially
853  *	unlink("bar");
854  *	link("foo", "bar");
855  *	unlink("foo");
856  * but ``atomically''.  Can't do full commit without saving state in the
857  * inode on disk which isn't feasible at this time.  Best we can do is
858  * always guarantee the target exists.
859  *
860  * Basic algorithm is:
861  *
862  * 1) Bump link count on source while we're linking it to the
863  *    target.  This also ensure the inode won't be deleted out
864  *    from underneath us while we work (it may be truncated by
865  *    a concurrent `trunc' or `open' for creation).
866  * 2) Link source to destination.  If destination already exists,
867  *    delete it first.
868  * 3) Unlink source reference to inode if still around. If a
869  *    directory was moved and the parent of the destination
870  *    is different from the source, patch the ".." entry in the
871  *    directory.
872  */
873 int
874 ufs_rename(ap)
875 	struct vop_rename_args  /* {
876 		struct vnode *a_fdvp;
877 		struct vnode *a_fvp;
878 		struct componentname *a_fcnp;
879 		struct vnode *a_tdvp;
880 		struct vnode *a_tvp;
881 		struct componentname *a_tcnp;
882 	} */ *ap;
883 {
884 	struct vnode *tvp = ap->a_tvp;
885 	register struct vnode *tdvp = ap->a_tdvp;
886 	struct vnode *fvp = ap->a_fvp;
887 	struct vnode *fdvp = ap->a_fdvp;
888 	struct componentname *tcnp = ap->a_tcnp;
889 	struct componentname *fcnp = ap->a_fcnp;
890 	struct proc *p = fcnp->cn_proc;
891 	struct inode *ip, *xp, *dp;
892 	struct direct newdir;
893 	int doingdirectory = 0, oldparent = 0, newparent = 0;
894 	int error = 0, ioflag;
895 
896 #ifdef DIAGNOSTIC
897 	if ((tcnp->cn_flags & HASBUF) == 0 ||
898 	    (fcnp->cn_flags & HASBUF) == 0)
899 		panic("ufs_rename: no name");
900 #endif
901 	/*
902 	 * Check for cross-device rename.
903 	 */
904 	if ((fvp->v_mount != tdvp->v_mount) ||
905 	    (tvp && (fvp->v_mount != tvp->v_mount))) {
906 		error = EXDEV;
907 abortit:
908 		if (tdvp == tvp)
909 			vrele(tdvp);
910 		else
911 			vput(tdvp);
912 		if (tvp)
913 			vput(tvp);
914 		vrele(fdvp);
915 		vrele(fvp);
916 		return (error);
917 	}
918 
919 	if (tvp && ((VTOI(tvp)->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
920 	    (VTOI(tdvp)->i_flags & APPEND))) {
921 		error = EPERM;
922 		goto abortit;
923 	}
924 
925 	/*
926 	 * Renaming a file to itself has no effect.  The upper layers should
927 	 * not call us in that case.  Temporarily just warn if they do.
928 	 */
929 	if (fvp == tvp) {
930 		printf("ufs_rename: fvp == tvp (can't happen)\n");
931 		error = 0;
932 		goto abortit;
933 	}
934 
935 	if ((error = vn_lock(fvp, LK_EXCLUSIVE, p)) != 0)
936 		goto abortit;
937 	dp = VTOI(fdvp);
938 	ip = VTOI(fvp);
939 	if (ip->i_nlink >= LINK_MAX) {
940 		VOP_UNLOCK(fvp, 0, p);
941 		error = EMLINK;
942 		goto abortit;
943 	}
944 	if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))
945 	    || (dp->i_flags & APPEND)) {
946 		VOP_UNLOCK(fvp, 0, p);
947 		error = EPERM;
948 		goto abortit;
949 	}
950 	if ((ip->i_mode & IFMT) == IFDIR) {
951 		/*
952 		 * Avoid ".", "..", and aliases of "." for obvious reasons.
953 		 */
954 		if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
955 		    dp == ip || (fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT ||
956 		    (ip->i_flag & IN_RENAME)) {
957 			VOP_UNLOCK(fvp, 0, p);
958 			error = EINVAL;
959 			goto abortit;
960 		}
961 		ip->i_flag |= IN_RENAME;
962 		oldparent = dp->i_number;
963 		doingdirectory = 1;
964 	}
965 	VN_KNOTE(fdvp, NOTE_WRITE);		/* XXX right place? */
966 	vrele(fdvp);
967 
968 	/*
969 	 * When the target exists, both the directory
970 	 * and target vnodes are returned locked.
971 	 */
972 	dp = VTOI(tdvp);
973 	xp = NULL;
974 	if (tvp)
975 		xp = VTOI(tvp);
976 
977 	/*
978 	 * 1) Bump link count while we're moving stuff
979 	 *    around.  If we crash somewhere before
980 	 *    completing our work, the link count
981 	 *    may be wrong, but correctable.
982 	 */
983 	ip->i_effnlink++;
984 	ip->i_nlink++;
985 	ip->i_flag |= IN_CHANGE;
986 	if (DOINGSOFTDEP(fvp))
987 		softdep_change_linkcnt(ip);
988 	if ((error = UFS_UPDATE(fvp, !(DOINGSOFTDEP(fvp) |
989 				       DOINGASYNC(fvp)))) != 0) {
990 		VOP_UNLOCK(fvp, 0, p);
991 		goto bad;
992 	}
993 
994 	/*
995 	 * If ".." must be changed (ie the directory gets a new
996 	 * parent) then the source directory must not be in the
997 	 * directory heirarchy above the target, as this would
998 	 * orphan everything below the source directory. Also
999 	 * the user must have write permission in the source so
1000 	 * as to be able to change "..". We must repeat the call
1001 	 * to namei, as the parent directory is unlocked by the
1002 	 * call to checkpath().
1003 	 */
1004 	error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_proc);
1005 	VOP_UNLOCK(fvp, 0, p);
1006 	if (oldparent != dp->i_number)
1007 		newparent = dp->i_number;
1008 	if (doingdirectory && newparent) {
1009 		if (error)	/* write access check above */
1010 			goto bad;
1011 		if (xp != NULL)
1012 			vput(tvp);
1013 		error = ufs_checkpath(ip, dp, tcnp->cn_cred);
1014 		if (error)
1015 			goto out;
1016 		if ((tcnp->cn_flags & SAVESTART) == 0)
1017 			panic("ufs_rename: lost to startdir");
1018 		VREF(tdvp);
1019 		error = relookup(tdvp, &tvp, tcnp);
1020 		if (error)
1021 			goto out;
1022 		vrele(tdvp);
1023 		dp = VTOI(tdvp);
1024 		xp = NULL;
1025 		if (tvp)
1026 			xp = VTOI(tvp);
1027 	}
1028 	/*
1029 	 * 2) If target doesn't exist, link the target
1030 	 *    to the source and unlink the source.
1031 	 *    Otherwise, rewrite the target directory
1032 	 *    entry to reference the source inode and
1033 	 *    expunge the original entry's existence.
1034 	 */
1035 	if (xp == NULL) {
1036 		if (dp->i_dev != ip->i_dev)
1037 			panic("ufs_rename: EXDEV");
1038 		/*
1039 		 * Account for ".." in new directory.
1040 		 * When source and destination have the same
1041 		 * parent we don't fool with the link count.
1042 		 */
1043 		if (doingdirectory && newparent) {
1044 			if ((nlink_t)dp->i_nlink >= LINK_MAX) {
1045 				error = EMLINK;
1046 				goto bad;
1047 			}
1048 			dp->i_effnlink++;
1049 			dp->i_nlink++;
1050 			dp->i_flag |= IN_CHANGE;
1051 			if (DOINGSOFTDEP(tdvp))
1052 				softdep_change_linkcnt(dp);
1053 			error = UFS_UPDATE(tdvp, !(DOINGSOFTDEP(tdvp) |
1054 						   DOINGASYNC(tdvp)));
1055 			if (error)
1056 				goto bad;
1057 		}
1058 		ufs_makedirentry(ip, tcnp, &newdir);
1059 		error = ufs_direnter(tdvp, NULL, &newdir, tcnp, NULL);
1060 		if (error) {
1061 			if (doingdirectory && newparent) {
1062 				dp->i_effnlink--;
1063 				dp->i_nlink--;
1064 				dp->i_flag |= IN_CHANGE;
1065 				if (DOINGSOFTDEP(tdvp))
1066 					softdep_change_linkcnt(dp);
1067 				(void)UFS_UPDATE(tdvp, 1);
1068 			}
1069 			goto bad;
1070 		}
1071 		VN_KNOTE(tdvp, NOTE_WRITE);
1072 		vput(tdvp);
1073 	} else {
1074 		if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev)
1075 			panic("ufs_rename: EXDEV");
1076 		/*
1077 		 * Short circuit rename(foo, foo).
1078 		 */
1079 		if (xp->i_number == ip->i_number)
1080 			panic("ufs_rename: same file");
1081 		/*
1082 		 * If the parent directory is "sticky", then the user must
1083 		 * own the parent directory, or the destination of the rename,
1084 		 * otherwise the destination may not be changed (except by
1085 		 * root). This implements append-only directories.
1086 		 */
1087 		if ((dp->i_mode & S_ISTXT) && tcnp->cn_cred->cr_uid != 0 &&
1088 		    tcnp->cn_cred->cr_uid != dp->i_uid &&
1089 		    xp->i_uid != tcnp->cn_cred->cr_uid) {
1090 			error = EPERM;
1091 			goto bad;
1092 		}
1093 		/*
1094 		 * Target must be empty if a directory and have no links
1095 		 * to it. Also, ensure source and target are compatible
1096 		 * (both directories, or both not directories).
1097 		 */
1098 		if ((xp->i_mode&IFMT) == IFDIR) {
1099 			if ((xp->i_effnlink > 2) ||
1100 			    !ufs_dirempty(xp, dp->i_number, tcnp->cn_cred)) {
1101 				error = ENOTEMPTY;
1102 				goto bad;
1103 			}
1104 			if (!doingdirectory) {
1105 				error = ENOTDIR;
1106 				goto bad;
1107 			}
1108 			cache_purge(tdvp);
1109 		} else if (doingdirectory) {
1110 			error = EISDIR;
1111 			goto bad;
1112 		}
1113 		error = ufs_dirrewrite(dp, xp, ip->i_number,
1114 		    IFTODT(ip->i_mode),
1115 		    (doingdirectory && newparent) ? newparent : doingdirectory);
1116 		if (error)
1117 			goto bad;
1118 		if (doingdirectory) {
1119 			if (!newparent) {
1120 				dp->i_effnlink--;
1121 				if (DOINGSOFTDEP(tdvp))
1122 					softdep_change_linkcnt(dp);
1123 			}
1124 			xp->i_effnlink--;
1125 			if (DOINGSOFTDEP(tvp))
1126 				softdep_change_linkcnt(xp);
1127 		}
1128 		if (doingdirectory && !DOINGSOFTDEP(tvp)) {
1129 			/*
1130 			 * Truncate inode. The only stuff left in the directory
1131 			 * is "." and "..". The "." reference is inconsequential
1132 			 * since we are quashing it. We have removed the "."
1133 			 * reference and the reference in the parent directory,
1134 			 * but there may be other hard links. The soft
1135 			 * dependency code will arrange to do these operations
1136 			 * after the parent directory entry has been deleted on
1137 			 * disk, so when running with that code we avoid doing
1138 			 * them now.
1139 			 */
1140 			if (!newparent) {
1141 				dp->i_nlink--;
1142 				dp->i_flag |= IN_CHANGE;
1143 			}
1144 			xp->i_nlink--;
1145 			xp->i_flag |= IN_CHANGE;
1146 			ioflag = DOINGASYNC(tvp) ? 0 : IO_SYNC;
1147 			if ((error = UFS_TRUNCATE(tvp, (off_t)0, ioflag,
1148 			    tcnp->cn_cred, tcnp->cn_proc)) != 0)
1149 				goto bad;
1150 		}
1151 		VN_KNOTE(tdvp, NOTE_WRITE);
1152 		vput(tdvp);
1153 		VN_KNOTE(tvp, NOTE_DELETE);
1154 		vput(tvp);
1155 		xp = NULL;
1156 	}
1157 
1158 	/*
1159 	 * 3) Unlink the source.
1160 	 */
1161 	fcnp->cn_flags &= ~MODMASK;
1162 	fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
1163 	if ((fcnp->cn_flags & SAVESTART) == 0)
1164 		panic("ufs_rename: lost from startdir");
1165 	VREF(fdvp);
1166 	error = relookup(fdvp, &fvp, fcnp);
1167 	if (error == 0)
1168 		vrele(fdvp);
1169 	if (fvp != NULL) {
1170 		xp = VTOI(fvp);
1171 		dp = VTOI(fdvp);
1172 	} else {
1173 		/*
1174 		 * From name has disappeared.
1175 		 */
1176 		if (doingdirectory)
1177 			panic("ufs_rename: lost dir entry");
1178 		vrele(ap->a_fvp);
1179 		return (0);
1180 	}
1181 	/*
1182 	 * Ensure that the directory entry still exists and has not
1183 	 * changed while the new name has been entered. If the source is
1184 	 * a file then the entry may have been unlinked or renamed. In
1185 	 * either case there is no further work to be done. If the source
1186 	 * is a directory then it cannot have been rmdir'ed; the IN_RENAME
1187 	 * flag ensures that it cannot be moved by another rename or removed
1188 	 * by a rmdir.
1189 	 */
1190 	if (xp != ip) {
1191 		if (doingdirectory)
1192 			panic("ufs_rename: lost dir entry");
1193 	} else {
1194 		/*
1195 		 * If the source is a directory with a
1196 		 * new parent, the link count of the old
1197 		 * parent directory must be decremented
1198 		 * and ".." set to point to the new parent.
1199 		 */
1200 		if (doingdirectory && newparent) {
1201 			xp->i_offset = mastertemplate.dot_reclen;
1202 			ufs_dirrewrite(xp, dp, newparent, DT_DIR, 0);
1203 			cache_purge(fdvp);
1204 		}
1205 		error = ufs_dirremove(fdvp, xp, fcnp->cn_flags, 0);
1206 		xp->i_flag &= ~IN_RENAME;
1207 	}
1208 	VN_KNOTE(fvp, NOTE_RENAME);
1209 	if (dp)
1210 		vput(fdvp);
1211 	if (xp)
1212 		vput(fvp);
1213 	vrele(ap->a_fvp);
1214 	return (error);
1215 
1216 bad:
1217 	if (xp)
1218 		vput(ITOV(xp));
1219 	vput(ITOV(dp));
1220 out:
1221 	if (doingdirectory)
1222 		ip->i_flag &= ~IN_RENAME;
1223 	if (vn_lock(fvp, LK_EXCLUSIVE, p) == 0) {
1224 		ip->i_effnlink--;
1225 		ip->i_nlink--;
1226 		ip->i_flag |= IN_CHANGE;
1227 		ip->i_flag &= ~IN_RENAME;
1228 		if (DOINGSOFTDEP(fvp))
1229 			softdep_change_linkcnt(ip);
1230 		vput(fvp);
1231 	} else
1232 		vrele(fvp);
1233 	return (error);
1234 }
1235 
1236 /*
1237  * Mkdir system call
1238  */
1239 int
1240 ufs_mkdir(ap)
1241 	struct vop_mkdir_args /* {
1242 		struct vnode *a_dvp;
1243 		struct vnode **a_vpp;
1244 		struct componentname *a_cnp;
1245 		struct vattr *a_vap;
1246 	} */ *ap;
1247 {
1248 	register struct vnode *dvp = ap->a_dvp;
1249 	register struct vattr *vap = ap->a_vap;
1250 	register struct componentname *cnp = ap->a_cnp;
1251 	register struct inode *ip, *dp;
1252 	struct vnode *tvp;
1253 	struct buf *bp;
1254 	struct dirtemplate dirtemplate, *dtp;
1255 	struct direct newdir;
1256 	int error, dmode;
1257 	long blkoff;
1258 
1259 #ifdef DIAGNOSTIC
1260 	if ((cnp->cn_flags & HASBUF) == 0)
1261 		panic("ufs_mkdir: no name");
1262 #endif
1263 	dp = VTOI(dvp);
1264 	if ((nlink_t)dp->i_nlink >= LINK_MAX) {
1265 		error = EMLINK;
1266 		goto out;
1267 	}
1268 	dmode = vap->va_mode & 0777;
1269 	dmode |= IFDIR;
1270 	/*
1271 	 * Must simulate part of ufs_makeinode here to acquire the inode,
1272 	 * but not have it entered in the parent directory. The entry is
1273 	 * made later after writing "." and ".." entries.
1274 	 */
1275 	error = UFS_VALLOC(dvp, dmode, cnp->cn_cred, &tvp);
1276 	if (error)
1277 		goto out;
1278 	ip = VTOI(tvp);
1279 	ip->i_gid = dp->i_gid;
1280 #ifdef SUIDDIR
1281 	{
1282 #ifdef QUOTA
1283 		struct ucred ucred, *ucp;
1284 		ucp = cnp->cn_cred;
1285 #endif
1286 		/*
1287 		 * If we are hacking owners here, (only do this where told to)
1288 		 * and we are not giving it TO root, (would subvert quotas)
1289 		 * then go ahead and give it to the other user.
1290 		 * The new directory also inherits the SUID bit.
1291 		 * If user's UID and dir UID are the same,
1292 		 * 'give it away' so that the SUID is still forced on.
1293 		 */
1294 		if ((dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
1295 		    (dp->i_mode & ISUID) && dp->i_uid) {
1296 			dmode |= ISUID;
1297 			ip->i_uid = dp->i_uid;
1298 #ifdef QUOTA
1299 			if (dp->i_uid != cnp->cn_cred->cr_uid) {
1300 				/*
1301 				 * Make sure the correct user gets charged
1302 				 * for the space.
1303 				 * Make a dummy credential for the victim.
1304 				 * XXX This seems to never be accessed out of
1305 				 * our context so a stack variable is ok.
1306 				 */
1307 				ucred.cr_ref = 1;
1308 				ucred.cr_uid = ip->i_uid;
1309 				ucred.cr_ngroups = 1;
1310 				ucred.cr_groups[0] = dp->i_gid;
1311 				ucp = &ucred;
1312 			}
1313 #endif
1314 		} else
1315 			ip->i_uid = cnp->cn_cred->cr_uid;
1316 #ifdef QUOTA
1317 		if ((error = getinoquota(ip)) ||
1318 	    	    (error = chkiq(ip, 1, ucp, 0))) {
1319 			UFS_VFREE(tvp, ip->i_number, dmode);
1320 			vput(tvp);
1321 			return (error);
1322 		}
1323 #endif
1324 	}
1325 #else	/* !SUIDDIR */
1326 	ip->i_uid = cnp->cn_cred->cr_uid;
1327 #ifdef QUOTA
1328 	if ((error = getinoquota(ip)) ||
1329 	    (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
1330 		UFS_VFREE(tvp, ip->i_number, dmode);
1331 		vput(tvp);
1332 		return (error);
1333 	}
1334 #endif
1335 #endif	/* !SUIDDIR */
1336 	ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
1337 	ip->i_mode = dmode;
1338 	tvp->v_type = VDIR;	/* Rest init'd in getnewvnode(). */
1339 	ip->i_effnlink = 2;
1340 	ip->i_nlink = 2;
1341 	if (DOINGSOFTDEP(tvp))
1342 		softdep_change_linkcnt(ip);
1343 	if (cnp->cn_flags & ISWHITEOUT)
1344 		ip->i_flags |= UF_OPAQUE;
1345 
1346 	/*
1347 	 * Bump link count in parent directory to reflect work done below.
1348 	 * Should be done before reference is created so cleanup is
1349 	 * possible if we crash.
1350 	 */
1351 	dp->i_effnlink++;
1352 	dp->i_nlink++;
1353 	dp->i_flag |= IN_CHANGE;
1354 	if (DOINGSOFTDEP(dvp))
1355 		softdep_change_linkcnt(dp);
1356 	error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(dvp) | DOINGASYNC(dvp)));
1357 	if (error)
1358 		goto bad;
1359 
1360 	/*
1361 	 * Initialize directory with "." and ".." from static template.
1362 	 */
1363 	if (dvp->v_mount->mnt_maxsymlinklen > 0
1364 	)
1365 		dtp = &mastertemplate;
1366 	else
1367 		dtp = (struct dirtemplate *)&omastertemplate;
1368 	dirtemplate = *dtp;
1369 	dirtemplate.dot_ino = ip->i_number;
1370 	dirtemplate.dotdot_ino = dp->i_number;
1371 	if ((error = VOP_BALLOC(tvp, (off_t)0, DIRBLKSIZ, cnp->cn_cred,
1372 	    B_CLRBUF, &bp)) != 0)
1373 		goto bad;
1374 	ip->i_size = DIRBLKSIZ;
1375 	ip->i_flag |= IN_CHANGE | IN_UPDATE;
1376 	vnode_pager_setsize(tvp, (u_long)ip->i_size);
1377 	bcopy((caddr_t)&dirtemplate, (caddr_t)bp->b_data, sizeof dirtemplate);
1378 	if (DOINGSOFTDEP(tvp)) {
1379 		/*
1380 		 * Ensure that the entire newly allocated block is a
1381 		 * valid directory so that future growth within the
1382 		 * block does not have to ensure that the block is
1383 		 * written before the inode.
1384 		 */
1385 		blkoff = DIRBLKSIZ;
1386 		while (blkoff < bp->b_bcount) {
1387 			((struct direct *)
1388 			   (bp->b_data + blkoff))->d_reclen = DIRBLKSIZ;
1389 			blkoff += DIRBLKSIZ;
1390 		}
1391 	}
1392 	if ((error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(tvp) |
1393 				       DOINGASYNC(tvp)))) != 0) {
1394 		(void)VOP_BWRITE(bp->b_vp, bp);
1395 		goto bad;
1396 	}
1397 	/*
1398 	 * Directory set up, now install its entry in the parent directory.
1399 	 *
1400 	 * If we are not doing soft dependencies, then we must write out the
1401 	 * buffer containing the new directory body before entering the new
1402 	 * name in the parent. If we are doing soft dependencies, then the
1403 	 * buffer containing the new directory body will be passed to and
1404 	 * released in the soft dependency code after the code has attached
1405 	 * an appropriate ordering dependency to the buffer which ensures that
1406 	 * the buffer is written before the new name is written in the parent.
1407 	 */
1408 	if (DOINGASYNC(dvp))
1409 		bdwrite(bp);
1410 	else if (!DOINGSOFTDEP(dvp) && ((error = VOP_BWRITE(bp->b_vp, bp))))
1411 		goto bad;
1412 	ufs_makedirentry(ip, cnp, &newdir);
1413 	error = ufs_direnter(dvp, tvp, &newdir, cnp, bp);
1414 
1415 bad:
1416 	if (error == 0) {
1417 		VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
1418 		*ap->a_vpp = tvp;
1419 	} else {
1420 		dp->i_effnlink--;
1421 		dp->i_nlink--;
1422 		dp->i_flag |= IN_CHANGE;
1423 		if (DOINGSOFTDEP(dvp))
1424 			softdep_change_linkcnt(dp);
1425 		/*
1426 		 * No need to do an explicit VOP_TRUNCATE here, vrele will
1427 		 * do this for us because we set the link count to 0.
1428 		 */
1429 		ip->i_effnlink = 0;
1430 		ip->i_nlink = 0;
1431 		ip->i_flag |= IN_CHANGE;
1432 		if (DOINGSOFTDEP(tvp))
1433 			softdep_change_linkcnt(ip);
1434 		vput(tvp);
1435 	}
1436 out:
1437 	return (error);
1438 }
1439 
1440 /*
1441  * Rmdir system call.
1442  */
1443 int
1444 ufs_rmdir(ap)
1445 	struct vop_rmdir_args /* {
1446 		struct vnode *a_dvp;
1447 		struct vnode *a_vp;
1448 		struct componentname *a_cnp;
1449 	} */ *ap;
1450 {
1451 	struct vnode *vp = ap->a_vp;
1452 	struct vnode *dvp = ap->a_dvp;
1453 	struct componentname *cnp = ap->a_cnp;
1454 	struct inode *ip, *dp;
1455 	int error, ioflag;
1456 
1457 	ip = VTOI(vp);
1458 	dp = VTOI(dvp);
1459 
1460 	/*
1461 	 * Do not remove a directory that is in the process of being renamed.
1462 	 * Verify the directory is empty (and valid). Rmdir ".." will not be
1463 	 * valid since ".." will contain a reference to the current directory
1464 	 * and thus be non-empty. Do not allow the removal of mounted on
1465 	 * directories (this can happen when an NFS exported filesystem
1466 	 * tries to remove a locally mounted on directory).
1467 	 */
1468 	error = 0;
1469 	if (ip->i_flag & IN_RENAME) {
1470 		error = EINVAL;
1471 		goto out;
1472 	}
1473 	if (ip->i_effnlink != 2 ||
1474 	    !ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) {
1475 		error = ENOTEMPTY;
1476 		goto out;
1477 	}
1478 	if ((dp->i_flags & APPEND)
1479 	    || (ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))) {
1480 		error = EPERM;
1481 		goto out;
1482 	}
1483 	if (vp->v_mountedhere != 0) {
1484 		error = EINVAL;
1485 		goto out;
1486 	}
1487 	/*
1488 	 * Delete reference to directory before purging
1489 	 * inode.  If we crash in between, the directory
1490 	 * will be reattached to lost+found,
1491 	 */
1492 	dp->i_effnlink--;
1493 	ip->i_effnlink--;
1494 	if (DOINGSOFTDEP(vp)) {
1495 		softdep_change_linkcnt(dp);
1496 		softdep_change_linkcnt(ip);
1497 	}
1498 	error = ufs_dirremove(dvp, ip, cnp->cn_flags, 1);
1499 	if (error) {
1500 		dp->i_effnlink++;
1501 		ip->i_effnlink++;
1502 		if (DOINGSOFTDEP(vp)) {
1503 			softdep_change_linkcnt(dp);
1504 			softdep_change_linkcnt(ip);
1505 		}
1506 		goto out;
1507 	}
1508 	VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
1509 	cache_purge(dvp);
1510 	/*
1511 	 * Truncate inode. The only stuff left in the directory is "." and
1512 	 * "..". The "." reference is inconsequential since we are quashing
1513 	 * it. The soft dependency code will arrange to do these operations
1514 	 * after the parent directory entry has been deleted on disk, so
1515 	 * when running with that code we avoid doing them now.
1516 	 */
1517 	if (!DOINGSOFTDEP(vp)) {
1518 		dp->i_nlink--;
1519 		dp->i_flag |= IN_CHANGE;
1520 		ip->i_nlink--;
1521 		ip->i_flag |= IN_CHANGE;
1522 		ioflag = DOINGASYNC(vp) ? 0 : IO_SYNC;
1523 		error = UFS_TRUNCATE(vp, (off_t)0, ioflag, cnp->cn_cred,
1524 		    cnp->cn_proc);
1525 	}
1526 	cache_purge(vp);
1527 #ifdef UFS_DIRHASH
1528 	/* Kill any active hash; i_effnlink == 0, so it will not come back. */
1529 	if (ip->i_dirhash != NULL)
1530 		ufsdirhash_free(ip);
1531 #endif
1532 out:
1533 	VN_KNOTE(vp, NOTE_DELETE);
1534 	return (error);
1535 }
1536 
1537 /*
1538  * symlink -- make a symbolic link
1539  */
1540 int
1541 ufs_symlink(ap)
1542 	struct vop_symlink_args /* {
1543 		struct vnode *a_dvp;
1544 		struct vnode **a_vpp;
1545 		struct componentname *a_cnp;
1546 		struct vattr *a_vap;
1547 		char *a_target;
1548 	} */ *ap;
1549 {
1550 	register struct vnode *vp, **vpp = ap->a_vpp;
1551 	register struct inode *ip;
1552 	int len, error;
1553 
1554 	error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
1555 	    vpp, ap->a_cnp);
1556 	if (error)
1557 		return (error);
1558 	VN_KNOTE(ap->a_dvp, NOTE_WRITE);
1559 	vp = *vpp;
1560 	len = strlen(ap->a_target);
1561 	if (len < vp->v_mount->mnt_maxsymlinklen) {
1562 		ip = VTOI(vp);
1563 		bcopy(ap->a_target, (char *)ip->i_shortlink, len);
1564 		ip->i_size = len;
1565 		ip->i_flag |= IN_CHANGE | IN_UPDATE;
1566 	} else
1567 		error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
1568 		    UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, (int *)0,
1569 		    (struct proc *)0);
1570 	if (error)
1571 		vput(vp);
1572 	return (error);
1573 }
1574 
1575 /*
1576  * Vnode op for reading directories.
1577  *
1578  * The routine below assumes that the on-disk format of a directory
1579  * is the same as that defined by <sys/dirent.h>. If the on-disk
1580  * format changes, then it will be necessary to do a conversion
1581  * from the on-disk format that read returns to the format defined
1582  * by <sys/dirent.h>.
1583  */
1584 int
1585 ufs_readdir(ap)
1586 	struct vop_readdir_args /* {
1587 		struct vnode *a_vp;
1588 		struct uio *a_uio;
1589 		struct ucred *a_cred;
1590 		int *a_eofflag;
1591 		int *ncookies;
1592 		u_long **a_cookies;
1593 	} */ *ap;
1594 {
1595 	register struct uio *uio = ap->a_uio;
1596 	int error;
1597 	size_t count, lost;
1598 	off_t off;
1599 
1600 	if (ap->a_ncookies != NULL)
1601 		/*
1602 		 * Ensure that the block is aligned.  The caller can use
1603 		 * the cookies to determine where in the block to start.
1604 		 */
1605 		uio->uio_offset &= ~(DIRBLKSIZ - 1);
1606 	off = uio->uio_offset;
1607 	count = uio->uio_resid;
1608 	/* Make sure we don't return partial entries. */
1609 	if (count <= ((uio->uio_offset + count) & (DIRBLKSIZ -1)))
1610 		return (EINVAL);
1611 	count -= (uio->uio_offset + count) & (DIRBLKSIZ -1);
1612 	lost = uio->uio_resid - count;
1613 	uio->uio_resid = count;
1614 	uio->uio_iov->iov_len = count;
1615 #	if (BYTE_ORDER == LITTLE_ENDIAN)
1616 		if (ap->a_vp->v_mount->mnt_maxsymlinklen > 0) {
1617 			error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
1618 		} else {
1619 			struct dirent *dp, *edp;
1620 			struct uio auio;
1621 			struct iovec aiov;
1622 			caddr_t dirbuf;
1623 			int readcnt;
1624 			u_char tmp;
1625 
1626 			auio = *uio;
1627 			auio.uio_iov = &aiov;
1628 			auio.uio_iovcnt = 1;
1629 			auio.uio_segflg = UIO_SYSSPACE;
1630 			aiov.iov_len = count;
1631 			MALLOC(dirbuf, caddr_t, count, M_TEMP, M_WAITOK);
1632 			aiov.iov_base = dirbuf;
1633 			error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred);
1634 			if (error == 0) {
1635 				readcnt = count - auio.uio_resid;
1636 				edp = (struct dirent *)&dirbuf[readcnt];
1637 				for (dp = (struct dirent *)dirbuf; dp < edp; ) {
1638 					tmp = dp->d_namlen;
1639 					dp->d_namlen = dp->d_type;
1640 					dp->d_type = tmp;
1641 					if (dp->d_reclen > 0) {
1642 						dp = (struct dirent *)
1643 						    ((char *)dp + dp->d_reclen);
1644 					} else {
1645 						error = EIO;
1646 						break;
1647 					}
1648 				}
1649 				if (dp >= edp)
1650 					error = uiomove(dirbuf, readcnt, uio);
1651 			}
1652 			FREE(dirbuf, M_TEMP);
1653 		}
1654 #	else
1655 		error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
1656 #	endif
1657 	if (!error && ap->a_ncookies != NULL) {
1658 		struct dirent* dpStart;
1659 		struct dirent* dpEnd;
1660 		struct dirent* dp;
1661 		int ncookies;
1662 		u_long *cookies;
1663 		u_long *cookiep;
1664 
1665 		if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
1666 			panic("ufs_readdir: unexpected uio from NFS server");
1667 		dpStart = (struct dirent *)
1668 		     (uio->uio_iov->iov_base - (uio->uio_offset - off));
1669 		dpEnd = (struct dirent *) uio->uio_iov->iov_base;
1670 		for (dp = dpStart, ncookies = 0;
1671 		     dp < dpEnd;
1672 		     dp = (struct dirent *)((caddr_t) dp + dp->d_reclen))
1673 			ncookies++;
1674 		MALLOC(cookies, u_long *, ncookies * sizeof(u_long), M_TEMP,
1675 		    M_WAITOK);
1676 		for (dp = dpStart, cookiep = cookies;
1677 		     dp < dpEnd;
1678 		     dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) {
1679 			off += dp->d_reclen;
1680 			*cookiep++ = (u_long) off;
1681 		}
1682 		*ap->a_ncookies = ncookies;
1683 		*ap->a_cookies = cookies;
1684 	}
1685 	uio->uio_resid += lost;
1686 	if (ap->a_eofflag)
1687 	    *ap->a_eofflag = VTOI(ap->a_vp)->i_size <= uio->uio_offset;
1688 	return (error);
1689 }
1690 
1691 /*
1692  * Return target name of a symbolic link
1693  */
1694 int
1695 ufs_readlink(ap)
1696 	struct vop_readlink_args /* {
1697 		struct vnode *a_vp;
1698 		struct uio *a_uio;
1699 		struct ucred *a_cred;
1700 	} */ *ap;
1701 {
1702 	register struct vnode *vp = ap->a_vp;
1703 	register struct inode *ip = VTOI(vp);
1704 	int isize;
1705 
1706 	isize = ip->i_size;
1707 	if ((isize < vp->v_mount->mnt_maxsymlinklen) ||
1708 	    (ip->i_din.di_blocks == 0)) {	/* XXX - for old fastlink support */
1709 		uiomove((char *)ip->i_shortlink, isize, ap->a_uio);
1710 		return (0);
1711 	}
1712 	return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred));
1713 }
1714 
1715 /*
1716  * Calculate the logical to physical mapping if not done already,
1717  * then call the device strategy routine.
1718  *
1719  * In order to be able to swap to a file, the VOP_BMAP operation may not
1720  * deadlock on memory.  See ufs_bmap() for details.
1721  */
1722 int
1723 ufs_strategy(ap)
1724 	struct vop_strategy_args /* {
1725 		struct vnode *a_vp;
1726 		struct buf *a_bp;
1727 	} */ *ap;
1728 {
1729 	register struct buf *bp = ap->a_bp;
1730 	register struct vnode *vp = ap->a_vp;
1731 	register struct inode *ip;
1732 	int error;
1733 
1734 	ip = VTOI(vp);
1735 	if (vp->v_type == VBLK || vp->v_type == VCHR)
1736 		panic("ufs_strategy: spec");
1737 	if (bp->b_blkno == bp->b_lblkno) {
1738 		error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL, NULL);
1739 		if (error) {
1740 			bp->b_error = error;
1741 			bp->b_flags |= B_ERROR;
1742 			biodone(bp);
1743 			return (error);
1744 		}
1745 		if ((long)bp->b_blkno == -1)
1746 			vfs_bio_clrbuf(bp);
1747 	}
1748 	if ((long)bp->b_blkno == -1) {
1749 		biodone(bp);
1750 		return (0);
1751 	}
1752 	vp = ip->i_devvp;
1753 	bp->b_dev = vp->v_rdev;
1754 	VOP_STRATEGY(vp, bp);
1755 	return (0);
1756 }
1757 
1758 /*
1759  * Print out the contents of an inode.
1760  */
1761 int
1762 ufs_print(ap)
1763 	struct vop_print_args /* {
1764 		struct vnode *a_vp;
1765 	} */ *ap;
1766 {
1767 	register struct vnode *vp = ap->a_vp;
1768 	register struct inode *ip = VTOI(vp);
1769 
1770 	printf("tag VT_UFS, ino %lu, on dev %s (%d, %d)",
1771 	    (u_long)ip->i_number, devtoname(ip->i_dev), major(ip->i_dev),
1772 	    minor(ip->i_dev));
1773 	if (vp->v_type == VFIFO)
1774 		fifo_printinfo(vp);
1775 	lockmgr_printinfo(&ip->i_lock);
1776 	printf("\n");
1777 	return (0);
1778 }
1779 
1780 /*
1781  * Read wrapper for special devices.
1782  */
1783 int
1784 ufsspec_read(ap)
1785 	struct vop_read_args /* {
1786 		struct vnode *a_vp;
1787 		struct uio *a_uio;
1788 		int  a_ioflag;
1789 		struct ucred *a_cred;
1790 	} */ *ap;
1791 {
1792 	int error, resid;
1793 	struct inode *ip;
1794 	struct uio *uio;
1795 
1796 	uio = ap->a_uio;
1797 	resid = uio->uio_resid;
1798 	error = VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap);
1799 	/*
1800 	 * The inode may have been revoked during the call, so it must not
1801 	 * be accessed blindly here or in the other wrapper functions.
1802 	 */
1803 	ip = VTOI(ap->a_vp);
1804 	if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
1805 		ip->i_flag |= IN_ACCESS;
1806 	return (error);
1807 }
1808 
1809 /*
1810  * Write wrapper for special devices.
1811  */
1812 int
1813 ufsspec_write(ap)
1814 	struct vop_write_args /* {
1815 		struct vnode *a_vp;
1816 		struct uio *a_uio;
1817 		int  a_ioflag;
1818 		struct ucred *a_cred;
1819 	} */ *ap;
1820 {
1821 	int error, resid;
1822 	struct inode *ip;
1823 	struct uio *uio;
1824 
1825 	uio = ap->a_uio;
1826 	resid = uio->uio_resid;
1827 	error = VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap);
1828 	ip = VTOI(ap->a_vp);
1829 	if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
1830 		VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
1831 	return (error);
1832 }
1833 
1834 /*
1835  * Close wrapper for special devices.
1836  *
1837  * Update the times on the inode then do device close.
1838  */
1839 int
1840 ufsspec_close(ap)
1841 	struct vop_close_args /* {
1842 		struct vnode *a_vp;
1843 		int  a_fflag;
1844 		struct ucred *a_cred;
1845 		struct proc *a_p;
1846 	} */ *ap;
1847 {
1848 	struct vnode *vp = ap->a_vp;
1849 
1850 	simple_lock(&vp->v_interlock);
1851 	if (vp->v_usecount > 1)
1852 		ufs_itimes(vp);
1853 	simple_unlock(&vp->v_interlock);
1854 	return (VOCALL(spec_vnodeop_p, VOFFSET(vop_close), ap));
1855 }
1856 
1857 /*
1858  * Read wrapper for fifos.
1859  */
1860 int
1861 ufsfifo_read(ap)
1862 	struct vop_read_args /* {
1863 		struct vnode *a_vp;
1864 		struct uio *a_uio;
1865 		int  a_ioflag;
1866 		struct ucred *a_cred;
1867 	} */ *ap;
1868 {
1869 	int error, resid;
1870 	struct inode *ip;
1871 	struct uio *uio;
1872 
1873 	uio = ap->a_uio;
1874 	resid = uio->uio_resid;
1875 	error = VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap);
1876 	ip = VTOI(ap->a_vp);
1877 	if ((ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) == 0 && ip != NULL &&
1878 	    (uio->uio_resid != resid || (error == 0 && resid != 0)))
1879 		VTOI(ap->a_vp)->i_flag |= IN_ACCESS;
1880 	return (error);
1881 }
1882 
1883 /*
1884  * Write wrapper for fifos.
1885  */
1886 int
1887 ufsfifo_write(ap)
1888 	struct vop_write_args /* {
1889 		struct vnode *a_vp;
1890 		struct uio *a_uio;
1891 		int  a_ioflag;
1892 		struct ucred *a_cred;
1893 	} */ *ap;
1894 {
1895 	int error, resid;
1896 	struct inode *ip;
1897 	struct uio *uio;
1898 
1899 	uio = ap->a_uio;
1900 	resid = uio->uio_resid;
1901 	error = VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap);
1902 	ip = VTOI(ap->a_vp);
1903 	if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
1904 		VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
1905 	return (error);
1906 }
1907 
1908 /*
1909  * Close wrapper for fifos.
1910  *
1911  * Update the times on the inode then do device close.
1912  */
1913 int
1914 ufsfifo_close(ap)
1915 	struct vop_close_args /* {
1916 		struct vnode *a_vp;
1917 		int  a_fflag;
1918 		struct ucred *a_cred;
1919 		struct proc *a_p;
1920 	} */ *ap;
1921 {
1922 	struct vnode *vp = ap->a_vp;
1923 
1924 	simple_lock(&vp->v_interlock);
1925 	if (vp->v_usecount > 1)
1926 		ufs_itimes(vp);
1927 	simple_unlock(&vp->v_interlock);
1928 	return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap));
1929 }
1930 
1931 /*
1932  * Kqfilter wrapper for fifos.
1933  *
1934  * Fall through to ufs kqfilter routines if needed
1935  */
1936 int
1937 ufsfifo_kqfilter(ap)
1938 	struct vop_kqfilter_args *ap;
1939 {
1940 	int error;
1941 
1942 	error = VOCALL(fifo_vnodeop_p, VOFFSET(vop_kqfilter), ap);
1943 	if (error)
1944 		error = ufs_kqfilter(ap);
1945 	return (error);
1946 }
1947 
1948 /*
1949  * Return POSIX pathconf information applicable to ufs filesystems.
1950  */
1951 int
1952 ufs_pathconf(ap)
1953 	struct vop_pathconf_args /* {
1954 		struct vnode *a_vp;
1955 		int a_name;
1956 		int *a_retval;
1957 	} */ *ap;
1958 {
1959 
1960 	switch (ap->a_name) {
1961 	case _PC_LINK_MAX:
1962 		*ap->a_retval = LINK_MAX;
1963 		return (0);
1964 	case _PC_NAME_MAX:
1965 		*ap->a_retval = NAME_MAX;
1966 		return (0);
1967 	case _PC_PATH_MAX:
1968 		*ap->a_retval = PATH_MAX;
1969 		return (0);
1970 	case _PC_PIPE_BUF:
1971 		*ap->a_retval = PIPE_BUF;
1972 		return (0);
1973 	case _PC_CHOWN_RESTRICTED:
1974 		*ap->a_retval = 1;
1975 		return (0);
1976 	case _PC_NO_TRUNC:
1977 		*ap->a_retval = 1;
1978 		return (0);
1979 	default:
1980 		return (EINVAL);
1981 	}
1982 	/* NOTREACHED */
1983 }
1984 
1985 /*
1986  * Advisory record locking support
1987  */
1988 int
1989 ufs_advlock(ap)
1990 	struct vop_advlock_args /* {
1991 		struct vnode *a_vp;
1992 		caddr_t  a_id;
1993 		int  a_op;
1994 		struct flock *a_fl;
1995 		int  a_flags;
1996 	} */ *ap;
1997 {
1998 	register struct inode *ip = VTOI(ap->a_vp);
1999 
2000 	return (lf_advlock(ap, &(ip->i_lockf), ip->i_size));
2001 }
2002 
2003 /*
2004  * Initialize the vnode associated with a new inode, handle aliased
2005  * vnodes.
2006  */
2007 int
2008 ufs_vinit(mntp, specops, fifoops, vpp)
2009 	struct mount *mntp;
2010 	vop_t **specops;
2011 	vop_t **fifoops;
2012 	struct vnode **vpp;
2013 {
2014 	struct inode *ip;
2015 	struct vnode *vp;
2016 	struct timeval tv;
2017 
2018 	vp = *vpp;
2019 	ip = VTOI(vp);
2020 	switch(vp->v_type = IFTOVT(ip->i_mode)) {
2021 	case VCHR:
2022 	case VBLK:
2023 		vp->v_op = specops;
2024 		addaliasu(vp, ip->i_rdev);
2025 		break;
2026 	case VFIFO:
2027 		vp->v_op = fifoops;
2028 		break;
2029 	default:
2030 		break;
2031 
2032 	}
2033 	if (ip->i_number == ROOTINO)
2034 		vp->v_flag |= VROOT;
2035 	/*
2036 	 * Initialize modrev times
2037 	 */
2038 	getmicrouptime(&tv);
2039 	SETHIGH(ip->i_modrev, tv.tv_sec);
2040 	SETLOW(ip->i_modrev, tv.tv_usec * 4294);
2041 	*vpp = vp;
2042 	return (0);
2043 }
2044 
2045 /*
2046  * Allocate a new inode.
2047  */
2048 int
2049 ufs_makeinode(mode, dvp, vpp, cnp)
2050 	int mode;
2051 	struct vnode *dvp;
2052 	struct vnode **vpp;
2053 	struct componentname *cnp;
2054 {
2055 	register struct inode *ip, *pdir;
2056 	struct direct newdir;
2057 	struct vnode *tvp;
2058 	int error;
2059 
2060 	pdir = VTOI(dvp);
2061 #ifdef DIAGNOSTIC
2062 	if ((cnp->cn_flags & HASBUF) == 0)
2063 		panic("ufs_makeinode: no name");
2064 #endif
2065 	*vpp = NULL;
2066 	if ((mode & IFMT) == 0)
2067 		mode |= IFREG;
2068 
2069 	error = UFS_VALLOC(dvp, mode, cnp->cn_cred, &tvp);
2070 	if (error)
2071 		return (error);
2072 	ip = VTOI(tvp);
2073 	ip->i_gid = pdir->i_gid;
2074 #ifdef SUIDDIR
2075 	{
2076 #ifdef QUOTA
2077 		struct ucred ucred, *ucp;
2078 		ucp = cnp->cn_cred;
2079 #endif
2080 		/*
2081 		 * If we are not the owner of the directory,
2082 		 * and we are hacking owners here, (only do this where told to)
2083 		 * and we are not giving it TO root, (would subvert quotas)
2084 		 * then go ahead and give it to the other user.
2085 		 * Note that this drops off the execute bits for security.
2086 		 */
2087 		if ((dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
2088 		    (pdir->i_mode & ISUID) &&
2089 		    (pdir->i_uid != cnp->cn_cred->cr_uid) && pdir->i_uid) {
2090 			ip->i_uid = pdir->i_uid;
2091 			mode &= ~07111;
2092 #ifdef QUOTA
2093 			/*
2094 			 * Make sure the correct user gets charged
2095 			 * for the space.
2096 			 * Quickly knock up a dummy credential for the victim.
2097 			 * XXX This seems to never be accessed out of our
2098 			 * context so a stack variable is ok.
2099 			 */
2100 			ucred.cr_ref = 1;
2101 			ucred.cr_uid = ip->i_uid;
2102 			ucred.cr_ngroups = 1;
2103 			ucred.cr_groups[0] = pdir->i_gid;
2104 			ucp = &ucred;
2105 #endif
2106 		} else
2107 			ip->i_uid = cnp->cn_cred->cr_uid;
2108 
2109 #ifdef QUOTA
2110 		if ((error = getinoquota(ip)) ||
2111 	    	    (error = chkiq(ip, 1, ucp, 0))) {
2112 			UFS_VFREE(tvp, ip->i_number, mode);
2113 			vput(tvp);
2114 			return (error);
2115 		}
2116 #endif
2117 	}
2118 #else	/* !SUIDDIR */
2119 	ip->i_uid = cnp->cn_cred->cr_uid;
2120 #ifdef QUOTA
2121 	if ((error = getinoquota(ip)) ||
2122 	    (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
2123 		UFS_VFREE(tvp, ip->i_number, mode);
2124 		vput(tvp);
2125 		return (error);
2126 	}
2127 #endif
2128 #endif	/* !SUIDDIR */
2129 	ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
2130 	ip->i_mode = mode;
2131 	tvp->v_type = IFTOVT(mode);	/* Rest init'd in getnewvnode(). */
2132 	ip->i_effnlink = 1;
2133 	ip->i_nlink = 1;
2134 	if (DOINGSOFTDEP(tvp))
2135 		softdep_change_linkcnt(ip);
2136 	if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
2137 	    suser_xxx(cnp->cn_cred, 0, 0))
2138 		ip->i_mode &= ~ISGID;
2139 
2140 	if (cnp->cn_flags & ISWHITEOUT)
2141 		ip->i_flags |= UF_OPAQUE;
2142 
2143 	/*
2144 	 * Make sure inode goes to disk before directory entry.
2145 	 */
2146 	error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(tvp) | DOINGASYNC(tvp)));
2147 	if (error)
2148 		goto bad;
2149 	ufs_makedirentry(ip, cnp, &newdir);
2150 	error = ufs_direnter(dvp, tvp, &newdir, cnp, NULL);
2151 	if (error)
2152 		goto bad;
2153 	*vpp = tvp;
2154 	return (0);
2155 
2156 bad:
2157 	/*
2158 	 * Write error occurred trying to update the inode
2159 	 * or the directory so must deallocate the inode.
2160 	 */
2161 	ip->i_effnlink = 0;
2162 	ip->i_nlink = 0;
2163 	ip->i_flag |= IN_CHANGE;
2164 	if (DOINGSOFTDEP(tvp))
2165 		softdep_change_linkcnt(ip);
2166 	vput(tvp);
2167 	return (error);
2168 }
2169 
2170 static int
2171 ufs_missingop(ap)
2172 	struct vop_generic_args *ap;
2173 {
2174 
2175 	panic("no vop function for %s in ufs child", ap->a_desc->vdesc_name);
2176 	return (EOPNOTSUPP);
2177 }
2178 
2179 static struct filterops ufsread_filtops =
2180 	{ 1, NULL, filt_ufsdetach, filt_ufsread };
2181 static struct filterops ufswrite_filtops =
2182 	{ 1, NULL, filt_ufsdetach, filt_ufswrite };
2183 static struct filterops ufsvnode_filtops =
2184 	{ 1, NULL, filt_ufsdetach, filt_ufsvnode };
2185 
2186 static int
2187 ufs_kqfilter(ap)
2188 	struct vop_kqfilter_args /* {
2189 		struct vnode *a_vp;
2190 		struct knote *a_kn;
2191 	} */ *ap;
2192 {
2193 	struct vnode *vp = ap->a_vp;
2194 	struct knote *kn = ap->a_kn;
2195 
2196 	switch (kn->kn_filter) {
2197 	case EVFILT_READ:
2198 		kn->kn_fop = &ufsread_filtops;
2199 		break;
2200 	case EVFILT_WRITE:
2201 		kn->kn_fop = &ufswrite_filtops;
2202 		break;
2203 	case EVFILT_VNODE:
2204 		kn->kn_fop = &ufsvnode_filtops;
2205 		break;
2206 	default:
2207 		return (1);
2208 	}
2209 
2210 	kn->kn_hook = (caddr_t)vp;
2211 
2212 	simple_lock(&vp->v_pollinfo.vpi_lock);
2213 	SLIST_INSERT_HEAD(&vp->v_pollinfo.vpi_selinfo.si_note, kn, kn_selnext);
2214 	simple_unlock(&vp->v_pollinfo.vpi_lock);
2215 
2216 	return (0);
2217 }
2218 
2219 static void
2220 filt_ufsdetach(struct knote *kn)
2221 {
2222 	struct vnode *vp = (struct vnode *)kn->kn_hook;
2223 
2224 	simple_lock(&vp->v_pollinfo.vpi_lock);
2225 	SLIST_REMOVE(&vp->v_pollinfo.vpi_selinfo.si_note,
2226 	    kn, knote, kn_selnext);
2227 	simple_unlock(&vp->v_pollinfo.vpi_lock);
2228 }
2229 
2230 /*ARGSUSED*/
2231 static int
2232 filt_ufsread(struct knote *kn, long hint)
2233 {
2234 	struct vnode *vp = (struct vnode *)kn->kn_hook;
2235 	struct inode *ip = VTOI(vp);
2236 
2237 	/*
2238 	 * filesystem is gone, so set the EOF flag and schedule
2239 	 * the knote for deletion.
2240 	 */
2241 	if (hint == NOTE_REVOKE) {
2242 		kn->kn_flags |= (EV_EOF | EV_ONESHOT);
2243 		return (1);
2244 	}
2245 
2246         kn->kn_data = ip->i_size - kn->kn_fp->f_offset;
2247         return (kn->kn_data != 0);
2248 }
2249 
2250 /*ARGSUSED*/
2251 static int
2252 filt_ufswrite(struct knote *kn, long hint)
2253 {
2254 
2255 	/*
2256 	 * filesystem is gone, so set the EOF flag and schedule
2257 	 * the knote for deletion.
2258 	 */
2259 	if (hint == NOTE_REVOKE)
2260 		kn->kn_flags |= (EV_EOF | EV_ONESHOT);
2261 
2262         kn->kn_data = 0;
2263         return (1);
2264 }
2265 
2266 static int
2267 filt_ufsvnode(struct knote *kn, long hint)
2268 {
2269 
2270 	if (kn->kn_sfflags & hint)
2271 		kn->kn_fflags |= hint;
2272 	if (hint == NOTE_REVOKE) {
2273 		kn->kn_flags |= EV_EOF;
2274 		return (1);
2275 	}
2276 	return (kn->kn_fflags != 0);
2277 }
2278 
2279 /* Global vfs data structures for ufs. */
2280 static vop_t **ufs_vnodeop_p;
2281 static struct vnodeopv_entry_desc ufs_vnodeop_entries[] = {
2282 	{ &vop_default_desc,		(vop_t *) vop_defaultop },
2283 	{ &vop_fsync_desc,		(vop_t *) ufs_missingop },
2284 	{ &vop_read_desc,		(vop_t *) ufs_missingop },
2285 	{ &vop_reallocblks_desc,	(vop_t *) ufs_missingop },
2286 	{ &vop_write_desc,		(vop_t *) ufs_missingop },
2287 	{ &vop_access_desc,		(vop_t *) ufs_access },
2288 	{ &vop_advlock_desc,		(vop_t *) ufs_advlock },
2289 	{ &vop_bmap_desc,		(vop_t *) ufs_bmap },
2290 	{ &vop_cachedlookup_desc,	(vop_t *) ufs_lookup },
2291 	{ &vop_close_desc,		(vop_t *) ufs_close },
2292 	{ &vop_create_desc,		(vop_t *) ufs_create },
2293 	{ &vop_getattr_desc,		(vop_t *) ufs_getattr },
2294 	{ &vop_inactive_desc,		(vop_t *) ufs_inactive },
2295 	{ &vop_islocked_desc,		(vop_t *) vop_stdislocked },
2296 	{ &vop_link_desc,		(vop_t *) ufs_link },
2297 	{ &vop_lock_desc,		(vop_t *) vop_stdlock },
2298 	{ &vop_lookup_desc,		(vop_t *) vfs_cache_lookup },
2299 	{ &vop_mkdir_desc,		(vop_t *) ufs_mkdir },
2300 	{ &vop_mknod_desc,		(vop_t *) ufs_mknod },
2301 	{ &vop_mmap_desc,		(vop_t *) ufs_mmap },
2302 	{ &vop_open_desc,		(vop_t *) ufs_open },
2303 	{ &vop_pathconf_desc,		(vop_t *) ufs_pathconf },
2304 	{ &vop_poll_desc,		(vop_t *) vop_stdpoll },
2305 	{ &vop_kqfilter_desc,		(vop_t *) ufs_kqfilter },
2306 	{ &vop_print_desc,		(vop_t *) ufs_print },
2307 	{ &vop_readdir_desc,		(vop_t *) ufs_readdir },
2308 	{ &vop_readlink_desc,		(vop_t *) ufs_readlink },
2309 	{ &vop_reclaim_desc,		(vop_t *) ufs_reclaim },
2310 	{ &vop_remove_desc,		(vop_t *) ufs_remove },
2311 	{ &vop_rename_desc,		(vop_t *) ufs_rename },
2312 	{ &vop_rmdir_desc,		(vop_t *) ufs_rmdir },
2313 	{ &vop_setattr_desc,		(vop_t *) ufs_setattr },
2314 	{ &vop_strategy_desc,		(vop_t *) ufs_strategy },
2315 	{ &vop_symlink_desc,		(vop_t *) ufs_symlink },
2316 	{ &vop_unlock_desc,		(vop_t *) vop_stdunlock },
2317 	{ &vop_whiteout_desc,		(vop_t *) ufs_whiteout },
2318 	{ NULL, NULL }
2319 };
2320 static struct vnodeopv_desc ufs_vnodeop_opv_desc =
2321 	{ &ufs_vnodeop_p, ufs_vnodeop_entries };
2322 
2323 static vop_t **ufs_specop_p;
2324 static struct vnodeopv_entry_desc ufs_specop_entries[] = {
2325 	{ &vop_default_desc,		(vop_t *) spec_vnoperate },
2326 	{ &vop_fsync_desc,		(vop_t *) ufs_missingop },
2327 	{ &vop_access_desc,		(vop_t *) ufs_access },
2328 	{ &vop_close_desc,		(vop_t *) ufsspec_close },
2329 	{ &vop_getattr_desc,		(vop_t *) ufs_getattr },
2330 	{ &vop_inactive_desc,		(vop_t *) ufs_inactive },
2331 	{ &vop_islocked_desc,		(vop_t *) vop_stdislocked },
2332 	{ &vop_lock_desc,		(vop_t *) vop_stdlock },
2333 	{ &vop_print_desc,		(vop_t *) ufs_print },
2334 	{ &vop_read_desc,		(vop_t *) ufsspec_read },
2335 	{ &vop_reclaim_desc,		(vop_t *) ufs_reclaim },
2336 	{ &vop_setattr_desc,		(vop_t *) ufs_setattr },
2337 	{ &vop_unlock_desc,		(vop_t *) vop_stdunlock },
2338 	{ &vop_write_desc,		(vop_t *) ufsspec_write },
2339 	{ NULL, NULL }
2340 };
2341 static struct vnodeopv_desc ufs_specop_opv_desc =
2342 	{ &ufs_specop_p, ufs_specop_entries };
2343 
2344 static vop_t **ufs_fifoop_p;
2345 static struct vnodeopv_entry_desc ufs_fifoop_entries[] = {
2346 	{ &vop_default_desc,		(vop_t *) fifo_vnoperate },
2347 	{ &vop_fsync_desc,		(vop_t *) ufs_missingop },
2348 	{ &vop_access_desc,		(vop_t *) ufs_access },
2349 	{ &vop_close_desc,		(vop_t *) ufsfifo_close },
2350 	{ &vop_getattr_desc,		(vop_t *) ufs_getattr },
2351 	{ &vop_inactive_desc,		(vop_t *) ufs_inactive },
2352 	{ &vop_islocked_desc,		(vop_t *) vop_stdislocked },
2353 	{ &vop_kqfilter_desc,		(vop_t *) ufsfifo_kqfilter },
2354 	{ &vop_lock_desc,		(vop_t *) vop_stdlock },
2355 	{ &vop_print_desc,		(vop_t *) ufs_print },
2356 	{ &vop_read_desc,		(vop_t *) ufsfifo_read },
2357 	{ &vop_reclaim_desc,		(vop_t *) ufs_reclaim },
2358 	{ &vop_setattr_desc,		(vop_t *) ufs_setattr },
2359 	{ &vop_unlock_desc,		(vop_t *) vop_stdunlock },
2360 	{ &vop_write_desc,		(vop_t *) ufsfifo_write },
2361 	{ NULL, NULL }
2362 };
2363 static struct vnodeopv_desc ufs_fifoop_opv_desc =
2364 	{ &ufs_fifoop_p, ufs_fifoop_entries };
2365 
2366 VNODEOP_SET(ufs_vnodeop_opv_desc);
2367 VNODEOP_SET(ufs_specop_opv_desc);
2368 VNODEOP_SET(ufs_fifoop_opv_desc);
2369 
2370 int
2371 ufs_vnoperate(ap)
2372 	struct vop_generic_args /* {
2373 		struct vnodeop_desc *a_desc;
2374 	} */ *ap;
2375 {
2376 	return (VOCALL(ufs_vnodeop_p, ap->a_desc->vdesc_offset, ap));
2377 }
2378 
2379 int
2380 ufs_vnoperatefifo(ap)
2381 	struct vop_generic_args /* {
2382 		struct vnodeop_desc *a_desc;
2383 	} */ *ap;
2384 {
2385 	return (VOCALL(ufs_fifoop_p, ap->a_desc->vdesc_offset, ap));
2386 }
2387 
2388 int
2389 ufs_vnoperatespec(ap)
2390 	struct vop_generic_args /* {
2391 		struct vnodeop_desc *a_desc;
2392 	} */ *ap;
2393 {
2394 	return (VOCALL(ufs_specop_p, ap->a_desc->vdesc_offset, ap));
2395 }
2396