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