1 /* ufs_vnops.c 4.60 83/06/12 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/dir.h" 6 #include "../h/user.h" 7 #include "../h/kernel.h" 8 #include "../h/file.h" 9 #include "../h/stat.h" 10 #include "../h/inode.h" 11 #include "../h/fs.h" 12 #include "../h/buf.h" 13 #include "../h/proc.h" 14 #include "../h/quota.h" 15 #include "../h/uio.h" 16 #include "../h/socket.h" 17 #include "../h/socketvar.h" 18 #include "../h/nami.h" 19 #include "../h/mount.h" 20 21 extern struct fileops inodeops; 22 struct file *getinode(); 23 24 /* 25 * Change current working directory (``.''). 26 */ 27 chdir() 28 { 29 30 chdirec(&u.u_cdir); 31 } 32 33 /* 34 * Change notion of root (``/'') directory. 35 */ 36 chroot() 37 { 38 39 if (suser()) 40 chdirec(&u.u_rdir); 41 } 42 43 /* 44 * Common routine for chroot and chdir. 45 */ 46 chdirec(ipp) 47 register struct inode **ipp; 48 { 49 register struct inode *ip; 50 struct a { 51 char *fname; 52 }; 53 54 ip = namei(uchar, LOOKUP, 1); 55 if (ip == NULL) 56 return; 57 if ((ip->i_mode&IFMT) != IFDIR) { 58 u.u_error = ENOTDIR; 59 goto bad; 60 } 61 if (access(ip, IEXEC)) 62 goto bad; 63 iunlock(ip); 64 if (*ipp) 65 irele(*ipp); 66 *ipp = ip; 67 return; 68 69 bad: 70 iput(ip); 71 } 72 73 /* 74 * Open system call. 75 */ 76 open() 77 { 78 struct a { 79 char *fname; 80 int mode; 81 int crtmode; 82 } *uap = (struct a *) u.u_ap; 83 84 copen(uap->mode-FOPEN, uap->crtmode); 85 } 86 87 /* 88 * Creat system call. 89 */ 90 creat() 91 { 92 struct a { 93 char *fname; 94 int fmode; 95 } *uap = (struct a *)u.u_ap; 96 97 copen(FWRITE|FCREAT|FTRUNC, uap->fmode); 98 } 99 100 /* 101 * Common code for open and creat. 102 * Check permissions, allocate an open file structure, 103 * and call the device open routine if any. 104 */ 105 copen(mode, arg) 106 register int mode; 107 int arg; 108 { 109 register struct inode *ip; 110 register struct file *fp; 111 int i; 112 113 #ifdef notdef 114 if ((mode&(FREAD|FWRITE)) == 0) { 115 u.u_error = EINVAL; 116 return; 117 } 118 #endif 119 if (mode&FCREAT) { 120 ip = namei(uchar, CREATE, 1); 121 if (ip == NULL) { 122 if (u.u_error) 123 return; 124 ip = maknode(arg&07777&(~ISVTX)); 125 if (ip == NULL) 126 return; 127 mode &= ~FTRUNC; 128 } else { 129 if (mode&FEXCL) { 130 u.u_error = EEXIST; 131 iput(ip); 132 return; 133 } 134 mode &= ~FCREAT; 135 } 136 } else { 137 ip = namei(uchar, LOOKUP, 1); 138 if (ip == NULL) 139 return; 140 } 141 if ((ip->i_mode & IFMT) == IFSOCK) { 142 u.u_error = EOPNOTSUPP; 143 goto bad; 144 } 145 if ((mode&FCREAT) == 0) { 146 if (mode&FREAD) 147 if (access(ip, IREAD)) 148 goto bad; 149 if (mode&FWRITE) { 150 if (access(ip, IWRITE)) 151 goto bad; 152 if ((ip->i_mode&IFMT) == IFDIR) { 153 u.u_error = EISDIR; 154 goto bad; 155 } 156 } 157 } 158 fp = falloc(); 159 if (fp == NULL) 160 goto bad; 161 if (mode&FTRUNC) 162 itrunc(ip, (u_long)0); 163 iunlock(ip); 164 fp->f_flag = mode&FMASK; 165 fp->f_type = DTYPE_INODE; 166 fp->f_ops = &inodeops; 167 fp->f_data = (caddr_t)ip; 168 i = u.u_r.r_val1; 169 #ifdef notdef 170 if (setjmp(&u.u_qsave)) { 171 if (u.u_error == 0) 172 u.u_error = EINTR; 173 u.u_ofile[i] = NULL; 174 closef(fp); 175 return; 176 } 177 #endif 178 u.u_error = openi(ip, mode); 179 if (u.u_error == 0) 180 return; 181 u.u_ofile[i] = NULL; 182 fp->f_count--; 183 irele(ip); 184 return; 185 bad: 186 iput(ip); 187 } 188 189 /* 190 * Mknod system call 191 */ 192 mknod() 193 { 194 register struct inode *ip; 195 register struct a { 196 char *fname; 197 int fmode; 198 int dev; 199 } *uap; 200 201 uap = (struct a *)u.u_ap; 202 if (!suser()) 203 return; 204 ip = namei(uchar, CREATE, 0); 205 if (ip != NULL) { 206 u.u_error = EEXIST; 207 goto out; 208 } 209 if (u.u_error) 210 return; 211 ip = maknode(uap->fmode); 212 if (ip == NULL) 213 return; 214 switch (ip->i_mode & IFMT) { 215 216 case IFCHR: 217 case IFBLK: 218 if (uap->dev) { 219 /* 220 * Want to be able to use this to make badblock 221 * inodes, so don't truncate the dev number. 222 */ 223 ip->i_rdev = uap->dev; 224 ip->i_flag |= IACC|IUPD|ICHG; 225 } 226 } 227 228 out: 229 iput(ip); 230 } 231 232 /* 233 * link system call 234 */ 235 link() 236 { 237 register struct inode *ip, *xp; 238 register struct a { 239 char *target; 240 char *linkname; 241 } *uap; 242 243 uap = (struct a *)u.u_ap; 244 ip = namei(uchar, LOOKUP, 1); /* well, this routine is doomed anyhow */ 245 if (ip == NULL) 246 return; 247 if ((ip->i_mode&IFMT) == IFDIR && !suser()) { 248 iput(ip); 249 return; 250 } 251 ip->i_nlink++; 252 ip->i_flag |= ICHG; 253 iupdat(ip, &time, &time, 1); 254 iunlock(ip); 255 u.u_dirp = (caddr_t)uap->linkname; 256 xp = namei(uchar, CREATE, 0); 257 if (xp != NULL) { 258 u.u_error = EEXIST; 259 iput(xp); 260 goto out; 261 } 262 if (u.u_error) 263 goto out; 264 if (u.u_pdir->i_dev != ip->i_dev) { 265 iput(u.u_pdir); 266 u.u_error = EXDEV; 267 goto out; 268 } 269 u.u_error = direnter(ip); 270 out: 271 if (u.u_error) { 272 ip->i_nlink--; 273 ip->i_flag |= ICHG; 274 } 275 irele(ip); 276 } 277 278 /* 279 * symlink -- make a symbolic link 280 */ 281 symlink() 282 { 283 register struct a { 284 char *target; 285 char *linkname; 286 } *uap; 287 register struct inode *ip; 288 register char *tp; 289 register c, nc; 290 291 uap = (struct a *)u.u_ap; 292 tp = uap->target; 293 nc = 0; 294 while (c = fubyte(tp)) { 295 if (c < 0) { 296 u.u_error = EFAULT; 297 return; 298 } 299 tp++; 300 nc++; 301 } 302 u.u_dirp = uap->linkname; 303 ip = namei(uchar, CREATE, 0); 304 if (ip) { 305 iput(ip); 306 u.u_error = EEXIST; 307 return; 308 } 309 if (u.u_error) 310 return; 311 ip = maknode(IFLNK | 0777); 312 if (ip == NULL) 313 return; 314 u.u_error = rdwri(UIO_WRITE, ip, uap->target, nc, 0, 0, (int *)0); 315 /* handle u.u_error != 0 */ 316 iput(ip); 317 } 318 319 /* 320 * Unlink system call. 321 * Hard to avoid races here, especially 322 * in unlinking directories. 323 */ 324 unlink() 325 { 326 struct a { 327 char *fname; 328 }; 329 register struct inode *ip, *dp; 330 331 ip = namei(uchar, DELETE | LOCKPARENT, 0); 332 if (ip == NULL) 333 return; 334 dp = u.u_pdir; 335 if ((ip->i_mode&IFMT) == IFDIR && !suser()) 336 goto out; 337 /* 338 * Don't unlink a mounted file. 339 */ 340 if (ip->i_dev != dp->i_dev) { 341 u.u_error = EBUSY; 342 goto out; 343 } 344 if (ip->i_flag&ITEXT) 345 xrele(ip); /* try once to free text */ 346 if (dirremove()) { 347 ip->i_nlink--; 348 ip->i_flag |= ICHG; 349 } 350 out: 351 if (dp == ip) 352 irele(ip); 353 else 354 iput(ip); 355 iput(dp); 356 } 357 358 /* 359 * Seek system call 360 */ 361 lseek() 362 { 363 register struct file *fp; 364 register struct a { 365 int fd; 366 off_t off; 367 int sbase; 368 } *uap; 369 370 uap = (struct a *)u.u_ap; 371 fp = getinode(uap->fd); 372 if (fp == NULL) 373 return; 374 if (uap->sbase == L_INCR) 375 uap->off += fp->f_offset; 376 else if (uap->sbase == L_XTND) 377 uap->off += ((struct inode *)fp->f_data)->i_size; 378 fp->f_offset = uap->off; 379 u.u_r.r_off = uap->off; 380 } 381 382 /* 383 * Access system call 384 */ 385 saccess() 386 { 387 register svuid, svgid; 388 register struct inode *ip; 389 register struct a { 390 char *fname; 391 int fmode; 392 } *uap; 393 394 uap = (struct a *)u.u_ap; 395 svuid = u.u_uid; 396 svgid = u.u_gid; 397 u.u_uid = u.u_ruid; 398 u.u_gid = u.u_rgid; 399 ip = namei(uchar, LOOKUP, 1); 400 if (ip != NULL) { 401 if ((uap->fmode&R_OK) && access(ip, IREAD)) 402 goto done; 403 if ((uap->fmode&W_OK) && access(ip, IWRITE)) 404 goto done; 405 if ((uap->fmode&X_OK) && access(ip, IEXEC)) 406 goto done; 407 done: 408 iput(ip); 409 } 410 u.u_uid = svuid; 411 u.u_gid = svgid; 412 } 413 414 /* 415 * Stat system call. This version follows links. 416 */ 417 stat() 418 { 419 420 stat1(1); 421 } 422 423 /* 424 * Lstat system call. This version does not follow links. 425 */ 426 lstat() 427 { 428 429 stat1(0); 430 } 431 432 stat1(follow) 433 int follow; 434 { 435 register struct inode *ip; 436 register struct a { 437 char *fname; 438 struct stat *ub; 439 } *uap; 440 struct stat sb; 441 442 uap = (struct a *)u.u_ap; 443 ip = namei(uchar, LOOKUP, follow); 444 if (ip == NULL) 445 return; 446 (void) ino_stat(ip, &sb); 447 iput(ip); 448 u.u_error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb)); 449 } 450 451 /* 452 * Return target name of a symbolic link 453 */ 454 readlink() 455 { 456 register struct inode *ip; 457 register struct a { 458 char *name; 459 char *buf; 460 int count; 461 } *uap = (struct a *)u.u_ap; 462 int resid; 463 464 ip = namei(uchar, LOOKUP, 0); 465 if (ip == NULL) 466 return; 467 if ((ip->i_mode&IFMT) != IFLNK) { 468 u.u_error = ENXIO; 469 goto out; 470 } 471 u.u_error = rdwri(UIO_READ, ip, uap->buf, uap->count, 0, 0, &resid); 472 out: 473 iput(ip); 474 u.u_r.r_val1 = uap->count - resid; 475 } 476 477 /* 478 * Change mode of a file given path name. 479 */ 480 chmod() 481 { 482 struct inode *ip; 483 struct a { 484 char *fname; 485 int fmode; 486 } *uap; 487 488 uap = (struct a *)u.u_ap; 489 if ((ip = owner(1)) == NULL) 490 return; 491 chmod1(ip, uap->fmode); 492 iput(ip); 493 } 494 495 /* 496 * Change mode of a file given a file descriptor. 497 */ 498 fchmod() 499 { 500 struct a { 501 int fd; 502 int fmode; 503 } *uap; 504 register struct inode *ip; 505 register struct file *fp; 506 507 uap = (struct a *)u.u_ap; 508 fp = getinode(uap->fd); 509 if (fp == NULL) 510 return; 511 ip = (struct inode *)fp->f_data; 512 if (u.u_uid != ip->i_uid && !suser()) 513 return; 514 ilock(ip); 515 chmod1(ip, uap->fmode); 516 iunlock(ip); 517 } 518 519 /* 520 * Change the mode on a file. 521 * Inode must be locked before calling. 522 */ 523 chmod1(ip, mode) 524 register struct inode *ip; 525 register int mode; 526 { 527 528 ip->i_mode &= ~07777; 529 if (u.u_uid) { 530 mode &= ~ISVTX; 531 if (!groupmember(ip->i_gid)) 532 mode &= ~ISGID; 533 } 534 ip->i_mode |= mode&07777; 535 ip->i_flag |= ICHG; 536 if (ip->i_flag&ITEXT && (ip->i_mode&ISVTX)==0) 537 xrele(ip); 538 } 539 540 /* 541 * Set ownership given a path name. 542 */ 543 chown() 544 { 545 struct inode *ip; 546 struct a { 547 char *fname; 548 int uid; 549 int gid; 550 } *uap; 551 552 uap = (struct a *)u.u_ap; 553 if (!suser() || (ip = owner(0)) == NULL) 554 return; 555 u.u_error = chown1(ip, uap->uid, uap->gid); 556 iput(ip); 557 } 558 559 /* 560 * Set ownership given a file descriptor. 561 */ 562 fchown() 563 { 564 struct a { 565 int fd; 566 int uid; 567 int gid; 568 } *uap; 569 register struct inode *ip; 570 register struct file *fp; 571 572 uap = (struct a *)u.u_ap; 573 fp = getinode(uap->fd); 574 if (fp == NULL) 575 return; 576 ip = (struct inode *)fp->f_data; 577 if (!suser()) 578 return; 579 ilock(ip); 580 u.u_error = chown1(ip, uap->uid, uap->gid); 581 iunlock(ip); 582 } 583 584 /* 585 * Perform chown operation on inode ip; 586 * inode must be locked prior to call. 587 */ 588 chown1(ip, uid, gid) 589 register struct inode *ip; 590 int uid, gid; 591 { 592 #ifdef QUOTA 593 register long change; 594 #endif 595 596 if (uid == -1) 597 uid = ip->i_uid; 598 if (gid == -1) 599 gid = ip->i_gid; 600 #ifdef QUOTA 601 if (ip->i_uid != uid) /* this just speeds things a little */ 602 change = 0; 603 else 604 change = ip->i_blocks; 605 (void) chkdq(ip, -change, 1); 606 (void) chkiq(ip->i_dev, ip, ip->i_uid, 1); 607 dqrele(ip->i_dquot); 608 #endif 609 ip->i_uid = uid; 610 ip->i_gid = gid; 611 ip->i_flag |= ICHG; 612 if (u.u_ruid != 0) 613 ip->i_mode &= ~(ISUID|ISGID); 614 #ifdef QUOTA 615 ip->i_dquot = inoquota(ip); 616 (void) chkdq(ip, change, 1); 617 (void) chkiq(ip->i_dev, (struct inode *)NULL, uid, 1); 618 return (u.u_error); /* should == 0 ALWAYS !! */ 619 #else 620 return (0); 621 #endif 622 } 623 624 utimes() 625 { 626 register struct a { 627 char *fname; 628 struct timeval *tptr; 629 } *uap = (struct a *)u.u_ap; 630 register struct inode *ip; 631 struct timeval tv[2]; 632 633 if ((ip = owner(1)) == NULL) 634 return; 635 u.u_error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)); 636 if (u.u_error == 0) { 637 ip->i_flag |= IACC|IUPD|ICHG; 638 iupdat(ip, &tv[0], &tv[1], 0); 639 } 640 iput(ip); 641 } 642 643 /* 644 * Flush any pending I/O. 645 */ 646 sync() 647 { 648 649 update(); 650 } 651 652 /* 653 * Truncate a file given its path name. 654 */ 655 truncate() 656 { 657 struct a { 658 char *fname; 659 u_long length; 660 } *uap = (struct a *)u.u_ap; 661 struct inode *ip; 662 663 ip = namei(uchar, LOOKUP, 1); 664 if (ip == NULL) 665 return; 666 if (access(ip, IWRITE)) 667 goto bad; 668 if ((ip->i_mode&IFMT) == IFDIR) { 669 u.u_error = EISDIR; 670 goto bad; 671 } 672 itrunc(ip, uap->length); 673 bad: 674 iput(ip); 675 } 676 677 /* 678 * Truncate a file given a file descriptor. 679 */ 680 ftruncate() 681 { 682 struct a { 683 int fd; 684 u_long length; 685 } *uap = (struct a *)u.u_ap; 686 struct inode *ip; 687 struct file *fp; 688 689 fp = getinode(uap->fd); 690 if (fp == NULL) 691 return; 692 if ((fp->f_flag&FWRITE) == 0) { 693 u.u_error = EINVAL; 694 return; 695 } 696 ip = (struct inode *)fp->f_data; 697 ilock(ip); 698 itrunc(ip, uap->length); 699 iunlock(ip); 700 } 701 702 /* 703 * Synch an open file. 704 */ 705 fsync() 706 { 707 struct a { 708 int fd; 709 } *uap = (struct a *)u.u_ap; 710 struct inode *ip; 711 struct file *fp; 712 713 fp = getinode(uap->fd); 714 if (fp == NULL) 715 return; 716 ip = (struct inode *)fp->f_data; 717 ilock(ip); 718 syncip(ip); 719 iunlock(ip); 720 } 721 722 /* 723 * Rename system call. 724 * rename("foo", "bar"); 725 * is essentially 726 * unlink("bar"); 727 * link("foo", "bar"); 728 * unlink("foo"); 729 * but ``atomically''. Can't do full commit without saving state in the 730 * inode on disk which isn't feasible at this time. Best we can do is 731 * always guarantee the target exists. 732 * 733 * Basic algorithm is: 734 * 735 * 1) Bump link count on source while we're linking it to the 736 * target. This also insure the inode won't be deleted out 737 * from underneath us while we work. 738 * 2) Link source to destination. If destination already exists, 739 * delete it first. 740 * 3) Unlink source reference to inode if still around. 741 * 4) If a directory was moved and the parent of the destination 742 * is different from the source, patch the ".." entry in the 743 * directory. 744 * 745 * Source and destination must either both be directories, or both 746 * not be directories. If target is a directory, it must be empty. 747 */ 748 rename() 749 { 750 struct a { 751 char *from; 752 char *to; 753 } *uap; 754 register struct inode *ip, *xp, *dp; 755 int oldparent, parentdifferent, doingdirectory; 756 int error = 0; 757 758 uap = (struct a *)u.u_ap; 759 ip = namei(uchar, DELETE | LOCKPARENT, 0); 760 if (ip == NULL) 761 return; 762 dp = u.u_pdir; 763 oldparent = 0, doingdirectory = 0; 764 if ((ip->i_mode&IFMT) == IFDIR) { 765 register struct direct *d; 766 767 d = &u.u_dent; 768 /* 769 * Avoid ".", "..", and aliases of "." for obvious reasons. 770 */ 771 if ((d->d_namlen == 1 && d->d_name[0] == '.') || 772 (d->d_namlen == 2 && bcmp(d->d_name, "..", 2) == 0) || 773 (dp == ip)) { 774 iput(dp); 775 if (dp == ip) 776 irele(ip); 777 else 778 iput(ip); 779 u.u_error = EINVAL; 780 return; 781 } 782 oldparent = dp->i_number; 783 doingdirectory++; 784 } 785 iput(dp); 786 787 /* 788 * 1) Bump link count while we're moving stuff 789 * around. If we crash somewhere before 790 * completing our work, the link count 791 * may be wrong, but correctable. 792 */ 793 ip->i_nlink++; 794 ip->i_flag |= ICHG; 795 iupdat(ip, &time, &time, 1); 796 iunlock(ip); 797 798 /* 799 * When the target exists, both the directory 800 * and target inodes are returned locked. 801 */ 802 u.u_dirp = (caddr_t)uap->to; 803 xp = namei(uchar, CREATE | LOCKPARENT, 0); 804 if (u.u_error) { 805 error = u.u_error; 806 goto out; 807 } 808 dp = u.u_pdir; 809 /* 810 * If ".." must be changed (ie the directory gets a new 811 * parent) then the source directory must not be in the 812 * directory heirarchy above the target, as this would 813 * orphan everything below the source directory. Also 814 * the user must have write permission in the source so 815 * as to be able to change "..". We must repeat the call 816 * to namei, as the parent directory is unlocked by the 817 * call to checkpath(). 818 */ 819 parentdifferent = oldparent != dp->i_number; 820 if (doingdirectory && parentdifferent) { 821 if (access(ip, IWRITE)) 822 goto bad; 823 do { 824 dp = u.u_pdir; 825 if (xp != NULL) 826 iput(xp); 827 u.u_error = checkpath(ip, dp); 828 if (u.u_error) 829 goto out; 830 u.u_dirp = (caddr_t)uap->to; 831 xp = namei(uchar, CREATE | LOCKPARENT, 0); 832 if (u.u_error) { 833 error = u.u_error; 834 goto out; 835 } 836 } while (dp != u.u_pdir); 837 } 838 /* 839 * 2) If target doesn't exist, link the target 840 * to the source and unlink the source. 841 * Otherwise, rewrite the target directory 842 * entry to reference the source inode and 843 * expunge the original entry's existence. 844 */ 845 if (xp == NULL) { 846 if (dp->i_dev != ip->i_dev) { 847 error = EXDEV; 848 goto bad; 849 } 850 /* 851 * Account for ".." in directory. 852 * When source and destination have the 853 * same parent we don't fool with the 854 * link count -- this isn't required 855 * because we do a similar check below. 856 */ 857 if (doingdirectory && parentdifferent) { 858 dp->i_nlink++; 859 dp->i_flag |= ICHG; 860 iupdat(dp, &time, &time, 1); 861 } 862 error = direnter(ip); 863 if (error) 864 goto out; 865 } else { 866 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) { 867 error = EXDEV; 868 goto bad; 869 } 870 /* 871 * Short circuit rename(foo, foo). 872 */ 873 if (xp->i_number == ip->i_number) 874 goto bad; 875 /* 876 * Target must be empty if a directory 877 * and have no links to it. 878 * Also, insure source and target are 879 * compatible (both directories, or both 880 * not directories). 881 */ 882 if ((xp->i_mode&IFMT) == IFDIR) { 883 if (!dirempty(xp) || xp->i_nlink > 2) { 884 error = ENOTEMPTY; 885 goto bad; 886 } 887 if (!doingdirectory) { 888 error = ENOTDIR; 889 goto bad; 890 } 891 } else if (doingdirectory) { 892 error = EISDIR; 893 goto bad; 894 } 895 dirrewrite(dp, ip); 896 if (u.u_error) { 897 error = u.u_error; 898 goto bad1; 899 } 900 /* 901 * Adjust the link count of the target to 902 * reflect the dirrewrite above. If this is 903 * a directory it is empty and there are 904 * no links to it, so we can squash the inode and 905 * any space associated with it. We disallowed 906 * renaming over top of a directory with links to 907 * it above, as we've no way to determine if 908 * we've got a link or the directory itself, and 909 * if we get a link, then ".." will be screwed up. 910 */ 911 xp->i_nlink--; 912 if (doingdirectory) { 913 if (--xp->i_nlink != 0) 914 panic("rename: linked directory"); 915 itrunc(xp, (u_long)0); 916 } 917 xp->i_flag |= ICHG; 918 iput(xp); 919 xp = NULL; 920 } 921 922 /* 923 * 3) Unlink the source. 924 */ 925 u.u_dirp = uap->from; 926 dp = namei(uchar, DELETE, 0); 927 /* 928 * Insure directory entry still exists and 929 * has not changed since the start of all 930 * this. If either has occured, forget about 931 * about deleting the original entry and just 932 * adjust the link count in the inode. 933 */ 934 if (dp == NULL || u.u_dent.d_ino != ip->i_number) { 935 ip->i_nlink--; 936 ip->i_flag |= ICHG; 937 } else { 938 /* 939 * If source is a directory, must adjust 940 * link count of parent directory also. 941 * If target didn't exist and source and 942 * target have the same parent, then we 943 * needn't touch the link count, it all 944 * balances out in the end. Otherwise, we 945 * must do so to reflect deletion of ".." 946 * done above. 947 */ 948 if (doingdirectory && (xp != NULL || parentdifferent)) { 949 dp->i_nlink--; 950 dp->i_flag |= ICHG; 951 } 952 if (dirremove()) { 953 ip->i_nlink--; 954 ip->i_flag |= ICHG; 955 } 956 if (error == 0) /* conservative */ 957 error = u.u_error; 958 } 959 irele(ip); 960 if (dp) 961 iput(dp); 962 963 /* 964 * 4) Renaming a directory with the parent 965 * different requires ".." to be rewritten. 966 * The window is still there for ".." to 967 * be inconsistent, but this is unavoidable, 968 * and a lot shorter than when it was done 969 * in a user process. 970 */ 971 if (doingdirectory && parentdifferent && error == 0) { 972 struct dirtemplate dirbuf; 973 974 u.u_dirp = uap->to; 975 ip = namei(uchar, LOOKUP | LOCKPARENT, 0); 976 if (ip == NULL) { 977 printf("rename: .. went away\n"); 978 return; 979 } 980 dp = u.u_pdir; 981 if ((ip->i_mode&IFMT) != IFDIR) { 982 printf("rename: .. not a directory\n"); 983 goto stuck; 984 } 985 error = rdwri(UIO_READ, ip, (caddr_t)&dirbuf, 986 sizeof (struct dirtemplate), (off_t)0, 1, (int *)0); 987 if (error == 0) { 988 dirbuf.dotdot_ino = dp->i_number; 989 (void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf, 990 sizeof (struct dirtemplate), (off_t)0, 1, (int *)0); 991 } 992 stuck: 993 irele(dp); 994 iput(ip); 995 } 996 goto done; 997 998 bad: 999 iput(dp); 1000 bad1: 1001 if (xp) 1002 iput(xp); 1003 out: 1004 ip->i_nlink--; 1005 ip->i_flag |= ICHG; 1006 irele(ip); 1007 done: 1008 if (error) 1009 u.u_error = error; 1010 } 1011 1012 /* 1013 * Make a new file. 1014 */ 1015 struct inode * 1016 maknode(mode) 1017 int mode; 1018 { 1019 register struct inode *ip; 1020 ino_t ipref; 1021 1022 if ((mode & IFMT) == IFDIR) 1023 ipref = dirpref(u.u_pdir->i_fs); 1024 else 1025 ipref = u.u_pdir->i_number; 1026 ip = ialloc(u.u_pdir, ipref, mode); 1027 if (ip == NULL) { 1028 iput(u.u_pdir); 1029 return (NULL); 1030 } 1031 #ifdef QUOTA 1032 if (ip->i_dquot != NODQUOT) 1033 panic("maknode: dquot"); 1034 #endif 1035 ip->i_flag |= IACC|IUPD|ICHG; 1036 if ((mode & IFMT) == 0) 1037 mode |= IFREG; 1038 ip->i_mode = mode & ~u.u_cmask; 1039 ip->i_nlink = 1; 1040 ip->i_uid = u.u_uid; 1041 ip->i_gid = u.u_pdir->i_gid; 1042 if (ip->i_mode & ISGID && !groupmember(ip->i_gid)) 1043 ip->i_mode &= ~ISGID; 1044 #ifdef QUOTA 1045 ip->i_dquot = inoquota(ip); 1046 #endif 1047 1048 /* 1049 * Make sure inode goes to disk before directory entry. 1050 */ 1051 iupdat(ip, &time, &time, 1); 1052 u.u_error = direnter(ip); 1053 if (u.u_error) { 1054 /* 1055 * Write error occurred trying to update directory 1056 * so must deallocate the inode. 1057 */ 1058 ip->i_nlink = 0; 1059 ip->i_flag |= ICHG; 1060 iput(ip); 1061 return (NULL); 1062 } 1063 return (ip); 1064 } 1065 1066 /* 1067 * A virgin directory (no blushing please). 1068 */ 1069 struct dirtemplate mastertemplate = { 1070 0, 12, 1, ".", 1071 0, DIRBLKSIZ - 12, 2, ".." 1072 }; 1073 1074 /* 1075 * Mkdir system call 1076 */ 1077 mkdir() 1078 { 1079 struct a { 1080 char *name; 1081 int dmode; 1082 } *uap; 1083 register struct inode *ip, *dp; 1084 struct dirtemplate dirtemplate; 1085 1086 uap = (struct a *)u.u_ap; 1087 ip = namei(uchar, CREATE, 0); 1088 if (u.u_error) 1089 return; 1090 if (ip != NULL) { 1091 iput(ip); 1092 u.u_error = EEXIST; 1093 return; 1094 } 1095 dp = u.u_pdir; 1096 uap->dmode &= 0777; 1097 uap->dmode |= IFDIR; 1098 /* 1099 * Must simulate part of maknode here 1100 * in order to acquire the inode, but 1101 * not have it entered in the parent 1102 * directory. The entry is made later 1103 * after writing "." and ".." entries out. 1104 */ 1105 ip = ialloc(dp, dirpref(dp->i_fs), uap->dmode); 1106 if (ip == NULL) { 1107 iput(dp); 1108 return; 1109 } 1110 #ifdef QUOTA 1111 if (ip->i_dquot != NODQUOT) 1112 panic("mkdir: dquot"); 1113 #endif 1114 ip->i_flag |= IACC|IUPD|ICHG; 1115 ip->i_mode = uap->dmode & ~u.u_cmask; 1116 ip->i_nlink = 2; 1117 ip->i_uid = u.u_uid; 1118 ip->i_gid = dp->i_gid; 1119 #ifdef QUOTA 1120 ip->i_dquot = inoquota(ip); 1121 #endif 1122 iupdat(ip, &time, &time, 1); 1123 1124 /* 1125 * Bump link count in parent directory 1126 * to reflect work done below. Should 1127 * be done before reference is created 1128 * so reparation is possible if we crash. 1129 */ 1130 dp->i_nlink++; 1131 dp->i_flag |= ICHG; 1132 iupdat(dp, &time, &time, 1); 1133 1134 /* 1135 * Initialize directory with "." 1136 * and ".." from static template. 1137 */ 1138 dirtemplate = mastertemplate; 1139 dirtemplate.dot_ino = ip->i_number; 1140 dirtemplate.dotdot_ino = dp->i_number; 1141 u.u_error = rdwri(UIO_WRITE, ip, (caddr_t)&dirtemplate, 1142 sizeof (dirtemplate), (off_t)0, 1, (int *)0); 1143 if (u.u_error) { 1144 dp->i_nlink--; 1145 dp->i_flag |= ICHG; 1146 goto bad; 1147 } 1148 /* 1149 * Directory all set up, now 1150 * install the entry for it in 1151 * the parent directory. 1152 */ 1153 u.u_error = direnter(ip); 1154 dp = NULL; 1155 if (u.u_error) { 1156 u.u_dirp = uap->name; 1157 dp = namei(uchar, LOOKUP, 0); 1158 if (dp) { 1159 dp->i_nlink--; 1160 dp->i_flag |= ICHG; 1161 } 1162 } 1163 bad: 1164 /* 1165 * No need to do an explicit itrunc here, 1166 * irele will do this for us because we set 1167 * the link count to 0. 1168 */ 1169 if (u.u_error) { 1170 ip->i_nlink = 0; 1171 ip->i_flag |= ICHG; 1172 } 1173 if (dp) 1174 iput(dp); 1175 iput(ip); 1176 } 1177 1178 /* 1179 * Rmdir system call. 1180 */ 1181 rmdir() 1182 { 1183 struct a { 1184 char *name; 1185 }; 1186 register struct inode *ip, *dp; 1187 1188 ip = namei(uchar, DELETE | LOCKPARENT, 0); 1189 if (ip == NULL) 1190 return; 1191 dp = u.u_pdir; 1192 /* 1193 * No rmdir "." please. 1194 */ 1195 if (dp == ip) { 1196 irele(dp); 1197 iput(ip); 1198 u.u_error = EINVAL; 1199 return; 1200 } 1201 if ((ip->i_mode&IFMT) != IFDIR) { 1202 u.u_error = ENOTDIR; 1203 goto out; 1204 } 1205 /* 1206 * Don't remove a mounted on directory. 1207 */ 1208 if (ip->i_dev != dp->i_dev) { 1209 u.u_error = EBUSY; 1210 goto out; 1211 } 1212 /* 1213 * Verify the directory is empty (and valid). 1214 * (Rmdir ".." won't be valid since 1215 * ".." will contain a reference to 1216 * the current directory and thus be 1217 * non-empty.) 1218 */ 1219 if (ip->i_nlink != 2 || !dirempty(ip)) { 1220 u.u_error = ENOTEMPTY; 1221 goto out; 1222 } 1223 /* 1224 * Delete reference to directory before purging 1225 * inode. If we crash in between, the directory 1226 * will be reattached to lost+found, 1227 */ 1228 if (dirremove() == 0) 1229 goto out; 1230 dp->i_nlink--; 1231 dp->i_flag |= ICHG; 1232 iput(dp); 1233 dp = NULL; 1234 /* 1235 * Truncate inode. The only stuff left 1236 * in the directory is "." and "..". The 1237 * "." reference is inconsequential since 1238 * we're quashing it. The ".." reference 1239 * has already been adjusted above. We've 1240 * removed the "." reference and the reference 1241 * in the parent directory, but there may be 1242 * other hard links so decrement by 2 and 1243 * worry about them later. 1244 */ 1245 ip->i_nlink -= 2; 1246 itrunc(ip, (u_long)0); 1247 out: 1248 if (dp) 1249 iput(dp); 1250 iput(ip); 1251 } 1252 1253 struct file * 1254 getinode(fdes) 1255 int fdes; 1256 { 1257 register struct file *fp; 1258 1259 fp = getf(fdes); 1260 if (fp == 0) 1261 return (0); 1262 if (fp->f_type != DTYPE_INODE) { 1263 u.u_error = EINVAL; 1264 return (0); 1265 } 1266 return (fp); 1267 } 1268 1269 /* 1270 * mode mask for creation of files 1271 */ 1272 umask() 1273 { 1274 register struct a { 1275 int mask; 1276 } *uap; 1277 1278 uap = (struct a *)u.u_ap; 1279 u.u_r.r_val1 = u.u_cmask; 1280 u.u_cmask = uap->mask & 07777; 1281 } 1282