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