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.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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
38 * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
42 #include "opt_quota.h"
43 #include "opt_suiddir.h"
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>
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>
62 #include <vm/vm_zone.h>
64 #include <vm/vm_extern.h>
66 #include <miscfs/fifofs/fifo.h>
68 #include <ufs/ufs/quota.h>
69 #include <ufs/ufs/inode.h>
70 #include <ufs/ufs/dir.h>
71 #include <ufs/ufs/ufsmount.h>
72 #include <ufs/ufs/ufs_extern.h>
74 static int ufs_abortop __P((struct vop_abortop_args *));
75 static int ufs_access __P((struct vop_access_args *));
76 static int ufs_advlock __P((struct vop_advlock_args *));
77 static int ufs_chmod __P((struct vnode *, int, struct ucred *, struct proc *));
78 static int ufs_chown __P((struct vnode *, uid_t, gid_t, struct ucred *, struct proc *));
79 static int ufs_close __P((struct vop_close_args *));
80 static int ufs_create __P((struct vop_create_args *));
81 static int ufs_getattr __P((struct vop_getattr_args *));
82 static int ufs_link __P((struct vop_link_args *));
83 static int ufs_makeinode __P((int mode, struct vnode *, struct vnode **, struct componentname *));
84 static int ufs_missingop __P((struct vop_generic_args *ap));
85 static int ufs_mkdir __P((struct vop_mkdir_args *));
86 static int ufs_mknod __P((struct vop_mknod_args *));
87 static int ufs_mmap __P((struct vop_mmap_args *));
88 static int ufs_open __P((struct vop_open_args *));
89 static int ufs_pathconf __P((struct vop_pathconf_args *));
90 static int ufs_print __P((struct vop_print_args *));
91 static int ufs_readdir __P((struct vop_readdir_args *));
92 static int ufs_readlink __P((struct vop_readlink_args *));
93 static int ufs_remove __P((struct vop_remove_args *));
94 static int ufs_rename __P((struct vop_rename_args *));
95 static int ufs_rmdir __P((struct vop_rmdir_args *));
96 static int ufs_setattr __P((struct vop_setattr_args *));
97 static int ufs_strategy __P((struct vop_strategy_args *));
98 static int ufs_symlink __P((struct vop_symlink_args *));
99 static int ufs_whiteout __P((struct vop_whiteout_args *));
100 static int ufsfifo_close __P((struct vop_close_args *));
101 static int ufsfifo_read __P((struct vop_read_args *));
102 static int ufsfifo_write __P((struct vop_write_args *));
103 static int ufsspec_close __P((struct vop_close_args *));
104 static int ufsspec_read __P((struct vop_read_args *));
105 static int ufsspec_write __P((struct vop_write_args *));
111 #define SETHIGH(q, h) { \
114 tmp.val[_QUAD_HIGHWORD] = (h); \
117 #define SETLOW(q, l) { \
120 tmp.val[_QUAD_LOWWORD] = (l); \
125 * A virgin directory (no blushing please).
127 static struct dirtemplate mastertemplate = {
128 0, 12, DT_DIR, 1, ".",
129 0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
131 static struct odirtemplate omastertemplate = {
133 0, DIRBLKSIZ - 12, 2, ".."
144 if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0)
146 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
148 if ((vp->v_type == VBLK || vp->v_type == VCHR) &&
150 ip->i_flag |= IN_LAZYMOD;
152 ip->i_flag |= IN_MODIFIED;
153 if (ip->i_flag & IN_ACCESS) {
154 ip->i_atime = ts.tv_sec;
155 ip->i_atimensec = ts.tv_nsec;
157 if (ip->i_flag & IN_UPDATE) {
158 ip->i_mtime = ts.tv_sec;
159 ip->i_mtimensec = ts.tv_nsec;
162 if (ip->i_flag & IN_CHANGE) {
163 ip->i_ctime = ts.tv_sec;
164 ip->i_ctimensec = ts.tv_nsec;
167 ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE);
171 * Create a regular file
175 struct vop_create_args /* {
177 struct vnode **a_vpp;
178 struct componentname *a_cnp;
185 ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode),
186 ap->a_dvp, ap->a_vpp, ap->a_cnp);
189 VN_POLLEVENT(ap->a_dvp, POLLWRITE);
199 struct vop_mknod_args /* {
201 struct vnode **a_vpp;
202 struct componentname *a_cnp;
206 struct vattr *vap = ap->a_vap;
207 struct vnode **vpp = ap->a_vpp;
211 error = ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
212 ap->a_dvp, vpp, ap->a_cnp);
215 VN_POLLEVENT(ap->a_dvp, POLLWRITE);
217 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
218 if (vap->va_rdev != VNOVAL) {
220 * Want to be able to use this to make badblock
221 * inodes, so don't truncate the dev number.
223 ip->i_rdev = vap->va_rdev;
226 * Remove inode, then reload it through VFS_VGET so it is
227 * checked to see if it is an alias of an existing entry in
231 (*vpp)->v_type = VNON;
233 error = VFS_VGET(ap->a_dvp->v_mount, ip->i_ino, vpp);
249 struct vop_open_args /* {
252 struct ucred *a_cred;
258 * Files marked append-only must be opened for appending.
260 if ((VTOI(ap->a_vp)->i_flags & APPEND) &&
261 (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE)
269 * Update the times on the inode.
274 struct vop_close_args /* {
277 struct ucred *a_cred;
281 register struct vnode *vp = ap->a_vp;
283 simple_lock(&vp->v_interlock);
284 if (vp->v_usecount > 1)
286 simple_unlock(&vp->v_interlock);
292 struct vop_access_args /* {
295 struct ucred *a_cred;
299 struct vnode *vp = ap->a_vp;
300 struct inode *ip = VTOI(vp);
301 struct ucred *cred = ap->a_cred;
302 mode_t mask, mode = ap->a_mode;
310 * Disallow write attempts on read-only file systems;
311 * unless the file is a socket, fifo, or a block or
312 * character device resident on the file system.
315 switch (vp->v_type) {
319 if (vp->v_mount->mnt_flag & MNT_RDONLY)
322 if ((error = getinoquota(ip)) != 0)
331 /* If immutable bit set, nobody gets to write it. */
332 if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE))
335 /* Otherwise, user id 0 always gets access. */
336 if (cred->cr_uid == 0)
341 /* Otherwise, check the owner. */
342 if (cred->cr_uid == ip->i_uid) {
349 return ((ip->i_mode & mask) == mask ? 0 : EACCES);
352 /* Otherwise, check the groups. */
353 for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
354 if (ip->i_gid == *gp) {
361 return ((ip->i_mode & mask) == mask ? 0 : EACCES);
364 /* Otherwise, check everyone else. */
371 return ((ip->i_mode & mask) == mask ? 0 : EACCES);
377 struct vop_getattr_args /* {
380 struct ucred *a_cred;
384 register struct vnode *vp = ap->a_vp;
385 register struct inode *ip = VTOI(vp);
386 register struct vattr *vap = ap->a_vap;
390 * Copy from inode table
392 vap->va_fsid = dev2udev(ip->i_dev);
393 vap->va_fileid = ip->i_number;
394 vap->va_mode = ip->i_mode & ~IFMT;
395 vap->va_nlink = VFSTOUFS(vp->v_mount)->um_i_effnlink_valid ?
396 ip->i_effnlink : ip->i_nlink;
397 vap->va_uid = ip->i_uid;
398 vap->va_gid = ip->i_gid;
399 vap->va_rdev = ip->i_rdev;
400 vap->va_size = ip->i_din.di_size;
401 vap->va_atime.tv_sec = ip->i_atime;
402 vap->va_atime.tv_nsec = ip->i_atimensec;
403 vap->va_mtime.tv_sec = ip->i_mtime;
404 vap->va_mtime.tv_nsec = ip->i_mtimensec;
405 vap->va_ctime.tv_sec = ip->i_ctime;
406 vap->va_ctime.tv_nsec = ip->i_ctimensec;
407 vap->va_flags = ip->i_flags;
408 vap->va_gen = ip->i_gen;
409 vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
410 vap->va_bytes = dbtob((u_quad_t)ip->i_blocks);
411 vap->va_type = IFTOVT(ip->i_mode);
412 vap->va_filerev = ip->i_modrev;
417 * Set attribute vnode op. called from several syscalls
421 struct vop_setattr_args /* {
424 struct ucred *a_cred;
428 struct vattr *vap = ap->a_vap;
429 struct vnode *vp = ap->a_vp;
430 struct inode *ip = VTOI(vp);
431 struct ucred *cred = ap->a_cred;
432 struct proc *p = ap->a_p;
436 * Check for unsettable attributes.
438 if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
439 (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
440 (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
441 ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
444 if (vap->va_flags != VNOVAL) {
445 if (vp->v_mount->mnt_flag & MNT_RDONLY)
447 if (cred->cr_uid != ip->i_uid &&
448 (error = suser_xxx(cred, p, PRISON_ROOT)))
450 if (cred->cr_uid == 0) {
452 & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) &&
455 ip->i_flags = vap->va_flags;
458 & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND) ||
459 (vap->va_flags & UF_SETTABLE) != vap->va_flags)
461 ip->i_flags &= SF_SETTABLE;
462 ip->i_flags |= (vap->va_flags & UF_SETTABLE);
464 ip->i_flag |= IN_CHANGE;
465 if (vap->va_flags & (IMMUTABLE | APPEND))
468 if (ip->i_flags & (IMMUTABLE | APPEND))
471 * Go through the fields and update iff not VNOVAL.
473 if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
474 if (vp->v_mount->mnt_flag & MNT_RDONLY)
476 if ((error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, p)) != 0)
479 if (vap->va_size != VNOVAL) {
481 * Disallow write attempts on read-only file systems;
482 * unless the file is a socket, fifo, or a block or
483 * character device resident on the file system.
485 switch (vp->v_type) {
490 if (vp->v_mount->mnt_flag & MNT_RDONLY)
496 if ((error = UFS_TRUNCATE(vp, vap->va_size, 0, cred, p)) != 0)
500 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
501 if (vp->v_mount->mnt_flag & MNT_RDONLY)
503 if (cred->cr_uid != ip->i_uid &&
504 (error = suser_xxx(cred, p, PRISON_ROOT)) &&
505 ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
506 (error = VOP_ACCESS(vp, VWRITE, cred, p))))
508 if (vap->va_atime.tv_sec != VNOVAL)
509 ip->i_flag |= IN_ACCESS;
510 if (vap->va_mtime.tv_sec != VNOVAL)
511 ip->i_flag |= IN_CHANGE | IN_UPDATE;
513 if (vap->va_atime.tv_sec != VNOVAL) {
514 ip->i_atime = vap->va_atime.tv_sec;
515 ip->i_atimensec = vap->va_atime.tv_nsec;
517 if (vap->va_mtime.tv_sec != VNOVAL) {
518 ip->i_mtime = vap->va_mtime.tv_sec;
519 ip->i_mtimensec = vap->va_mtime.tv_nsec;
521 error = UFS_UPDATE(vp, 0);
526 if (vap->va_mode != (mode_t)VNOVAL) {
527 if (vp->v_mount->mnt_flag & MNT_RDONLY)
529 error = ufs_chmod(vp, (int)vap->va_mode, cred, p);
531 VN_POLLEVENT(vp, POLLATTRIB);
536 * Change the mode on a file.
537 * Inode must be locked before calling.
540 ufs_chmod(vp, mode, cred, p)
541 register struct vnode *vp;
543 register struct ucred *cred;
546 register struct inode *ip = VTOI(vp);
549 if (cred->cr_uid != ip->i_uid) {
550 error = suser_xxx(cred, p, PRISON_ROOT);
555 if (vp->v_type != VDIR && (mode & S_ISTXT))
557 if (!groupmember(ip->i_gid, cred) && (mode & ISGID))
560 ip->i_mode &= ~ALLPERMS;
561 ip->i_mode |= (mode & ALLPERMS);
562 ip->i_flag |= IN_CHANGE;
567 * Perform chown operation on inode ip;
568 * inode must be locked prior to call.
571 ufs_chown(vp, uid, gid, cred, p)
572 register struct vnode *vp;
578 register struct inode *ip = VTOI(vp);
587 if (uid == (uid_t)VNOVAL)
589 if (gid == (gid_t)VNOVAL)
592 * If we don't own the file, are trying to change the owner
593 * of the file, or are not a member of the target group,
594 * the caller must be superuser or the call fails.
596 if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid ||
597 (gid != ip->i_gid && !groupmember((gid_t)gid, cred))) &&
598 (error = suser_xxx(cred, p, PRISON_ROOT)))
603 if ((error = getinoquota(ip)) != 0)
606 dqrele(vp, ip->i_dquot[USRQUOTA]);
607 ip->i_dquot[USRQUOTA] = NODQUOT;
610 dqrele(vp, ip->i_dquot[GRPQUOTA]);
611 ip->i_dquot[GRPQUOTA] = NODQUOT;
613 change = ip->i_blocks;
614 (void) chkdq(ip, -change, cred, CHOWN);
615 (void) chkiq(ip, -1, cred, CHOWN);
616 for (i = 0; i < MAXQUOTAS; i++) {
617 dqrele(vp, ip->i_dquot[i]);
618 ip->i_dquot[i] = NODQUOT;
624 if ((error = getinoquota(ip)) == 0) {
626 dqrele(vp, ip->i_dquot[USRQUOTA]);
627 ip->i_dquot[USRQUOTA] = NODQUOT;
630 dqrele(vp, ip->i_dquot[GRPQUOTA]);
631 ip->i_dquot[GRPQUOTA] = NODQUOT;
633 if ((error = chkdq(ip, change, cred, CHOWN)) == 0) {
634 if ((error = chkiq(ip, 1, cred, CHOWN)) == 0)
637 (void) chkdq(ip, -change, cred, CHOWN|FORCE);
639 for (i = 0; i < MAXQUOTAS; i++) {
640 dqrele(vp, ip->i_dquot[i]);
641 ip->i_dquot[i] = NODQUOT;
646 if (getinoquota(ip) == 0) {
648 dqrele(vp, ip->i_dquot[USRQUOTA]);
649 ip->i_dquot[USRQUOTA] = NODQUOT;
652 dqrele(vp, ip->i_dquot[GRPQUOTA]);
653 ip->i_dquot[GRPQUOTA] = NODQUOT;
655 (void) chkdq(ip, change, cred, FORCE|CHOWN);
656 (void) chkiq(ip, 1, cred, FORCE|CHOWN);
657 (void) getinoquota(ip);
662 panic("ufs_chown: lost quota");
664 ip->i_flag |= IN_CHANGE;
665 if (cred->cr_uid != 0 && (ouid != uid || ogid != gid))
666 ip->i_mode &= ~(ISUID | ISGID);
673 * NB Currently unsupported.
678 struct vop_mmap_args /* {
681 struct ucred *a_cred;
691 struct vop_remove_args /* {
694 struct componentname *a_cnp;
698 struct vnode *vp = ap->a_vp;
699 struct vnode *dvp = ap->a_dvp;
703 if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
704 (VTOI(dvp)->i_flags & APPEND)) {
708 error = ufs_dirremove(dvp, ip, ap->a_cnp->cn_flags, 0);
709 VN_POLLEVENT(vp, POLLNLINK);
710 VN_POLLEVENT(dvp, POLLWRITE);
720 struct vop_link_args /* {
721 struct vnode *a_tdvp;
723 struct componentname *a_cnp;
726 struct vnode *vp = ap->a_vp;
727 struct vnode *tdvp = ap->a_tdvp;
728 struct componentname *cnp = ap->a_cnp;
729 struct proc *p = cnp->cn_proc;
731 struct direct newdir;
735 if ((cnp->cn_flags & HASBUF) == 0)
736 panic("ufs_link: no name");
738 if (tdvp->v_mount != vp->v_mount) {
739 VOP_ABORTOP(tdvp, cnp);
743 if (tdvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE, p))) {
744 VOP_ABORTOP(tdvp, cnp);
748 if ((nlink_t)ip->i_nlink >= LINK_MAX) {
749 VOP_ABORTOP(tdvp, cnp);
753 if (ip->i_flags & (IMMUTABLE | APPEND)) {
754 VOP_ABORTOP(tdvp, cnp);
760 ip->i_flag |= IN_CHANGE;
761 if (DOINGSOFTDEP(vp))
762 softdep_increase_linkcnt(ip);
763 error = UFS_UPDATE(vp, !(DOINGSOFTDEP(vp) | DOINGASYNC(vp)));
765 ufs_makedirentry(ip, cnp, &newdir);
766 error = ufs_direnter(tdvp, vp, &newdir, cnp, NULL);
772 ip->i_flag |= IN_CHANGE;
774 zfree(namei_zone, cnp->cn_pnbuf);
777 VOP_UNLOCK(vp, 0, p);
779 VN_POLLEVENT(vp, POLLNLINK);
780 VN_POLLEVENT(tdvp, POLLWRITE);
785 * whiteout vnode call
789 struct vop_whiteout_args /* {
791 struct componentname *a_cnp;
795 struct vnode *dvp = ap->a_dvp;
796 struct componentname *cnp = ap->a_cnp;
797 struct direct newdir;
800 switch (ap->a_flags) {
802 /* 4.4 format directories support whiteout operations */
803 if (dvp->v_mount->mnt_maxsymlinklen > 0)
808 /* create a new directory whiteout */
810 if ((cnp->cn_flags & SAVENAME) == 0)
811 panic("ufs_whiteout: missing name");
812 if (dvp->v_mount->mnt_maxsymlinklen <= 0)
813 panic("ufs_whiteout: old format filesystem");
817 newdir.d_namlen = cnp->cn_namelen;
818 bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1);
819 newdir.d_type = DT_WHT;
820 error = ufs_direnter(dvp, NULL, &newdir, cnp, NULL);
824 /* remove an existing directory whiteout */
826 if (dvp->v_mount->mnt_maxsymlinklen <= 0)
827 panic("ufs_whiteout: old format filesystem");
830 cnp->cn_flags &= ~DOWHITEOUT;
831 error = ufs_dirremove(dvp, NULL, cnp->cn_flags, 0);
834 panic("ufs_whiteout: unknown op");
836 if (cnp->cn_flags & HASBUF) {
837 zfree(namei_zone, cnp->cn_pnbuf);
838 cnp->cn_flags &= ~HASBUF;
844 * Rename system call.
845 * rename("foo", "bar");
848 * link("foo", "bar");
850 * but ``atomically''. Can't do full commit without saving state in the
851 * inode on disk which isn't feasible at this time. Best we can do is
852 * always guarantee the target exists.
854 * Basic algorithm is:
856 * 1) Bump link count on source while we're linking it to the
857 * target. This also ensure the inode won't be deleted out
858 * from underneath us while we work (it may be truncated by
859 * a concurrent `trunc' or `open' for creation).
860 * 2) Link source to destination. If destination already exists,
862 * 3) Unlink source reference to inode if still around. If a
863 * directory was moved and the parent of the destination
864 * is different from the source, patch the ".." entry in the
869 struct vop_rename_args /* {
870 struct vnode *a_fdvp;
872 struct componentname *a_fcnp;
873 struct vnode *a_tdvp;
875 struct componentname *a_tcnp;
878 struct vnode *tvp = ap->a_tvp;
879 register struct vnode *tdvp = ap->a_tdvp;
880 struct vnode *fvp = ap->a_fvp;
881 struct vnode *fdvp = ap->a_fdvp;
882 struct componentname *tcnp = ap->a_tcnp;
883 struct componentname *fcnp = ap->a_fcnp;
884 struct proc *p = fcnp->cn_proc;
885 struct inode *ip, *xp, *dp;
886 struct direct newdir;
887 int doingdirectory = 0, oldparent = 0, newparent = 0;
888 int error = 0, ioflag;
891 if ((tcnp->cn_flags & HASBUF) == 0 ||
892 (fcnp->cn_flags & HASBUF) == 0)
893 panic("ufs_rename: no name");
896 * Check for cross-device rename.
898 if ((fvp->v_mount != tdvp->v_mount) ||
899 (tvp && (fvp->v_mount != tvp->v_mount))) {
902 VOP_ABORTOP(tdvp, tcnp);
909 VOP_ABORTOP(fdvp, fcnp);
915 if (tvp && ((VTOI(tvp)->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) ||
916 (VTOI(tdvp)->i_flags & APPEND))) {
922 * Check if just deleting a link name or if we've lost a race.
923 * If another process completes the same rename after we've looked
924 * up the source and have blocked looking up the target, then the
925 * source and target inodes may be identical now although the
926 * names were never linked.
929 if (fvp->v_type == VDIR) {
931 * Linked directories are impossible, so we must
932 * have lost the race. Pretend that the rename
933 * completed before the lookup.
935 #ifdef UFS_RENAME_DEBUG
936 printf("ufs_rename: fvp == tvp for directories\n");
942 /* Release destination completely. */
943 VOP_ABORTOP(tdvp, tcnp);
948 * Delete source. There is another race now that everything
949 * is unlocked, but this doesn't cause any new complications.
950 * Relookup() may find a file that is unrelated to the
951 * original one, or it may fail. Too bad.
955 fcnp->cn_flags &= ~MODMASK;
956 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
957 if ((fcnp->cn_flags & SAVESTART) == 0)
958 panic("ufs_rename: lost from startdir");
959 fcnp->cn_nameiop = DELETE;
961 error = relookup(fdvp, &fvp, fcnp);
965 #ifdef UFS_RENAME_DEBUG
966 printf("ufs_rename: from name disappeared\n");
970 error = VOP_REMOVE(fdvp, fvp, fcnp);
978 if ((error = vn_lock(fvp, LK_EXCLUSIVE, p)) != 0)
982 if (ip->i_nlink >= LINK_MAX) {
983 VOP_UNLOCK(fvp, 0, p);
987 if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))
988 || (dp->i_flags & APPEND)) {
989 VOP_UNLOCK(fvp, 0, p);
993 if ((ip->i_mode & IFMT) == IFDIR) {
995 * Avoid ".", "..", and aliases of "." for obvious reasons.
997 if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
998 dp == ip || (fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT ||
999 (ip->i_flag & IN_RENAME)) {
1000 VOP_UNLOCK(fvp, 0, p);
1004 ip->i_flag |= IN_RENAME;
1005 oldparent = dp->i_number;
1008 VN_POLLEVENT(fdvp, POLLWRITE);
1012 * When the target exists, both the directory
1013 * and target vnodes are returned locked.
1021 * 1) Bump link count while we're moving stuff
1022 * around. If we crash somewhere before
1023 * completing our work, the link count
1024 * may be wrong, but correctable.
1028 ip->i_flag |= IN_CHANGE;
1029 if (DOINGSOFTDEP(fvp))
1030 softdep_increase_linkcnt(ip);
1031 if ((error = UFS_UPDATE(fvp, !(DOINGSOFTDEP(fvp) |
1032 DOINGASYNC(fvp)))) != 0) {
1033 VOP_UNLOCK(fvp, 0, p);
1038 * If ".." must be changed (ie the directory gets a new
1039 * parent) then the source directory must not be in the
1040 * directory heirarchy above the target, as this would
1041 * orphan everything below the source directory. Also
1042 * the user must have write permission in the source so
1043 * as to be able to change "..". We must repeat the call
1044 * to namei, as the parent directory is unlocked by the
1045 * call to checkpath().
1047 error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_proc);
1048 VOP_UNLOCK(fvp, 0, p);
1049 if (oldparent != dp->i_number)
1050 newparent = dp->i_number;
1051 if (doingdirectory && newparent) {
1052 if (error) /* write access check above */
1056 error = ufs_checkpath(ip, dp, tcnp->cn_cred);
1059 if ((tcnp->cn_flags & SAVESTART) == 0)
1060 panic("ufs_rename: lost to startdir");
1062 error = relookup(tdvp, &tvp, tcnp);
1072 * 2) If target doesn't exist, link the target
1073 * to the source and unlink the source.
1074 * Otherwise, rewrite the target directory
1075 * entry to reference the source inode and
1076 * expunge the original entry's existence.
1079 if (dp->i_dev != ip->i_dev)
1080 panic("ufs_rename: EXDEV");
1082 * Account for ".." in new directory.
1083 * When source and destination have the same
1084 * parent we don't fool with the link count.
1086 if (doingdirectory && newparent) {
1087 if ((nlink_t)dp->i_nlink >= LINK_MAX) {
1093 dp->i_flag |= IN_CHANGE;
1094 if (DOINGSOFTDEP(tdvp))
1095 softdep_increase_linkcnt(dp);
1096 error = UFS_UPDATE(tdvp, !(DOINGSOFTDEP(tdvp) |
1101 ufs_makedirentry(ip, tcnp, &newdir);
1102 error = ufs_direnter(tdvp, NULL, &newdir, tcnp, NULL);
1104 if (doingdirectory && newparent) {
1107 dp->i_flag |= IN_CHANGE;
1108 (void)UFS_UPDATE(tdvp, 1);
1112 VN_POLLEVENT(tdvp, POLLWRITE);
1115 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev)
1116 panic("ufs_rename: EXDEV");
1118 * Short circuit rename(foo, foo).
1120 if (xp->i_number == ip->i_number)
1121 panic("ufs_rename: same file");
1123 * If the parent directory is "sticky", then the user must
1124 * own the parent directory, or the destination of the rename,
1125 * otherwise the destination may not be changed (except by
1126 * root). This implements append-only directories.
1128 if ((dp->i_mode & S_ISTXT) && tcnp->cn_cred->cr_uid != 0 &&
1129 tcnp->cn_cred->cr_uid != dp->i_uid &&
1130 xp->i_uid != tcnp->cn_cred->cr_uid) {
1135 * Target must be empty if a directory and have no links
1136 * to it. Also, ensure source and target are compatible
1137 * (both directories, or both not directories).
1139 if ((xp->i_mode&IFMT) == IFDIR) {
1140 if ((xp->i_effnlink > 2) ||
1141 !ufs_dirempty(xp, dp->i_number, tcnp->cn_cred)) {
1145 if (!doingdirectory) {
1150 } else if (doingdirectory) {
1154 error = ufs_dirrewrite(dp, xp, ip->i_number,
1156 (doingdirectory && newparent) ? newparent : doingdirectory);
1159 if (doingdirectory) {
1162 dp->i_flag |= IN_CHANGE;
1165 xp->i_flag |= IN_CHANGE;
1167 VN_POLLEVENT(tdvp, POLLWRITE);
1168 if (doingdirectory && !DOINGSOFTDEP(tvp)) {
1170 * Truncate inode. The only stuff left in the directory
1171 * is "." and "..". The "." reference is inconsequential
1172 * since we are quashing it. We have removed the "."
1173 * reference and the reference in the parent directory,
1174 * but there may be other hard links. The soft
1175 * dependency code will arrange to do these operations
1176 * after the parent directory entry has been deleted on
1177 * disk, so when running with that code we avoid doing
1183 ioflag = DOINGASYNC(tvp) ? 0 : IO_SYNC;
1184 if ((error = UFS_TRUNCATE(tvp, (off_t)0, ioflag,
1185 tcnp->cn_cred, tcnp->cn_proc)) != 0)
1189 VN_POLLEVENT(tvp, POLLNLINK); /* XXX this right? */
1195 * 3) Unlink the source.
1197 fcnp->cn_flags &= ~MODMASK;
1198 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
1199 if ((fcnp->cn_flags & SAVESTART) == 0)
1200 panic("ufs_rename: lost from startdir");
1202 error = relookup(fdvp, &fvp, fcnp);
1210 * From name has disappeared.
1213 panic("ufs_rename: lost dir entry");
1218 * Ensure that the directory entry still exists and has not
1219 * changed while the new name has been entered. If the source is
1220 * a file then the entry may have been unlinked or renamed. In
1221 * either case there is no further work to be done. If the source
1222 * is a directory then it cannot have been rmdir'ed; the IN_RENAME
1223 * flag ensures that it cannot be moved by another rename or removed
1228 panic("ufs_rename: lost dir entry");
1231 * If the source is a directory with a
1232 * new parent, the link count of the old
1233 * parent directory must be decremented
1234 * and ".." set to point to the new parent.
1236 if (doingdirectory && newparent) {
1237 xp->i_offset = mastertemplate.dot_reclen;
1238 ufs_dirrewrite(xp, dp, newparent, DT_DIR, 0);
1241 error = ufs_dirremove(fdvp, xp, fcnp->cn_flags, 0);
1242 xp->i_flag &= ~IN_RENAME;
1257 ip->i_flag &= ~IN_RENAME;
1258 if (vn_lock(fvp, LK_EXCLUSIVE, p) == 0) {
1261 ip->i_flag |= IN_CHANGE;
1262 ip->i_flag &= ~IN_RENAME;
1274 struct vop_mkdir_args /* {
1275 struct vnode *a_dvp;
1276 struct vnode **a_vpp;
1277 struct componentname *a_cnp;
1278 struct vattr *a_vap;
1281 register struct vnode *dvp = ap->a_dvp;
1282 register struct vattr *vap = ap->a_vap;
1283 register struct componentname *cnp = ap->a_cnp;
1284 register struct inode *ip, *dp;
1287 struct dirtemplate dirtemplate, *dtp;
1288 struct direct newdir;
1293 if ((cnp->cn_flags & HASBUF) == 0)
1294 panic("ufs_mkdir: no name");
1297 if ((nlink_t)dp->i_nlink >= LINK_MAX) {
1301 dmode = vap->va_mode & 0777;
1304 * Must simulate part of ufs_makeinode here to acquire the inode,
1305 * but not have it entered in the parent directory. The entry is
1306 * made later after writing "." and ".." entries.
1308 error = UFS_VALLOC(dvp, dmode, cnp->cn_cred, &tvp);
1312 ip->i_gid = dp->i_gid;
1316 struct ucred ucred, *ucp;
1320 * If we are hacking owners here, (only do this where told to)
1321 * and we are not giving it TOO root, (would subvert quotas)
1322 * then go ahead and give it to the other user.
1323 * The new directory also inherits the SUID bit.
1324 * If user's UID and dir UID are the same,
1325 * 'give it away' so that the SUID is still forced on.
1327 if ((dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
1328 (dp->i_mode & ISUID) && dp->i_uid) {
1330 ip->i_uid = dp->i_uid;
1332 if (dp->i_uid != cnp->cn_cred->cr_uid) {
1334 * Make sure the correct user gets charged
1336 * Make a dummy credential for the victim.
1337 * XXX This seems to never be accessed out of
1338 * our context so a stack variable is ok.
1341 ucred.cr_uid = ip->i_uid;
1342 ucred.cr_ngroups = 1;
1343 ucred.cr_groups[0] = dp->i_gid;
1348 ip->i_uid = cnp->cn_cred->cr_uid;
1350 if ((error = getinoquota(ip)) ||
1351 (error = chkiq(ip, 1, ucp, 0))) {
1352 zfree(namei_zone, cnp->cn_pnbuf);
1353 UFS_VFREE(tvp, ip->i_number, dmode);
1359 #else /* !SUIDDIR */
1360 ip->i_uid = cnp->cn_cred->cr_uid;
1362 if ((error = getinoquota(ip)) ||
1363 (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
1364 zfree(namei_zone, cnp->cn_pnbuf);
1365 UFS_VFREE(tvp, ip->i_number, dmode);
1370 #endif /* !SUIDDIR */
1371 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
1373 tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */
1376 if (DOINGSOFTDEP(tvp))
1377 softdep_increase_linkcnt(ip);
1378 if (cnp->cn_flags & ISWHITEOUT)
1379 ip->i_flags |= UF_OPAQUE;
1382 * Bump link count in parent directory to reflect work done below.
1383 * Should be done before reference is created so cleanup is
1384 * possible if we crash.
1388 dp->i_flag |= IN_CHANGE;
1389 if (DOINGSOFTDEP(dvp))
1390 softdep_increase_linkcnt(dp);
1391 error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(dvp) | DOINGASYNC(dvp)));
1396 * Initialize directory with "." and ".." from static template.
1398 if (dvp->v_mount->mnt_maxsymlinklen > 0
1400 dtp = &mastertemplate;
1402 dtp = (struct dirtemplate *)&omastertemplate;
1404 dirtemplate.dot_ino = ip->i_number;
1405 dirtemplate.dotdot_ino = dp->i_number;
1406 if ((error = VOP_BALLOC(tvp, (off_t)0, DIRBLKSIZ, cnp->cn_cred,
1407 B_CLRBUF, &bp)) != 0)
1409 ip->i_size = DIRBLKSIZ;
1410 ip->i_flag |= IN_CHANGE | IN_UPDATE;
1411 vnode_pager_setsize(tvp, (u_long)ip->i_size);
1412 bcopy((caddr_t)&dirtemplate, (caddr_t)bp->b_data, sizeof dirtemplate);
1413 if (DOINGSOFTDEP(tvp)) {
1415 * Ensure that the entire newly allocated block is a
1416 * valid directory so that future growth within the
1417 * block does not have to ensure that the block is
1418 * written before the inode.
1421 while (blkoff < bp->b_bcount) {
1423 (bp->b_data + blkoff))->d_reclen = DIRBLKSIZ;
1424 blkoff += DIRBLKSIZ;
1427 if ((error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(tvp) |
1428 DOINGASYNC(tvp)))) != 0) {
1429 (void)VOP_BWRITE(bp->b_vp, bp);
1432 VN_POLLEVENT(dvp, POLLWRITE); /* XXX right place? */
1434 * Directory set up, now install its entry in the parent directory.
1436 * If we are not doing soft dependencies, then we must write out the
1437 * buffer containing the new directory body before entering the new
1438 * name in the parent. If we are doing soft dependencies, then the
1439 * buffer containing the new directory body will be passed to and
1440 * released in the soft dependency code after the code has attached
1441 * an appropriate ordering dependency to the buffer which ensures that
1442 * the buffer is written before the new name is written in the parent.
1444 if (DOINGASYNC(dvp))
1446 else if (!DOINGSOFTDEP(dvp) && ((error = VOP_BWRITE(bp->b_vp, bp))))
1448 ufs_makedirentry(ip, cnp, &newdir);
1449 error = ufs_direnter(dvp, tvp, &newdir, cnp, bp);
1457 dp->i_flag |= IN_CHANGE;
1459 * No need to do an explicit VOP_TRUNCATE here, vrele will
1460 * do this for us because we set the link count to 0.
1464 ip->i_flag |= IN_CHANGE;
1468 zfree(namei_zone, cnp->cn_pnbuf);
1473 * Rmdir system call.
1477 struct vop_rmdir_args /* {
1478 struct vnode *a_dvp;
1480 struct componentname *a_cnp;
1483 struct vnode *vp = ap->a_vp;
1484 struct vnode *dvp = ap->a_dvp;
1485 struct componentname *cnp = ap->a_cnp;
1486 struct inode *ip, *dp;
1493 * Do not remove a directory that is in the process of being renamed.
1494 * Verify the directory is empty (and valid). Rmdir ".." will not be
1495 * valid since ".." will contain a reference to the current directory
1496 * and thus be non-empty. Do not allow the removal of mounted on
1497 * directories (this can happen when an NFS exported filesystem
1498 * tries to remove a locally mounted on directory).
1501 if (ip->i_flag & IN_RENAME) {
1505 if (ip->i_effnlink != 2 ||
1506 !ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) {
1510 if ((dp->i_flags & APPEND)
1511 || (ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND))) {
1515 if (vp->v_mountedhere != 0) {
1520 * Delete reference to directory before purging
1521 * inode. If we crash in between, the directory
1522 * will be reattached to lost+found,
1524 error = ufs_dirremove(dvp, ip, cnp->cn_flags, 1);
1527 VN_POLLEVENT(dvp, POLLWRITE|POLLNLINK);
1530 * Truncate inode. The only stuff left in the directory is "." and
1531 * "..". The "." reference is inconsequential since we are quashing
1532 * it. We have removed the "." reference and the reference in the
1533 * parent directory, but there may be other hard links. So,
1534 * ufs_dirremove will set the UF_IMMUTABLE flag to ensure that no
1535 * new entries are made. The soft dependency code will arrange to
1536 * do these operations after the parent directory entry has been
1537 * deleted on disk, so when running with that code we avoid doing
1541 dp->i_flag |= IN_CHANGE;
1543 ip->i_flag |= IN_CHANGE;
1544 if (!DOINGSOFTDEP(vp)) {
1547 ioflag = DOINGASYNC(vp) ? 0 : IO_SYNC;
1548 error = UFS_TRUNCATE(vp, (off_t)0, ioflag, cnp->cn_cred,
1553 VN_POLLEVENT(vp, POLLNLINK);
1558 * symlink -- make a symbolic link
1562 struct vop_symlink_args /* {
1563 struct vnode *a_dvp;
1564 struct vnode **a_vpp;
1565 struct componentname *a_cnp;
1566 struct vattr *a_vap;
1570 register struct vnode *vp, **vpp = ap->a_vpp;
1571 register struct inode *ip;
1574 error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
1578 VN_POLLEVENT(ap->a_dvp, POLLWRITE);
1580 len = strlen(ap->a_target);
1581 if (len < vp->v_mount->mnt_maxsymlinklen) {
1583 bcopy(ap->a_target, (char *)ip->i_shortlink, len);
1585 ip->i_flag |= IN_CHANGE | IN_UPDATE;
1587 error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
1588 UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, (int *)0,
1596 * Vnode op for reading directories.
1598 * The routine below assumes that the on-disk format of a directory
1599 * is the same as that defined by <sys/dirent.h>. If the on-disk
1600 * format changes, then it will be necessary to do a conversion
1601 * from the on-disk format that read returns to the format defined
1602 * by <sys/dirent.h>.
1606 struct vop_readdir_args /* {
1609 struct ucred *a_cred;
1615 register struct uio *uio = ap->a_uio;
1620 if (ap->a_ncookies != NULL)
1622 * Ensure that the block is aligned. The caller can use
1623 * the cookies to determine where in the block to start.
1625 uio->uio_offset &= ~(DIRBLKSIZ - 1);
1626 off = uio->uio_offset;
1627 count = uio->uio_resid;
1628 /* Make sure we don't return partial entries. */
1629 if (count <= ((uio->uio_offset + count) & (DIRBLKSIZ -1)))
1631 count -= (uio->uio_offset + count) & (DIRBLKSIZ -1);
1632 lost = uio->uio_resid - count;
1633 uio->uio_resid = count;
1634 uio->uio_iov->iov_len = count;
1635 # if (BYTE_ORDER == LITTLE_ENDIAN)
1636 if (ap->a_vp->v_mount->mnt_maxsymlinklen > 0) {
1637 error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
1639 struct dirent *dp, *edp;
1647 auio.uio_iov = &aiov;
1648 auio.uio_iovcnt = 1;
1649 auio.uio_segflg = UIO_SYSSPACE;
1650 aiov.iov_len = count;
1651 MALLOC(dirbuf, caddr_t, count, M_TEMP, M_WAITOK);
1652 aiov.iov_base = dirbuf;
1653 error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred);
1655 readcnt = count - auio.uio_resid;
1656 edp = (struct dirent *)&dirbuf[readcnt];
1657 for (dp = (struct dirent *)dirbuf; dp < edp; ) {
1659 dp->d_namlen = dp->d_type;
1661 if (dp->d_reclen > 0) {
1662 dp = (struct dirent *)
1663 ((char *)dp + dp->d_reclen);
1670 error = uiomove(dirbuf, readcnt, uio);
1672 FREE(dirbuf, M_TEMP);
1675 error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred);
1677 if (!error && ap->a_ncookies != NULL) {
1678 struct dirent* dpStart;
1679 struct dirent* dpEnd;
1685 if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
1686 panic("ufs_readdir: unexpected uio from NFS server");
1687 dpStart = (struct dirent *)
1688 (uio->uio_iov->iov_base - (uio->uio_offset - off));
1689 dpEnd = (struct dirent *) uio->uio_iov->iov_base;
1690 for (dp = dpStart, ncookies = 0;
1692 dp = (struct dirent *)((caddr_t) dp + dp->d_reclen))
1694 MALLOC(cookies, u_long *, ncookies * sizeof(u_long), M_TEMP,
1696 for (dp = dpStart, cookiep = cookies;
1698 dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) {
1699 off += dp->d_reclen;
1700 *cookiep++ = (u_long) off;
1702 *ap->a_ncookies = ncookies;
1703 *ap->a_cookies = cookies;
1705 uio->uio_resid += lost;
1707 *ap->a_eofflag = VTOI(ap->a_vp)->i_size <= uio->uio_offset;
1712 * Return target name of a symbolic link
1716 struct vop_readlink_args /* {
1719 struct ucred *a_cred;
1722 register struct vnode *vp = ap->a_vp;
1723 register struct inode *ip = VTOI(vp);
1727 if ((isize < vp->v_mount->mnt_maxsymlinklen) ||
1728 (ip->i_din.di_blocks == 0)) { /* XXX - for old fastlink support */
1729 uiomove((char *)ip->i_shortlink, isize, ap->a_uio);
1732 return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred));
1736 * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually
1737 * done. If a buffer has been saved in anticipation of a CREATE, delete it.
1742 struct vop_abortop_args /* {
1743 struct vnode *a_dvp;
1744 struct componentname *a_cnp;
1747 if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
1748 zfree(namei_zone, ap->a_cnp->cn_pnbuf);
1753 * Calculate the logical to physical mapping if not done already,
1754 * then call the device strategy routine.
1756 * In order to be able to swap to a file, the VOP_BMAP operation may not
1757 * deadlock on memory. See ufs_bmap() for details.
1761 struct vop_strategy_args /* {
1766 register struct buf *bp = ap->a_bp;
1767 register struct vnode *vp = ap->a_vp;
1768 register struct inode *ip;
1772 if (vp->v_type == VBLK || vp->v_type == VCHR)
1773 panic("ufs_strategy: spec");
1774 if (bp->b_blkno == bp->b_lblkno) {
1775 error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL, NULL);
1777 bp->b_error = error;
1778 bp->b_flags |= B_ERROR;
1782 if ((long)bp->b_blkno == -1)
1785 if ((long)bp->b_blkno == -1) {
1790 bp->b_dev = vp->v_rdev;
1791 VOP_STRATEGY(vp, bp);
1796 * Print out the contents of an inode.
1800 struct vop_print_args /* {
1804 register struct vnode *vp = ap->a_vp;
1805 register struct inode *ip = VTOI(vp);
1807 printf("tag VT_UFS, ino %lu, on dev %s (%d, %d)",
1808 (u_long)ip->i_number, devtoname(ip->i_dev), major(ip->i_dev),
1810 if (vp->v_type == VFIFO)
1812 lockmgr_printinfo(&ip->i_lock);
1818 * Read wrapper for special devices.
1822 struct vop_read_args /* {
1826 struct ucred *a_cred;
1834 resid = uio->uio_resid;
1835 error = VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap);
1837 * The inode may have been revoked during the call, so it must not
1838 * be accessed blindly here or in the other wrapper functions.
1840 ip = VTOI(ap->a_vp);
1841 if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
1842 ip->i_flag |= IN_ACCESS;
1847 * Write wrapper for special devices.
1851 struct vop_write_args /* {
1855 struct ucred *a_cred;
1863 resid = uio->uio_resid;
1864 error = VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap);
1865 ip = VTOI(ap->a_vp);
1866 if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
1867 VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
1872 * Close wrapper for special devices.
1874 * Update the times on the inode then do device close.
1878 struct vop_close_args /* {
1881 struct ucred *a_cred;
1885 struct vnode *vp = ap->a_vp;
1887 simple_lock(&vp->v_interlock);
1888 if (vp->v_usecount > 1)
1890 simple_unlock(&vp->v_interlock);
1891 return (VOCALL(spec_vnodeop_p, VOFFSET(vop_close), ap));
1895 * Read wrapper for fifos.
1899 struct vop_read_args /* {
1903 struct ucred *a_cred;
1911 resid = uio->uio_resid;
1912 error = VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap);
1913 ip = VTOI(ap->a_vp);
1914 if ((ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) == 0 && ip != NULL &&
1915 (uio->uio_resid != resid || (error == 0 && resid != 0)))
1916 VTOI(ap->a_vp)->i_flag |= IN_ACCESS;
1921 * Write wrapper for fifos.
1925 struct vop_write_args /* {
1929 struct ucred *a_cred;
1937 resid = uio->uio_resid;
1938 error = VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap);
1939 ip = VTOI(ap->a_vp);
1940 if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
1941 VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
1946 * Close wrapper for fifos.
1948 * Update the times on the inode then do device close.
1952 struct vop_close_args /* {
1955 struct ucred *a_cred;
1959 struct vnode *vp = ap->a_vp;
1961 simple_lock(&vp->v_interlock);
1962 if (vp->v_usecount > 1)
1964 simple_unlock(&vp->v_interlock);
1965 return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap));
1969 * Return POSIX pathconf information applicable to ufs filesystems.
1973 struct vop_pathconf_args /* {
1980 switch (ap->a_name) {
1982 *ap->a_retval = LINK_MAX;
1985 *ap->a_retval = NAME_MAX;
1988 *ap->a_retval = PATH_MAX;
1991 *ap->a_retval = PIPE_BUF;
1993 case _PC_CHOWN_RESTRICTED:
2006 * Advisory record locking support
2010 struct vop_advlock_args /* {
2018 register struct inode *ip = VTOI(ap->a_vp);
2020 return (lf_advlock(ap, &(ip->i_lockf), ip->i_size));
2024 * Initialize the vnode associated with a new inode, handle aliased
2028 ufs_vinit(mntp, specops, fifoops, vpp)
2040 switch(vp->v_type = IFTOVT(ip->i_mode)) {
2044 addaliasu(vp, ip->i_rdev);
2053 if (ip->i_number == ROOTINO)
2054 vp->v_flag |= VROOT;
2056 * Initialize modrev times
2058 getmicrouptime(&tv);
2059 SETHIGH(ip->i_modrev, tv.tv_sec);
2060 SETLOW(ip->i_modrev, tv.tv_usec * 4294);
2066 * Allocate a new inode.
2069 ufs_makeinode(mode, dvp, vpp, cnp)
2073 struct componentname *cnp;
2075 register struct inode *ip, *pdir;
2076 struct direct newdir;
2082 if ((cnp->cn_flags & HASBUF) == 0)
2083 panic("ufs_makeinode: no name");
2086 if ((mode & IFMT) == 0)
2089 error = UFS_VALLOC(dvp, mode, cnp->cn_cred, &tvp);
2091 zfree(namei_zone, cnp->cn_pnbuf);
2095 ip->i_gid = pdir->i_gid;
2099 struct ucred ucred, *ucp;
2103 * If we are not the owner of the directory,
2104 * and we are hacking owners here, (only do this where told to)
2105 * and we are not giving it TOO root, (would subvert quotas)
2106 * then go ahead and give it to the other user.
2107 * Note that this drops off the execute bits for security.
2109 if ((dvp->v_mount->mnt_flag & MNT_SUIDDIR) &&
2110 (pdir->i_mode & ISUID) &&
2111 (pdir->i_uid != cnp->cn_cred->cr_uid) && pdir->i_uid) {
2112 ip->i_uid = pdir->i_uid;
2116 * Make sure the correct user gets charged
2118 * Quickly knock up a dummy credential for the victim.
2119 * XXX This seems to never be accessed out of our
2120 * context so a stack variable is ok.
2123 ucred.cr_uid = ip->i_uid;
2124 ucred.cr_ngroups = 1;
2125 ucred.cr_groups[0] = pdir->i_gid;
2129 ip->i_uid = cnp->cn_cred->cr_uid;
2132 if ((error = getinoquota(ip)) ||
2133 (error = chkiq(ip, 1, ucp, 0))) {
2134 zfree(namei_zone, cnp->cn_pnbuf);
2135 UFS_VFREE(tvp, ip->i_number, mode);
2141 #else /* !SUIDDIR */
2142 ip->i_uid = cnp->cn_cred->cr_uid;
2144 if ((error = getinoquota(ip)) ||
2145 (error = chkiq(ip, 1, cnp->cn_cred, 0))) {
2146 zfree(namei_zone, cnp->cn_pnbuf);
2147 UFS_VFREE(tvp, ip->i_number, mode);
2152 #endif /* !SUIDDIR */
2153 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
2155 tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */
2158 if (DOINGSOFTDEP(tvp))
2159 softdep_increase_linkcnt(ip);
2160 if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
2161 suser_xxx(cnp->cn_cred, 0, 0))
2162 ip->i_mode &= ~ISGID;
2164 if (cnp->cn_flags & ISWHITEOUT)
2165 ip->i_flags |= UF_OPAQUE;
2168 * Make sure inode goes to disk before directory entry.
2170 error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(tvp) | DOINGASYNC(tvp)));
2173 ufs_makedirentry(ip, cnp, &newdir);
2174 error = ufs_direnter(dvp, tvp, &newdir, cnp, NULL);
2178 if ((cnp->cn_flags & SAVESTART) == 0)
2179 zfree(namei_zone, cnp->cn_pnbuf);
2185 * Write error occurred trying to update the inode
2186 * or the directory so must deallocate the inode.
2188 zfree(namei_zone, cnp->cn_pnbuf);
2191 ip->i_flag |= IN_CHANGE;
2198 struct vop_generic_args *ap;
2201 panic("no vop function for %s in ufs child", ap->a_desc->vdesc_name);
2202 return (EOPNOTSUPP);
2205 /* Global vfs data structures for ufs. */
2206 static vop_t **ufs_vnodeop_p;
2207 static struct vnodeopv_entry_desc ufs_vnodeop_entries[] = {
2208 { &vop_default_desc, (vop_t *) vop_defaultop },
2209 { &vop_fsync_desc, (vop_t *) ufs_missingop },
2210 { &vop_read_desc, (vop_t *) ufs_missingop },
2211 { &vop_reallocblks_desc, (vop_t *) ufs_missingop },
2212 { &vop_write_desc, (vop_t *) ufs_missingop },
2213 { &vop_abortop_desc, (vop_t *) ufs_abortop },
2214 { &vop_access_desc, (vop_t *) ufs_access },
2215 { &vop_advlock_desc, (vop_t *) ufs_advlock },
2216 { &vop_bmap_desc, (vop_t *) ufs_bmap },
2217 { &vop_cachedlookup_desc, (vop_t *) ufs_lookup },
2218 { &vop_close_desc, (vop_t *) ufs_close },
2219 { &vop_create_desc, (vop_t *) ufs_create },
2220 { &vop_getattr_desc, (vop_t *) ufs_getattr },
2221 { &vop_inactive_desc, (vop_t *) ufs_inactive },
2222 { &vop_islocked_desc, (vop_t *) vop_stdislocked },
2223 { &vop_link_desc, (vop_t *) ufs_link },
2224 { &vop_lock_desc, (vop_t *) vop_stdlock },
2225 { &vop_lookup_desc, (vop_t *) vfs_cache_lookup },
2226 { &vop_mkdir_desc, (vop_t *) ufs_mkdir },
2227 { &vop_mknod_desc, (vop_t *) ufs_mknod },
2228 { &vop_mmap_desc, (vop_t *) ufs_mmap },
2229 { &vop_open_desc, (vop_t *) ufs_open },
2230 { &vop_pathconf_desc, (vop_t *) ufs_pathconf },
2231 { &vop_poll_desc, (vop_t *) vop_stdpoll },
2232 { &vop_print_desc, (vop_t *) ufs_print },
2233 { &vop_readdir_desc, (vop_t *) ufs_readdir },
2234 { &vop_readlink_desc, (vop_t *) ufs_readlink },
2235 { &vop_reclaim_desc, (vop_t *) ufs_reclaim },
2236 { &vop_remove_desc, (vop_t *) ufs_remove },
2237 { &vop_rename_desc, (vop_t *) ufs_rename },
2238 { &vop_rmdir_desc, (vop_t *) ufs_rmdir },
2239 { &vop_setattr_desc, (vop_t *) ufs_setattr },
2240 { &vop_strategy_desc, (vop_t *) ufs_strategy },
2241 { &vop_symlink_desc, (vop_t *) ufs_symlink },
2242 { &vop_unlock_desc, (vop_t *) vop_stdunlock },
2243 { &vop_whiteout_desc, (vop_t *) ufs_whiteout },
2246 static struct vnodeopv_desc ufs_vnodeop_opv_desc =
2247 { &ufs_vnodeop_p, ufs_vnodeop_entries };
2249 static vop_t **ufs_specop_p;
2250 static struct vnodeopv_entry_desc ufs_specop_entries[] = {
2251 { &vop_default_desc, (vop_t *) spec_vnoperate },
2252 { &vop_fsync_desc, (vop_t *) ufs_missingop },
2253 { &vop_access_desc, (vop_t *) ufs_access },
2254 { &vop_close_desc, (vop_t *) ufsspec_close },
2255 { &vop_getattr_desc, (vop_t *) ufs_getattr },
2256 { &vop_inactive_desc, (vop_t *) ufs_inactive },
2257 { &vop_islocked_desc, (vop_t *) vop_stdislocked },
2258 { &vop_lock_desc, (vop_t *) vop_stdlock },
2259 { &vop_print_desc, (vop_t *) ufs_print },
2260 { &vop_read_desc, (vop_t *) ufsspec_read },
2261 { &vop_reclaim_desc, (vop_t *) ufs_reclaim },
2262 { &vop_setattr_desc, (vop_t *) ufs_setattr },
2263 { &vop_unlock_desc, (vop_t *) vop_stdunlock },
2264 { &vop_write_desc, (vop_t *) ufsspec_write },
2267 static struct vnodeopv_desc ufs_specop_opv_desc =
2268 { &ufs_specop_p, ufs_specop_entries };
2270 static vop_t **ufs_fifoop_p;
2271 static struct vnodeopv_entry_desc ufs_fifoop_entries[] = {
2272 { &vop_default_desc, (vop_t *) fifo_vnoperate },
2273 { &vop_fsync_desc, (vop_t *) ufs_missingop },
2274 { &vop_access_desc, (vop_t *) ufs_access },
2275 { &vop_close_desc, (vop_t *) ufsfifo_close },
2276 { &vop_getattr_desc, (vop_t *) ufs_getattr },
2277 { &vop_inactive_desc, (vop_t *) ufs_inactive },
2278 { &vop_islocked_desc, (vop_t *) vop_stdislocked },
2279 { &vop_lock_desc, (vop_t *) vop_stdlock },
2280 { &vop_print_desc, (vop_t *) ufs_print },
2281 { &vop_read_desc, (vop_t *) ufsfifo_read },
2282 { &vop_reclaim_desc, (vop_t *) ufs_reclaim },
2283 { &vop_setattr_desc, (vop_t *) ufs_setattr },
2284 { &vop_unlock_desc, (vop_t *) vop_stdunlock },
2285 { &vop_write_desc, (vop_t *) ufsfifo_write },
2288 static struct vnodeopv_desc ufs_fifoop_opv_desc =
2289 { &ufs_fifoop_p, ufs_fifoop_entries };
2291 VNODEOP_SET(ufs_vnodeop_opv_desc);
2292 VNODEOP_SET(ufs_specop_opv_desc);
2293 VNODEOP_SET(ufs_fifoop_opv_desc);
2297 struct vop_generic_args /* {
2298 struct vnodeop_desc *a_desc;
2301 return (VOCALL(ufs_vnodeop_p, ap->a_desc->vdesc_offset, ap));
2305 ufs_vnoperatefifo(ap)
2306 struct vop_generic_args /* {
2307 struct vnodeop_desc *a_desc;
2310 return (VOCALL(ufs_fifoop_p, ap->a_desc->vdesc_offset, ap));
2314 ufs_vnoperatespec(ap)
2315 struct vop_generic_args /* {
2316 struct vnodeop_desc *a_desc;
2319 return (VOCALL(ufs_specop_p, ap->a_desc->vdesc_offset, ap));