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