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