1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)ufs_vnops.c 7.93 (Berkeley) 06/02/92 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/namei.h> 13 #include <sys/resourcevar.h> 14 #include <sys/kernel.h> 15 #include <sys/file.h> 16 #include <sys/stat.h> 17 #include <sys/buf.h> 18 #include <sys/proc.h> 19 #include <sys/conf.h> 20 #include <sys/mount.h> 21 #include <sys/vnode.h> 22 #include <sys/specdev.h> 23 #include <sys/fifo.h> 24 #include <sys/malloc.h> 25 26 #include <vm/vm.h> 27 28 #include <ufs/ufs/lockf.h> 29 #include <ufs/ufs/quota.h> 30 #include <ufs/ufs/inode.h> 31 #include <ufs/ufs/dir.h> 32 #include <ufs/ufs/ufsmount.h> 33 #include <ufs/ufs/ufs_extern.h> 34 35 int ufs_chmod __P((struct vnode *, int, struct ucred *, struct proc *)); 36 int ufs_chown 37 __P((struct vnode *, uid_t, gid_t, struct ucred *, struct proc *)); 38 39 #ifdef _NOQUAD 40 #define SETHIGH(q, h) (q).val[_QUAD_HIGHWORD] = (h) 41 #define SETLOW(q, l) (q).val[_QUAD_LOWWORD] = (l) 42 #else /* QUAD */ 43 union _qcvt { 44 quad_t qcvt; 45 long val[2]; 46 }; 47 #define SETHIGH(q, h) { \ 48 union _qcvt tmp; \ 49 tmp.qcvt = (q); \ 50 tmp.val[_QUAD_HIGHWORD] = (h); \ 51 (q) = tmp.qcvt; \ 52 } 53 #define SETLOW(q, l) { \ 54 union _qcvt tmp; \ 55 tmp.qcvt = (q); \ 56 tmp.val[_QUAD_LOWWORD] = (l); \ 57 (q) = tmp.qcvt; \ 58 } 59 #endif /* QUAD */ 60 61 /* 62 * Create a regular file 63 */ 64 int 65 ufs_create(ap) 66 struct vop_create_args *ap; 67 { 68 int error; 69 70 if (error = 71 ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), 72 ap->a_dvp, ap->a_vpp, ap->a_cnp)) 73 return (error); 74 return (0); 75 } 76 77 /* 78 * Mknod vnode call 79 */ 80 /* ARGSUSED */ 81 int 82 ufs_mknod(ap) 83 struct vop_mknod_args *ap; 84 { 85 register struct vattr *vap = ap->a_vap; 86 register struct vnode **vpp = ap->a_vpp; 87 register struct inode *ip; 88 int error; 89 90 if (error = 91 ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode), 92 ap->a_dvp, vpp, ap->a_cnp)) 93 return (error); 94 ip = VTOI(*vpp); 95 ip->i_flag |= IACC|IUPD|ICHG; 96 if (vap->va_rdev != VNOVAL) { 97 /* 98 * Want to be able to use this to make badblock 99 * inodes, so don't truncate the dev number. 100 */ 101 ip->i_rdev = vap->va_rdev; 102 } 103 /* 104 * Remove inode so that it will be reloaded by iget and 105 * checked to see if it is an alias of an existing entry 106 * in the inode cache. 107 */ 108 vput(*vpp); 109 (*vpp)->v_type = VNON; 110 vgone(*vpp); 111 *vpp = 0; 112 return (0); 113 } 114 115 /* 116 * Open called. 117 * 118 * Nothing to do. 119 */ 120 /* ARGSUSED */ 121 int 122 ufs_open(ap) 123 struct vop_open_args *ap; 124 { 125 126 return (0); 127 } 128 129 /* 130 * Close called 131 * 132 * Update the times on the inode. 133 */ 134 /* ARGSUSED */ 135 int 136 ufs_close(ap) 137 struct vop_close_args *ap; 138 { 139 register struct vnode *vp = ap->a_vp; 140 register struct inode *ip = VTOI(vp); 141 142 if (vp->v_usecount > 1 && !(ip->i_flag & ILOCKED)) 143 ITIMES(ip, &time, &time); 144 return (0); 145 } 146 147 /* 148 * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. 149 * The mode is shifted to select the owner/group/other fields. The 150 * super user is granted all permissions. 151 */ 152 int 153 ufs_access(ap) 154 struct vop_access_args *ap; 155 { 156 USES_VOP_ISLOCKED; 157 register struct vnode *vp = ap->a_vp; 158 register struct inode *ip = VTOI(vp); 159 register struct ucred *cred = ap->a_cred; 160 mode_t mode = ap->a_mode; 161 register gid_t *gp; 162 int i, error; 163 164 #ifdef DIAGNOSTIC 165 if (!VOP_ISLOCKED(vp)) { 166 vprint("ufs_access: not locked", vp); 167 panic("ufs_access: not locked"); 168 } 169 #endif 170 #ifdef QUOTA 171 if (mode & VWRITE) { 172 switch (vp->v_type) { 173 case VREG: case VDIR: case VLNK: 174 if (error = getinoquota(ip)) 175 return (error); 176 } 177 } 178 #endif /* QUOTA */ 179 /* 180 * If you're the super-user, you always get access. 181 */ 182 if (cred->cr_uid == 0) 183 return (0); 184 /* 185 * Access check is based on only one of owner, group, public. 186 * If not owner, then check group. If not a member of the 187 * group, then check public access. 188 */ 189 if (cred->cr_uid != ip->i_uid) { 190 mode >>= 3; 191 gp = cred->cr_groups; 192 for (i = 0; i < cred->cr_ngroups; i++, gp++) 193 if (ip->i_gid == *gp) 194 goto found; 195 mode >>= 3; 196 found: 197 ; 198 } 199 if ((ip->i_mode & mode) != 0) 200 return (0); 201 return (EACCES); 202 } 203 204 /* ARGSUSED */ 205 int 206 ufs_getattr(ap) 207 struct vop_getattr_args *ap; 208 { 209 register struct vnode *vp = ap->a_vp; 210 register struct inode *ip = VTOI(vp); 211 register struct vattr *vap = ap->a_vap; 212 213 ITIMES(ip, &time, &time); 214 /* 215 * Copy from inode table 216 */ 217 vap->va_fsid = ip->i_dev; 218 vap->va_fileid = ip->i_number; 219 vap->va_mode = ip->i_mode & ~IFMT; 220 vap->va_nlink = ip->i_nlink; 221 vap->va_uid = ip->i_uid; 222 vap->va_gid = ip->i_gid; 223 vap->va_rdev = (dev_t)ip->i_rdev; 224 #ifdef tahoe 225 vap->va_size = ip->i_size; 226 vap->va_size_rsv = 0; 227 #else 228 vap->va_qsize = ip->i_din.di_qsize; 229 #endif 230 vap->va_atime = ip->i_atime; 231 vap->va_mtime = ip->i_mtime; 232 vap->va_ctime = ip->i_ctime; 233 vap->va_flags = ip->i_flags; 234 vap->va_gen = ip->i_gen; 235 /* this doesn't belong here */ 236 if (vp->v_type == VBLK) 237 vap->va_blocksize = BLKDEV_IOSIZE; 238 else if (vp->v_type == VCHR) 239 vap->va_blocksize = MAXBSIZE; 240 else 241 vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize; 242 vap->va_bytes = dbtob(ip->i_blocks); 243 #ifdef _NOQUAD 244 vap->va_bytes_rsv = 0; 245 #endif 246 vap->va_type = vp->v_type; 247 vap->va_filerev = ip->i_modrev; 248 return (0); 249 } 250 251 /* 252 * Set attribute vnode op. called from several syscalls 253 */ 254 int 255 ufs_setattr(ap) 256 struct vop_setattr_args *ap; 257 { 258 USES_VOP_TRUNCATE; 259 USES_VOP_UPDATE; 260 register struct vattr *vap = ap->a_vap; 261 register struct vnode *vp = ap->a_vp; 262 register struct inode *ip = VTOI(vp); 263 register struct ucred *cred = ap->a_cred; 264 register struct proc *p = ap->a_p; 265 int error; 266 267 /* 268 * Check for unsettable attributes. 269 */ 270 if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || 271 (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || 272 (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) || 273 ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { 274 return (EINVAL); 275 } 276 /* 277 * Go through the fields and update iff not VNOVAL. 278 */ 279 if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) 280 if (error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, p)) 281 return (error); 282 if (vap->va_size != VNOVAL) { 283 if (vp->v_type == VDIR) 284 return (EISDIR); 285 if (error = VOP_TRUNCATE(vp, vap->va_size, 0, cred)) 286 return (error); 287 } 288 ip = VTOI(vp); 289 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { 290 if (cred->cr_uid != ip->i_uid && 291 (error = suser(cred, &p->p_acflag))) 292 return (error); 293 if (vap->va_atime.tv_sec != VNOVAL) 294 ip->i_flag |= IACC; 295 if (vap->va_mtime.tv_sec != VNOVAL) 296 ip->i_flag |= IUPD; 297 ip->i_flag |= ICHG; 298 if (error = VOP_UPDATE(vp, &vap->va_atime, &vap->va_mtime, 1)) 299 return (error); 300 } 301 error = 0; 302 if (vap->va_mode != (mode_t)VNOVAL) 303 error = ufs_chmod(vp, (int)vap->va_mode, cred, p); 304 if (vap->va_flags != VNOVAL) { 305 if (cred->cr_uid != ip->i_uid && 306 (error = suser(cred, &p->p_acflag))) 307 return (error); 308 if (cred->cr_uid == 0) { 309 ip->i_flags = vap->va_flags; 310 } else { 311 ip->i_flags &= 0xffff0000; 312 ip->i_flags |= (vap->va_flags & 0xffff); 313 } 314 ip->i_flag |= ICHG; 315 } 316 return (error); 317 } 318 319 /* 320 * Change the mode on a file. 321 * Inode must be locked before calling. 322 */ 323 static int 324 ufs_chmod(vp, mode, cred, p) 325 register struct vnode *vp; 326 register int mode; 327 register struct ucred *cred; 328 struct proc *p; 329 { 330 register struct inode *ip = VTOI(vp); 331 int error; 332 333 if (cred->cr_uid != ip->i_uid && 334 (error = suser(cred, &p->p_acflag))) 335 return (error); 336 if (cred->cr_uid) { 337 if (vp->v_type != VDIR && (mode & ISVTX)) 338 return (EFTYPE); 339 if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) 340 return (EPERM); 341 } 342 ip->i_mode &= ~07777; 343 ip->i_mode |= mode & 07777; 344 ip->i_flag |= ICHG; 345 if ((vp->v_flag & VTEXT) && (ip->i_mode & ISVTX) == 0) 346 (void) vnode_pager_uncache(vp); 347 return (0); 348 } 349 350 /* 351 * Perform chown operation on inode ip; 352 * inode must be locked prior to call. 353 */ 354 static int 355 ufs_chown(vp, uid, gid, cred, p) 356 register struct vnode *vp; 357 uid_t uid; 358 gid_t gid; 359 struct ucred *cred; 360 struct proc *p; 361 { 362 register struct inode *ip = VTOI(vp); 363 uid_t ouid; 364 gid_t ogid; 365 int error = 0; 366 #ifdef QUOTA 367 register int i; 368 long change; 369 #endif 370 371 if (uid == (uid_t)VNOVAL) 372 uid = ip->i_uid; 373 if (gid == (gid_t)VNOVAL) 374 gid = ip->i_gid; 375 /* 376 * If we don't own the file, are trying to change the owner 377 * of the file, or are not a member of the target group, 378 * the caller must be superuser or the call fails. 379 */ 380 if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid || 381 !groupmember((gid_t)gid, cred)) && 382 (error = suser(cred, &p->p_acflag))) 383 return (error); 384 ouid = ip->i_uid; 385 ogid = ip->i_gid; 386 #ifdef QUOTA 387 if (error = getinoquota(ip)) 388 return (error); 389 if (ouid == uid) { 390 dqrele(vp, ip->i_dquot[USRQUOTA]); 391 ip->i_dquot[USRQUOTA] = NODQUOT; 392 } 393 if (ogid == gid) { 394 dqrele(vp, ip->i_dquot[GRPQUOTA]); 395 ip->i_dquot[GRPQUOTA] = NODQUOT; 396 } 397 change = ip->i_blocks; 398 (void) chkdq(ip, -change, cred, CHOWN); 399 (void) chkiq(ip, -1, cred, CHOWN); 400 for (i = 0; i < MAXQUOTAS; i++) { 401 dqrele(vp, ip->i_dquot[i]); 402 ip->i_dquot[i] = NODQUOT; 403 } 404 #endif 405 ip->i_uid = uid; 406 ip->i_gid = gid; 407 #ifdef QUOTA 408 if ((error = getinoquota(ip)) == 0) { 409 if (ouid == uid) { 410 dqrele(vp, ip->i_dquot[USRQUOTA]); 411 ip->i_dquot[USRQUOTA] = NODQUOT; 412 } 413 if (ogid == gid) { 414 dqrele(vp, ip->i_dquot[GRPQUOTA]); 415 ip->i_dquot[GRPQUOTA] = NODQUOT; 416 } 417 if ((error = chkdq(ip, change, cred, CHOWN)) == 0) { 418 if ((error = chkiq(ip, 1, cred, CHOWN)) == 0) 419 goto good; 420 else 421 (void) chkdq(ip, -change, cred, CHOWN|FORCE); 422 } 423 for (i = 0; i < MAXQUOTAS; i++) { 424 dqrele(vp, ip->i_dquot[i]); 425 ip->i_dquot[i] = NODQUOT; 426 } 427 } 428 ip->i_uid = ouid; 429 ip->i_gid = ogid; 430 if (getinoquota(ip) == 0) { 431 if (ouid == uid) { 432 dqrele(vp, ip->i_dquot[USRQUOTA]); 433 ip->i_dquot[USRQUOTA] = NODQUOT; 434 } 435 if (ogid == gid) { 436 dqrele(vp, ip->i_dquot[GRPQUOTA]); 437 ip->i_dquot[GRPQUOTA] = NODQUOT; 438 } 439 (void) chkdq(ip, change, cred, FORCE|CHOWN); 440 (void) chkiq(ip, 1, cred, FORCE|CHOWN); 441 (void) getinoquota(ip); 442 } 443 return (error); 444 good: 445 if (getinoquota(ip)) 446 panic("chown: lost quota"); 447 #endif /* QUOTA */ 448 if (ouid != uid || ogid != gid) 449 ip->i_flag |= ICHG; 450 if (ouid != uid && cred->cr_uid != 0) 451 ip->i_mode &= ~ISUID; 452 if (ogid != gid && cred->cr_uid != 0) 453 ip->i_mode &= ~ISGID; 454 return (0); 455 } 456 457 /* ARGSUSED */ 458 int 459 ufs_ioctl(ap) 460 struct vop_ioctl_args *ap; 461 { 462 463 return (ENOTTY); 464 } 465 466 /* ARGSUSED */ 467 int 468 ufs_select(ap) 469 struct vop_select_args *ap; 470 { 471 472 /* 473 * We should really check to see if I/O is possible. 474 */ 475 return (1); 476 } 477 478 /* 479 * Mmap a file 480 * 481 * NB Currently unsupported. 482 */ 483 /* ARGSUSED */ 484 int 485 ufs_mmap(ap) 486 struct vop_mmap_args *ap; 487 { 488 489 return (EINVAL); 490 } 491 492 /* 493 * Seek on a file 494 * 495 * Nothing to do, so just return. 496 */ 497 /* ARGSUSED */ 498 int 499 ufs_seek(ap) 500 struct vop_seek_args *ap; 501 { 502 503 return (0); 504 } 505 506 /* 507 * ufs remove 508 * Hard to avoid races here, especially 509 * in unlinking directories. 510 */ 511 int 512 ufs_remove(ap) 513 struct vop_remove_args *ap; 514 { 515 register struct inode *ip, *dp; 516 int error; 517 518 ip = VTOI(ap->a_vp); 519 dp = VTOI(ap->a_dvp); 520 error = ufs_dirremove(ap->a_dvp, ap->a_cnp); 521 if (!error) { 522 ip->i_nlink--; 523 ip->i_flag |= ICHG; 524 } 525 if (dp == ip) 526 vrele(ITOV(ip)); 527 else 528 ufs_iput(ip); 529 ufs_iput(dp); 530 return (error); 531 } 532 533 /* 534 * link vnode call 535 */ 536 int 537 ufs_link(ap) 538 struct vop_link_args *ap; 539 { 540 USES_VOP_UPDATE; 541 USES_VOP_ABORTOP; 542 register struct vnode *vp = ap->a_vp; 543 register struct vnode *tdvp = ap->a_tdvp; 544 register struct componentname *cnp = ap->a_cnp; 545 register struct inode *ip; 546 int error; 547 548 if (vp->v_mount != tdvp->v_mount) { 549 VOP_ABORTOP(vp, cnp); 550 if (tdvp == vp) 551 vrele(vp); 552 else 553 vput(vp); 554 vrele(tdvp); 555 return (EXDEV); 556 } 557 558 #ifdef DIAGNOSTIC 559 if ((cnp->cn_flags & HASBUF) == 0) 560 panic("ufs_link: no name"); 561 #endif 562 ip = VTOI(tdvp); 563 if ((nlink_t)ip->i_nlink >= LINK_MAX) { 564 free(cnp->cn_pnbuf, M_NAMEI); 565 return (EMLINK); 566 } 567 if (vp != tdvp) 568 ILOCK(ip); 569 ip->i_nlink++; 570 ip->i_flag |= ICHG; 571 error = VOP_UPDATE(tdvp, &time, &time, 1); 572 if (!error) 573 error = ufs_direnter(ip, vp, cnp); 574 if (vp != tdvp) 575 IUNLOCK(ip); 576 FREE(cnp->cn_pnbuf, M_NAMEI); 577 vput(vp); 578 if (error) { 579 ip->i_nlink--; 580 ip->i_flag |= ICHG; 581 } 582 return (error); 583 } 584 585 586 587 /* 588 * relookup - lookup a path name component 589 * Used by lookup to re-aquire things. 590 */ 591 int 592 relookup(dvp, vpp, cnp) 593 struct vnode *dvp, **vpp; 594 struct componentname *cnp; 595 { 596 USES_VOP_LOCK; 597 USES_VOP_LOOKUP; 598 USES_VOP_UNLOCK; 599 register struct vnode *dp = 0; /* the directory we are searching */ 600 struct vnode *tdp; /* saved dp */ 601 struct mount *mp; /* mount table entry */ 602 int docache; /* == 0 do not cache last component */ 603 int wantparent; /* 1 => wantparent or lockparent flag */ 604 int rdonly; /* lookup read-only flag bit */ 605 char *cp; /* DEBUG: check name ptr/len */ 606 int newhash; /* DEBUG: check name hash */ 607 int error = 0; 608 609 /* 610 * Setup: break out flag bits into variables. 611 */ 612 wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT); 613 docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE; 614 if (cnp->cn_nameiop == DELETE || 615 (wantparent && cnp->cn_nameiop != CREATE)) 616 docache = 0; 617 rdonly = cnp->cn_flags & RDONLY; 618 cnp->cn_flags &= ~ISSYMLINK; 619 dp = dvp; 620 VOP_LOCK(dp); 621 622 /* dirloop: */ 623 /* 624 * Search a new directory. 625 * 626 * The cn_hash value is for use by vfs_cache. 627 * The last component of the filename is left accessible via 628 * cnp->cn_nameptr for callers that need the name. Callers needing 629 * the name set the SAVENAME flag. When done, they assume 630 * responsibility for freeing the pathname buffer. 631 */ 632 #ifdef NAMEI_DIAGNOSTIC 633 for (newhash = 0, cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++) 634 newhash += (unsigned char)*cp; 635 if (newhash != cnp->cn_hash) 636 panic("relookup: bad hash"); 637 if (cnp->cn_namelen != cp - cnp->cn_nameptr) 638 panic ("relookup: bad len"); 639 if (*cp != 0) 640 panic("relookup: not last component"); 641 printf("{%s}: ", cnp->cn_nameptr); 642 #endif 643 644 /* 645 * Check for degenerate name (e.g. / or "") 646 * which is a way of talking about a directory, 647 * e.g. like "/." or ".". 648 */ 649 if (cnp->cn_nameptr[0] == '\0') { 650 if (cnp->cn_nameiop != LOOKUP || wantparent) { 651 error = EISDIR; 652 goto bad; 653 } 654 if (dp->v_type != VDIR) { 655 error = ENOTDIR; 656 goto bad; 657 } 658 if (!(cnp->cn_flags & LOCKLEAF)) 659 VOP_UNLOCK(dp); 660 *vpp = dp; 661 if (cnp->cn_flags & SAVESTART) 662 panic("lookup: SAVESTART"); 663 return (0); 664 } 665 666 if (cnp->cn_flags & ISDOTDOT) 667 panic ("relookup: lookup on dot-dot"); 668 669 /* 670 * We now have a segment name to search for, and a directory to search. 671 */ 672 if (error = VOP_LOOKUP(dp, vpp, cnp)) { 673 #ifdef DIAGNOSTIC 674 if (*vpp != NULL) 675 panic("leaf should be empty"); 676 #endif 677 if (error != EJUSTRETURN) 678 goto bad; 679 /* 680 * If creating and at end of pathname, then can consider 681 * allowing file to be created. 682 */ 683 if (rdonly || (dvp->v_mount->mnt_flag & MNT_RDONLY)) { 684 error = EROFS; 685 goto bad; 686 } 687 /* ASSERT(dvp == ndp->ni_startdir) */ 688 if (cnp->cn_flags & SAVESTART) 689 VREF(dvp); 690 /* 691 * We return with ni_vp NULL to indicate that the entry 692 * doesn't currently exist, leaving a pointer to the 693 * (possibly locked) directory inode in ndp->ni_dvp. 694 */ 695 return (0); 696 } 697 dp = *vpp; 698 699 #ifdef DIAGNOSTIC 700 /* 701 * Check for symbolic link 702 */ 703 if (dp->v_type == VLNK && (cnp->cn_flags & FOLLOW)) 704 panic ("relookup: symlink found.\n"); 705 #endif 706 707 nextname: 708 /* 709 * Check for read-only file systems. 710 */ 711 if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) { 712 /* 713 * Disallow directory write attempts on read-only 714 * file systems. 715 */ 716 if (rdonly || (dp->v_mount->mnt_flag & MNT_RDONLY) || 717 (wantparent && 718 (dvp->v_mount->mnt_flag & MNT_RDONLY))) { 719 error = EROFS; 720 goto bad2; 721 } 722 } 723 /* ASSERT(dvp == ndp->ni_startdir) */ 724 if (cnp->cn_flags & SAVESTART) 725 VREF(dvp); 726 727 if (!wantparent) 728 vrele(dvp); 729 if ((cnp->cn_flags & LOCKLEAF) == 0) 730 VOP_UNLOCK(dp); 731 return (0); 732 733 bad2: 734 if ((cnp->cn_flags & LOCKPARENT) && (cnp->cn_flags & ISLASTCN)) 735 VOP_UNLOCK(dvp); 736 vrele(dvp); 737 bad: 738 vput(dp); 739 *vpp = NULL; 740 return (error); 741 } 742 743 744 /* 745 * Rename system call. 746 * rename("foo", "bar"); 747 * is essentially 748 * unlink("bar"); 749 * link("foo", "bar"); 750 * unlink("foo"); 751 * but ``atomically''. Can't do full commit without saving state in the 752 * inode on disk which isn't feasible at this time. Best we can do is 753 * always guarantee the target exists. 754 * 755 * Basic algorithm is: 756 * 757 * 1) Bump link count on source while we're linking it to the 758 * target. This also ensure the inode won't be deleted out 759 * from underneath us while we work (it may be truncated by 760 * a concurrent `trunc' or `open' for creation). 761 * 2) Link source to destination. If destination already exists, 762 * delete it first. 763 * 3) Unlink source reference to inode if still around. If a 764 * directory was moved and the parent of the destination 765 * is different from the source, patch the ".." entry in the 766 * directory. 767 */ 768 int 769 ufs_rename(ap) 770 struct vop_rename_args *ap; 771 { 772 USES_VOP_ABORTOP; 773 USES_VOP_ACCESS; 774 USES_VOP_LOCK; 775 USES_VOP_TRUNCATE; 776 USES_VOP_UNLOCK; 777 USES_VOP_UPDATE; 778 struct vnode *tvp = ap->a_tvp; 779 register struct vnode *tdvp = ap->a_tdvp; 780 struct vnode *fvp = ap->a_fvp; 781 register struct vnode *fdvp = ap->a_fdvp; 782 register struct componentname *tcnp = ap->a_tcnp; 783 register struct componentname *fcnp = ap->a_fcnp; 784 register struct inode *ip, *xp, *dp; 785 struct dirtemplate dirbuf; 786 int doingdirectory = 0, oldparent = 0, newparent = 0; 787 int error = 0; 788 int fdvpneedsrele = 1, tdvpneedsrele = 1; 789 790 /* Check for cross-device rename */ 791 if ((fvp->v_mount != tdvp->v_mount) || 792 (tvp && (fvp->v_mount != tvp->v_mount))) { 793 VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */ 794 if (tdvp == tvp) 795 vrele(tdvp); 796 else 797 vput(tdvp); 798 if (tvp) 799 vput(tvp); 800 VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */ 801 vrele(fdvp); 802 vrele(fvp); 803 return (EXDEV); 804 } 805 806 #ifdef DIAGNOSTIC 807 if ((tcnp->cn_flags & HASBUF) == 0 || 808 (fcnp->cn_flags & HASBUF) == 0) 809 panic("ufs_rename: no name"); 810 #endif 811 dp = VTOI(fdvp); 812 ip = VTOI(fvp); 813 /* 814 * Check if just deleting a link name. 815 */ 816 if (fvp == tvp) { 817 VOP_ABORTOP(tdvp, tcnp); 818 vput(tdvp); 819 vput(tvp); 820 vrele(fdvp); 821 if ((ip->i_mode&IFMT) == IFDIR) { 822 VOP_ABORTOP(fdvp, fcnp); 823 vrele(fvp); 824 return (EINVAL); 825 } 826 doingdirectory = 0; 827 goto unlinkit; 828 } 829 ILOCK(ip); 830 if ((ip->i_mode&IFMT) == IFDIR) { 831 /* 832 * Avoid ".", "..", and aliases of "." for obvious reasons. 833 */ 834 if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') || 835 dp == ip || (fcnp->cn_flags&ISDOTDOT) || 836 (ip->i_flag & IRENAME)) { 837 VOP_ABORTOP(tdvp, tcnp); 838 vput(tdvp); 839 if (tvp) 840 vput(tvp); 841 VOP_ABORTOP(fdvp, fcnp); 842 vrele(fdvp); 843 vput(fvp); 844 return (EINVAL); 845 } 846 ip->i_flag |= IRENAME; 847 oldparent = dp->i_number; 848 doingdirectory++; 849 } 850 vrele(fdvp); 851 852 /* 853 * 1) Bump link count while we're moving stuff 854 * around. If we crash somewhere before 855 * completing our work, the link count 856 * may be wrong, but correctable. 857 */ 858 ip->i_nlink++; 859 ip->i_flag |= ICHG; 860 error = VOP_UPDATE(fvp, &time, &time, 1); 861 IUNLOCK(ip); 862 863 /* 864 * When the target exists, both the directory 865 * and target vnodes are returned locked. 866 */ 867 dp = VTOI(tdvp); 868 xp = NULL; 869 if (tvp) 870 xp = VTOI(tvp); 871 /* 872 * If ".." must be changed (ie the directory gets a new 873 * parent) then the source directory must not be in the 874 * directory heirarchy above the target, as this would 875 * orphan everything below the source directory. Also 876 * the user must have write permission in the source so 877 * as to be able to change "..". We must repeat the call 878 * to namei, as the parent directory is unlocked by the 879 * call to checkpath(). 880 */ 881 if (oldparent != dp->i_number) 882 newparent = dp->i_number; 883 if (doingdirectory && newparent) { 884 VOP_LOCK(fvp); 885 error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_proc); 886 VOP_UNLOCK(fvp); 887 if (error) 888 goto bad; 889 if (xp != NULL) 890 ufs_iput(xp); 891 if (error = ufs_checkpath(ip, dp, tcnp->cn_cred)) 892 goto out; 893 if ((tcnp->cn_flags & SAVESTART) == 0) 894 panic("ufs_rename: lost to startdir"); 895 if (error = relookup(tdvp, &tvp, tcnp)) 896 goto out; 897 dp = VTOI(tdvp); 898 xp = NULL; 899 if (tvp) 900 xp = VTOI(tvp); 901 } 902 /* 903 * 2) If target doesn't exist, link the target 904 * to the source and unlink the source. 905 * Otherwise, rewrite the target directory 906 * entry to reference the source inode and 907 * expunge the original entry's existence. 908 */ 909 if (xp == NULL) { 910 if (dp->i_dev != ip->i_dev) 911 panic("rename: EXDEV"); 912 /* 913 * Account for ".." in new directory. 914 * When source and destination have the same 915 * parent we don't fool with the link count. 916 */ 917 if (doingdirectory && newparent) { 918 if ((nlink_t)dp->i_nlink >= LINK_MAX) { 919 error = EMLINK; 920 goto bad; 921 } 922 dp->i_nlink++; 923 dp->i_flag |= ICHG; 924 if (error = VOP_UPDATE(ITOV(dp), &time, &time, 1)) 925 goto bad; 926 } 927 if (error = ufs_direnter(ip, tdvp, tcnp)) { 928 if (doingdirectory && newparent) { 929 dp->i_nlink--; 930 dp->i_flag |= ICHG; 931 (void)VOP_UPDATE(ITOV(dp), &time, &time, 1); 932 } 933 goto bad; 934 } 935 ufs_iput(dp); 936 } else { 937 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) 938 panic("rename: EXDEV"); 939 /* 940 * Short circuit rename(foo, foo). 941 */ 942 if (xp->i_number == ip->i_number) 943 panic("rename: same file"); 944 /* 945 * If the parent directory is "sticky", then the user must 946 * own the parent directory, or the destination of the rename, 947 * otherwise the destination may not be changed (except by 948 * root). This implements append-only directories. 949 */ 950 if ((dp->i_mode & ISVTX) && tcnp->cn_cred->cr_uid != 0 && 951 tcnp->cn_cred->cr_uid != dp->i_uid && 952 xp->i_uid != tcnp->cn_cred->cr_uid) { 953 error = EPERM; 954 goto bad; 955 } 956 /* 957 * Target must be empty if a directory and have no links 958 * to it. Also, ensure source and target are compatible 959 * (both directories, or both not directories). 960 */ 961 if ((xp->i_mode&IFMT) == IFDIR) { 962 if (!ufs_dirempty(xp, dp->i_number, tcnp->cn_cred) || 963 xp->i_nlink > 2) { 964 error = ENOTEMPTY; 965 goto bad; 966 } 967 if (!doingdirectory) { 968 error = ENOTDIR; 969 goto bad; 970 } 971 cache_purge(ITOV(dp)); 972 } else if (doingdirectory) { 973 error = EISDIR; 974 goto bad; 975 } 976 if (error = ufs_dirrewrite(dp, ip, tcnp)) 977 goto bad; 978 /* 979 * If the target directory is in the same 980 * directory as the source directory, 981 * decrement the link count on the parent 982 * of the target directory. 983 */ 984 if (doingdirectory && !newparent) { 985 dp->i_nlink--; 986 dp->i_flag |= ICHG; 987 } 988 ufs_iput(dp); 989 /* 990 * Adjust the link count of the target to 991 * reflect the dirrewrite above. If this is 992 * a directory it is empty and there are 993 * no links to it, so we can squash the inode and 994 * any space associated with it. We disallowed 995 * renaming over top of a directory with links to 996 * it above, as the remaining link would point to 997 * a directory without "." or ".." entries. 998 */ 999 xp->i_nlink--; 1000 if (doingdirectory) { 1001 if (--xp->i_nlink != 0) 1002 panic("rename: linked directory"); 1003 error = VOP_TRUNCATE(ITOV(xp), (off_t)0, IO_SYNC, 1004 tcnp->cn_cred); 1005 } 1006 xp->i_flag |= ICHG; 1007 ufs_iput(xp); 1008 xp = NULL; 1009 } 1010 1011 /* 1012 * 3) Unlink the source. 1013 */ 1014 unlinkit: 1015 fcnp->cn_flags &= ~MODMASK; 1016 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF; 1017 if ((fcnp->cn_flags & SAVESTART) == 0) 1018 panic("ufs_rename: lost from startdir"); 1019 (void) relookup(fdvp, &fvp, fcnp); 1020 if (fvp != NULL) { 1021 xp = VTOI(fvp); 1022 dp = VTOI(fdvp); 1023 } else { 1024 /* 1025 * From name has disappeared. 1026 */ 1027 if (doingdirectory) 1028 panic("rename: lost dir entry"); 1029 vrele(ITOV(ip)); 1030 return (0); 1031 } 1032 /* 1033 * Ensure that the directory entry still exists and has not 1034 * changed while the new name has been entered. If the source is 1035 * a file then the entry may have been unlinked or renamed. In 1036 * either case there is no further work to be done. If the source 1037 * is a directory then it cannot have been rmdir'ed; its link 1038 * count of three would cause a rmdir to fail with ENOTEMPTY. 1039 * The IRENAME flag ensures that it cannot be moved by another 1040 * rename. 1041 */ 1042 if (xp != ip) { 1043 if (doingdirectory) 1044 panic("rename: lost dir entry"); 1045 } else { 1046 /* 1047 * If the source is a directory with a 1048 * new parent, the link count of the old 1049 * parent directory must be decremented 1050 * and ".." set to point to the new parent. 1051 */ 1052 if (doingdirectory && newparent) { 1053 dp->i_nlink--; 1054 dp->i_flag |= ICHG; 1055 error = vn_rdwr(UIO_READ, ITOV(xp), (caddr_t)&dirbuf, 1056 sizeof (struct dirtemplate), (off_t)0, 1057 UIO_SYSSPACE, IO_NODELOCKED, 1058 tcnp->cn_cred, (int *)0, (struct proc *)0); 1059 if (error == 0) { 1060 if (dirbuf.dotdot_namlen != 2 || 1061 dirbuf.dotdot_name[0] != '.' || 1062 dirbuf.dotdot_name[1] != '.') { 1063 ufs_dirbad(xp, (doff_t)12, 1064 "rename: mangled dir"); 1065 } else { 1066 dirbuf.dotdot_ino = newparent; 1067 (void) vn_rdwr(UIO_WRITE, ITOV(xp), 1068 (caddr_t)&dirbuf, 1069 sizeof (struct dirtemplate), 1070 (off_t)0, UIO_SYSSPACE, 1071 IO_NODELOCKED|IO_SYNC, 1072 tcnp->cn_cred, (int *)0, 1073 (struct proc *)0); 1074 cache_purge(ITOV(dp)); 1075 } 1076 } 1077 } 1078 error = ufs_dirremove(fdvp, fcnp); 1079 if (!error) { 1080 xp->i_nlink--; 1081 xp->i_flag |= ICHG; 1082 } 1083 xp->i_flag &= ~IRENAME; 1084 } 1085 if (dp) 1086 vput(ITOV(dp)); 1087 if (xp) 1088 vput(ITOV(xp)); 1089 vrele(ITOV(ip)); 1090 return (error); 1091 1092 bad: 1093 if (xp) 1094 vput(ITOV(xp)); 1095 vput(ITOV(dp)); 1096 out: 1097 ip->i_nlink--; 1098 ip->i_flag |= ICHG; 1099 vrele(ITOV(ip)); 1100 return (error); 1101 } 1102 1103 /* 1104 * A virgin directory (no blushing please). 1105 */ 1106 static struct dirtemplate mastertemplate = { 1107 0, 12, 1, ".", 1108 0, DIRBLKSIZ - 12, 2, ".." 1109 }; 1110 1111 /* 1112 * Mkdir system call 1113 */ 1114 int 1115 ufs_mkdir(ap) 1116 struct vop_mkdir_args *ap; 1117 { 1118 USES_VOP_TRUNCATE; 1119 USES_VOP_UPDATE; 1120 USES_VOP_VALLOC; 1121 USES_VOP_VFREE; 1122 register struct vnode *dvp = ap->a_dvp; 1123 register struct vattr *vap = ap->a_vap; 1124 register struct componentname *cnp = ap->a_cnp; 1125 register struct inode *ip, *dp; 1126 struct vnode *tvp; 1127 struct dirtemplate dirtemplate; 1128 int error; 1129 int dmode; 1130 1131 #ifdef DIAGNOSTIC 1132 if ((cnp->cn_flags & HASBUF) == 0) 1133 panic("ufs_mkdir: no name"); 1134 #endif 1135 dp = VTOI(dvp); 1136 if ((nlink_t)dp->i_nlink >= LINK_MAX) { 1137 free(cnp->cn_pnbuf, M_NAMEI); 1138 ufs_iput(dp); 1139 return (EMLINK); 1140 } 1141 dmode = vap->va_mode&0777; 1142 dmode |= IFDIR; 1143 /* 1144 * Must simulate part of maknode here to acquire the inode, but 1145 * not have it entered in the parent directory. The entry is made 1146 * later after writing "." and ".." entries. 1147 */ 1148 if (error = VOP_VALLOC(dvp, dmode, cnp->cn_cred, &tvp)) { 1149 free(cnp->cn_pnbuf, M_NAMEI); 1150 ufs_iput(dp); 1151 return (error); 1152 } 1153 ip = VTOI(tvp); 1154 ip->i_uid = cnp->cn_cred->cr_uid; 1155 ip->i_gid = dp->i_gid; 1156 #ifdef QUOTA 1157 if ((error = getinoquota(ip)) || 1158 (error = chkiq(ip, 1, cnp->cn_cred, 0))) { 1159 free(cnp->cn_pnbuf, M_NAMEI); 1160 VOP_VFREE(tvp, ip->i_number, dmode); 1161 ufs_iput(ip); 1162 ufs_iput(dp); 1163 return (error); 1164 } 1165 #endif 1166 ip->i_flag |= IACC|IUPD|ICHG; 1167 ip->i_mode = dmode; 1168 ITOV(ip)->v_type = VDIR; /* Rest init'd in iget() */ 1169 ip->i_nlink = 2; 1170 error = VOP_UPDATE(ITOV(ip), &time, &time, 1); 1171 1172 /* 1173 * Bump link count in parent directory 1174 * to reflect work done below. Should 1175 * be done before reference is created 1176 * so reparation is possible if we crash. 1177 */ 1178 dp->i_nlink++; 1179 dp->i_flag |= ICHG; 1180 if (error = VOP_UPDATE(ITOV(dp), &time, &time, 1)) 1181 goto bad; 1182 1183 /* Initialize directory with "." and ".." from static template. */ 1184 dirtemplate = mastertemplate; 1185 dirtemplate.dot_ino = ip->i_number; 1186 dirtemplate.dotdot_ino = dp->i_number; 1187 error = vn_rdwr(UIO_WRITE, ITOV(ip), (caddr_t)&dirtemplate, 1188 sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE, 1189 IO_NODELOCKED|IO_SYNC, cnp->cn_cred, (int *)0, (struct proc *)0); 1190 if (error) { 1191 dp->i_nlink--; 1192 dp->i_flag |= ICHG; 1193 goto bad; 1194 } 1195 if (DIRBLKSIZ > VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_bsize) 1196 panic("ufs_mkdir: blksize"); /* XXX should grow with balloc() */ 1197 else { 1198 ip->i_size = DIRBLKSIZ; 1199 ip->i_flag |= ICHG; 1200 } 1201 1202 /* Directory set up, now install it's entry in the parent directory. */ 1203 if (error = ufs_direnter(ip, dvp, cnp)) { 1204 dp->i_nlink--; 1205 dp->i_flag |= ICHG; 1206 } 1207 bad: 1208 /* 1209 * No need to do an explicit VOP_TRUNCATE here, vrele will do this 1210 * for us because we set the link count to 0. 1211 */ 1212 if (error) { 1213 ip->i_nlink = 0; 1214 ip->i_flag |= ICHG; 1215 ufs_iput(ip); 1216 } else 1217 *ap->a_vpp = ITOV(ip); 1218 FREE(cnp->cn_pnbuf, M_NAMEI); 1219 ufs_iput(dp); 1220 return (error); 1221 } 1222 1223 /* 1224 * Rmdir system call. 1225 */ 1226 int 1227 ufs_rmdir(ap) 1228 struct vop_rmdir_args *ap; 1229 { 1230 USES_VOP_TRUNCATE; 1231 register struct vnode *dvp = ap->a_dvp; 1232 register struct componentname *cnp = ap->a_cnp; 1233 register struct inode *ip, *dp; 1234 int error; 1235 1236 ip = VTOI(ap->a_vp); 1237 dp = VTOI(dvp); 1238 /* 1239 * No rmdir "." please. 1240 */ 1241 if (dp == ip) { 1242 vrele(dvp); 1243 ufs_iput(ip); 1244 return (EINVAL); 1245 } 1246 /* 1247 * Verify the directory is empty (and valid). 1248 * (Rmdir ".." won't be valid since 1249 * ".." will contain a reference to 1250 * the current directory and thus be 1251 * non-empty.) 1252 */ 1253 error = 0; 1254 if (ip->i_nlink != 2 || 1255 !ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) { 1256 error = ENOTEMPTY; 1257 goto out; 1258 } 1259 /* 1260 * Delete reference to directory before purging 1261 * inode. If we crash in between, the directory 1262 * will be reattached to lost+found, 1263 */ 1264 if (error = ufs_dirremove(dvp, cnp)) 1265 goto out; 1266 dp->i_nlink--; 1267 dp->i_flag |= ICHG; 1268 cache_purge(dvp); 1269 ufs_iput(dp); 1270 dvp = NULL; 1271 /* 1272 * Truncate inode. The only stuff left 1273 * in the directory is "." and "..". The 1274 * "." reference is inconsequential since 1275 * we're quashing it. The ".." reference 1276 * has already been adjusted above. We've 1277 * removed the "." reference and the reference 1278 * in the parent directory, but there may be 1279 * other hard links so decrement by 2 and 1280 * worry about them later. 1281 */ 1282 ip->i_nlink -= 2; 1283 error = VOP_TRUNCATE(ap->a_vp, (off_t)0, IO_SYNC, cnp->cn_cred); 1284 cache_purge(ITOV(ip)); 1285 out: 1286 if (dvp) 1287 ufs_iput(dp); 1288 ufs_iput(ip); 1289 return (error); 1290 } 1291 1292 /* 1293 * symlink -- make a symbolic link 1294 */ 1295 int 1296 ufs_symlink(ap) 1297 struct vop_symlink_args *ap; 1298 { 1299 register struct vnode **vpp = ap->a_vpp; 1300 int error; 1301 1302 if (error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp, 1303 vpp, ap->a_cnp)) 1304 return (error); 1305 error = vn_rdwr(UIO_WRITE, *vpp, ap->a_target, strlen(ap->a_target), 1306 (off_t)0, UIO_SYSSPACE, IO_NODELOCKED, ap->a_cnp->cn_cred, 1307 (int *)0, (struct proc *)0); 1308 vput(*vpp); 1309 return (error); 1310 } 1311 1312 /* 1313 * Vnode op for reading directories. 1314 * 1315 * The routine below assumes that the on-disk format of a directory 1316 * is the same as that defined by <sys/dirent.h>. If the on-disk 1317 * format changes, then it will be necessary to do a conversion 1318 * from the on-disk format that read returns to the format defined 1319 * by <sys/dirent.h>. 1320 */ 1321 int 1322 ufs_readdir(ap) 1323 struct vop_readdir_args *ap; 1324 { 1325 USES_VOP_READ; 1326 register struct uio *uio = ap->a_uio; 1327 int count, lost, error; 1328 1329 count = uio->uio_resid; 1330 count &= ~(DIRBLKSIZ - 1); 1331 lost = uio->uio_resid - count; 1332 if (count < DIRBLKSIZ || (uio->uio_offset & (DIRBLKSIZ -1))) 1333 return (EINVAL); 1334 uio->uio_resid = count; 1335 uio->uio_iov->iov_len = count; 1336 error = VOP_READ(ap->a_vp, uio, 0, ap->a_cred); 1337 uio->uio_resid += lost; 1338 if ((VTOI(ap->a_vp)->i_size - uio->uio_offset) <= 0) 1339 *ap->a_eofflagp = 1; 1340 else 1341 *ap->a_eofflagp = 0; 1342 return (error); 1343 } 1344 1345 /* 1346 * Return target name of a symbolic link 1347 */ 1348 int 1349 ufs_readlink(ap) 1350 struct vop_readlink_args *ap; 1351 { 1352 USES_VOP_READ; 1353 1354 return (VOP_READ(ap->a_vp, ap->a_uio, 0, ap->a_cred)); 1355 } 1356 1357 /* 1358 * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually 1359 * done. If a buffer has been saved in anticipation of a CREATE, delete it. 1360 */ 1361 /* ARGSUSED */ 1362 int 1363 ufs_abortop(ap) 1364 struct vop_abortop_args *ap; 1365 { 1366 if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF) 1367 FREE(ap->a_cnp->cn_pnbuf, M_NAMEI); 1368 return (0); 1369 } 1370 1371 /* 1372 * Lock an inode. 1373 */ 1374 int 1375 ufs_lock(ap) 1376 struct vop_lock_args *ap; 1377 { 1378 register struct inode *ip = VTOI(ap->a_vp); 1379 1380 ILOCK(ip); 1381 return (0); 1382 } 1383 1384 /* 1385 * Unlock an inode. 1386 */ 1387 int 1388 ufs_unlock(ap) 1389 struct vop_unlock_args *ap; 1390 { 1391 register struct inode *ip = VTOI(ap->a_vp); 1392 1393 if (!(ip->i_flag & ILOCKED)) 1394 panic("ufs_unlock NOT LOCKED"); 1395 IUNLOCK(ip); 1396 return (0); 1397 } 1398 1399 /* 1400 * Check for a locked inode. 1401 */ 1402 int 1403 ufs_islocked(ap) 1404 struct vop_islocked_args *ap; 1405 { 1406 1407 if (VTOI(ap->a_vp)->i_flag & ILOCKED) 1408 return (1); 1409 return (0); 1410 } 1411 1412 /* 1413 * Calculate the logical to physical mapping if not done already, 1414 * then call the device strategy routine. 1415 */ 1416 int 1417 ufs_strategy(ap) 1418 struct vop_strategy_args *ap; 1419 { 1420 USES_VOP_BMAP; 1421 register struct buf *bp = ap->a_bp; 1422 register struct vnode *vp = bp->b_vp; 1423 register struct inode *ip; 1424 int error; 1425 1426 ip = VTOI(vp); 1427 if (vp->v_type == VBLK || vp->v_type == VCHR) 1428 panic("ufs_strategy: spec"); 1429 if (bp->b_blkno == bp->b_lblkno) { 1430 if (error = 1431 VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno)) { 1432 bp->b_error = error; 1433 bp->b_flags |= B_ERROR; 1434 biodone(bp); 1435 return (error); 1436 } 1437 if ((long)bp->b_blkno == -1) 1438 clrbuf(bp); 1439 } 1440 if ((long)bp->b_blkno == -1) { 1441 biodone(bp); 1442 return (0); 1443 } 1444 vp = ip->i_devvp; 1445 bp->b_dev = vp->v_rdev; 1446 VOCALL (vp->v_op, VOFFSET(vop_strategy), ap); 1447 return (0); 1448 } 1449 1450 /* 1451 * Print out the contents of an inode. 1452 */ 1453 int 1454 ufs_print(ap) 1455 struct vop_print_args *ap; 1456 { 1457 register struct vnode *vp = ap->a_vp; 1458 register struct inode *ip = VTOI(vp); 1459 1460 printf("tag VT_UFS, ino %d, on dev %d, %d", ip->i_number, 1461 major(ip->i_dev), minor(ip->i_dev)); 1462 #ifdef FIFO 1463 if (vp->v_type == VFIFO) 1464 fifo_printinfo(vp); 1465 #endif /* FIFO */ 1466 printf("%s\n", (ip->i_flag & ILOCKED) ? " (LOCKED)" : ""); 1467 if (ip->i_lockholder == 0) 1468 return (0); 1469 printf("\towner pid %d", ip->i_lockholder); 1470 if (ip->i_lockwaiter) 1471 printf(" waiting pid %d", ip->i_lockwaiter); 1472 printf("\n"); 1473 return (0); 1474 } 1475 1476 /* 1477 * Read wrapper for special devices. 1478 */ 1479 int 1480 ufsspec_read(ap) 1481 struct vop_read_args *ap; 1482 { 1483 extern int (**spec_vnodeop_p)(); 1484 1485 /* 1486 * Set access flag. 1487 */ 1488 VTOI(ap->a_vp)->i_flag |= IACC; 1489 return (VOCALL (spec_vnodeop_p, VOFFSET(vop_read), ap)); 1490 } 1491 1492 /* 1493 * Write wrapper for special devices. 1494 */ 1495 int 1496 ufsspec_write(ap) 1497 struct vop_write_args *ap; 1498 { 1499 extern int (**spec_vnodeop_p)(); 1500 1501 /* 1502 * Set update and change flags. 1503 */ 1504 VTOI(ap->a_vp)->i_flag |= IUPD|ICHG; 1505 return (VOCALL (spec_vnodeop_p, VOFFSET(vop_write), ap)); 1506 } 1507 1508 /* 1509 * Close wrapper for special devices. 1510 * 1511 * Update the times on the inode then do device close. 1512 */ 1513 int 1514 ufsspec_close(ap) 1515 struct vop_close_args *ap; 1516 { 1517 extern int (**spec_vnodeop_p)(); 1518 register struct inode *ip = VTOI(ap->a_vp); 1519 1520 if (ap->a_vp->v_usecount > 1 && !(ip->i_flag & ILOCKED)) 1521 ITIMES(ip, &time, &time); 1522 return (VOCALL (spec_vnodeop_p, VOFFSET(vop_close), ap)); 1523 } 1524 1525 #ifdef FIFO 1526 /* 1527 * Read wrapper for fifo's 1528 */ 1529 int 1530 ufsfifo_read(ap) 1531 struct vop_read_args *ap; 1532 { 1533 extern int (**fifo_vnodeop_p)(); 1534 1535 /* 1536 * Set access flag. 1537 */ 1538 VTOI(ap->a_vp)->i_flag |= IACC; 1539 return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_read), ap)); 1540 } 1541 1542 /* 1543 * Write wrapper for fifo's. 1544 */ 1545 int 1546 ufsfifo_write(ap) 1547 struct vop_write_args *ap; 1548 { 1549 extern int (**fifo_vnodeop_p)(); 1550 1551 /* 1552 * Set update and change flags. 1553 */ 1554 VTOI(ap->a_vp)->i_flag |= IUPD|ICHG; 1555 return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_write), ap)); 1556 } 1557 1558 /* 1559 * Close wrapper for fifo's. 1560 * 1561 * Update the times on the inode then do device close. 1562 */ 1563 ufsfifo_close(ap) 1564 struct vop_close_args *ap; 1565 { 1566 extern int (**fifo_vnodeop_p)(); 1567 register struct inode *ip = VTOI(ap->a_vp); 1568 1569 if (ap->a_vp->v_usecount > 1 && !(ip->i_flag & ILOCKED)) 1570 ITIMES(ip, &time, &time); 1571 return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_close), ap)); 1572 } 1573 #endif /* FIFO */ 1574 1575 /* 1576 * Advisory record locking support 1577 */ 1578 int 1579 ufs_advlock(ap) 1580 struct vop_advlock_args *ap; 1581 { 1582 register struct inode *ip = VTOI(ap->a_vp); 1583 register struct flock *fl = ap->a_fl; 1584 register struct lockf *lock; 1585 off_t start, end; 1586 int error; 1587 1588 /* 1589 * Avoid the common case of unlocking when inode has no locks. 1590 */ 1591 if (ip->i_lockf == (struct lockf *)0) { 1592 if (ap->a_op != F_SETLK) { 1593 fl->l_type = F_UNLCK; 1594 return (0); 1595 } 1596 } 1597 /* 1598 * Convert the flock structure into a start and end. 1599 */ 1600 switch (fl->l_whence) { 1601 1602 case SEEK_SET: 1603 case SEEK_CUR: 1604 /* 1605 * Caller is responsible for adding any necessary offset 1606 * when SEEK_CUR is used. 1607 */ 1608 start = fl->l_start; 1609 break; 1610 1611 case SEEK_END: 1612 start = ip->i_size + fl->l_start; 1613 break; 1614 1615 default: 1616 return (EINVAL); 1617 } 1618 if (start < 0) 1619 return (EINVAL); 1620 if (fl->l_len == 0) 1621 end = -1; 1622 else 1623 end = start + fl->l_len - 1; 1624 /* 1625 * Create the lockf structure 1626 */ 1627 MALLOC(lock, struct lockf *, sizeof *lock, M_LOCKF, M_WAITOK); 1628 lock->lf_start = start; 1629 lock->lf_end = end; 1630 lock->lf_id = ap->a_id; 1631 lock->lf_inode = ip; 1632 lock->lf_type = fl->l_type; 1633 lock->lf_next = (struct lockf *)0; 1634 lock->lf_block = (struct lockf *)0; 1635 lock->lf_flags = ap->a_flags; 1636 /* 1637 * Do the requested operation. 1638 */ 1639 switch(ap->a_op) { 1640 case F_SETLK: 1641 return (lf_setlock(lock)); 1642 1643 case F_UNLCK: 1644 error = lf_clearlock(lock); 1645 FREE(lock, M_LOCKF); 1646 return (error); 1647 1648 case F_GETLK: 1649 error = lf_getlock(lock, fl); 1650 FREE(lock, M_LOCKF); 1651 return (error); 1652 1653 default: 1654 free(lock, M_LOCKF); 1655 return (EINVAL); 1656 } 1657 /* NOTREACHED */ 1658 } 1659 1660 /* 1661 * Initialize the vnode associated with a new inode, handle aliased 1662 * vnodes. 1663 */ 1664 int 1665 ufs_vinit(mntp, specops, fifoops, vpp) 1666 struct mount *mntp; 1667 int (**specops)(); 1668 int (**fifoops)(); 1669 struct vnode **vpp; 1670 { 1671 struct inode *ip, *nip; 1672 struct vnode *vp, *nvp; 1673 extern int (**spec_vnodeop_p)(); 1674 1675 vp = *vpp; 1676 ip = VTOI(vp); 1677 switch(vp->v_type = IFTOVT(ip->i_mode)) { 1678 case VCHR: 1679 case VBLK: 1680 vp->v_op = specops; 1681 if (nvp = checkalias(vp, ip->i_rdev, mntp)) { 1682 /* 1683 * Discard unneeded vnode, but save its inode. 1684 */ 1685 remque(ip); 1686 IUNLOCK(ip); 1687 nvp->v_data = vp->v_data; 1688 vp->v_data = NULL; 1689 vp->v_op = spec_vnodeop_p; 1690 vrele(vp); 1691 vgone(vp); 1692 /* 1693 * Reinitialize aliased inode. 1694 */ 1695 vp = nvp; 1696 ip->i_vnode = vp; 1697 ufs_ihashins(ip); 1698 } 1699 break; 1700 case VFIFO: 1701 #ifdef FIFO 1702 vp->v_op = fifoops; 1703 break; 1704 #else 1705 return (EOPNOTSUPP); 1706 #endif 1707 } 1708 if (ip->i_number == ROOTINO) 1709 vp->v_flag |= VROOT; 1710 /* 1711 * Initialize modrev times 1712 */ 1713 SETHIGH(ip->i_modrev, mono_time.tv_sec); 1714 SETLOW(ip->i_modrev, mono_time.tv_usec * 4294); 1715 *vpp = vp; 1716 return (0); 1717 } 1718 1719 /* 1720 * Allocate a new inode. 1721 */ 1722 int 1723 ufs_makeinode(mode, dvp, vpp, cnp) 1724 int mode; 1725 struct vnode *dvp; 1726 struct vnode **vpp; 1727 struct componentname *cnp; 1728 { 1729 USES_VOP_UPDATE; 1730 USES_VOP_VALLOC; 1731 USES_VOP_VFREE; 1732 register struct inode *ip, *pdir; 1733 struct vnode *tvp; 1734 int error; 1735 1736 pdir = VTOI(dvp); 1737 #ifdef DIAGNOSTIC 1738 if ((cnp->cn_flags & HASBUF) == 0) 1739 panic("ufs_makeinode: no name"); 1740 #endif 1741 *vpp = NULL; 1742 if ((mode & IFMT) == 0) 1743 mode |= IFREG; 1744 1745 if (error = VOP_VALLOC(dvp, mode, cnp->cn_cred, &tvp)) { 1746 free(cnp->cn_pnbuf, M_NAMEI); 1747 ufs_iput(pdir); 1748 return (error); 1749 } 1750 ip = VTOI(tvp); 1751 ip->i_uid = cnp->cn_cred->cr_uid; 1752 ip->i_gid = pdir->i_gid; 1753 #ifdef QUOTA 1754 if ((error = getinoquota(ip)) || 1755 (error = chkiq(ip, 1, cnp->cn_cred, 0))) { 1756 free(cnp->cn_pnbuf, M_NAMEI); 1757 VOP_VFREE(tvp, ip->i_number, mode); 1758 ufs_iput(ip); 1759 ufs_iput(pdir); 1760 return (error); 1761 } 1762 #endif 1763 ip->i_flag |= IACC|IUPD|ICHG; 1764 ip->i_mode = mode; 1765 tvp->v_type = IFTOVT(mode); /* Rest init'd in iget() */ 1766 ip->i_nlink = 1; 1767 if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) && 1768 suser(cnp->cn_cred, NULL)) 1769 ip->i_mode &= ~ISGID; 1770 1771 /* 1772 * Make sure inode goes to disk before directory entry. 1773 */ 1774 if (error = VOP_UPDATE(tvp, &time, &time, 1)) 1775 goto bad; 1776 if (error = ufs_direnter(ip, dvp, cnp)) 1777 goto bad; 1778 if ((cnp->cn_flags & SAVESTART) == 0) 1779 FREE(cnp->cn_pnbuf, M_NAMEI); 1780 ufs_iput(pdir); 1781 *vpp = tvp; 1782 return (0); 1783 1784 bad: 1785 /* 1786 * Write error occurred trying to update the inode 1787 * or the directory so must deallocate the inode. 1788 */ 1789 free(cnp->cn_pnbuf, M_NAMEI); 1790 ufs_iput(pdir); 1791 ip->i_nlink = 0; 1792 ip->i_flag |= ICHG; 1793 ufs_iput(ip); 1794 return (error); 1795 } 1796