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