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