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