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