1 /* ufs_vnops.c 6.1 83/08/06 */ 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 switch (uap->sbase) { 375 376 case L_INCR: 377 fp->f_offset += uap->off; 378 break; 379 380 case L_XTND: 381 fp->f_offset = uap->off + ((struct inode *)fp->f_data)->i_size; 382 break; 383 384 case L_SET: 385 fp->f_offset = uap->off; 386 break; 387 388 default: 389 u.u_error = EINVAL; 390 return; 391 } 392 u.u_r.r_off = fp->f_offset; 393 } 394 395 /* 396 * Access system call 397 */ 398 saccess() 399 { 400 register svuid, svgid; 401 register struct inode *ip; 402 register struct a { 403 char *fname; 404 int fmode; 405 } *uap; 406 407 uap = (struct a *)u.u_ap; 408 svuid = u.u_uid; 409 svgid = u.u_gid; 410 u.u_uid = u.u_ruid; 411 u.u_gid = u.u_rgid; 412 ip = namei(uchar, LOOKUP, 1); 413 if (ip != NULL) { 414 if ((uap->fmode&R_OK) && access(ip, IREAD)) 415 goto done; 416 if ((uap->fmode&W_OK) && access(ip, IWRITE)) 417 goto done; 418 if ((uap->fmode&X_OK) && access(ip, IEXEC)) 419 goto done; 420 done: 421 iput(ip); 422 } 423 u.u_uid = svuid; 424 u.u_gid = svgid; 425 } 426 427 /* 428 * Stat system call. This version follows links. 429 */ 430 stat() 431 { 432 433 stat1(1); 434 } 435 436 /* 437 * Lstat system call. This version does not follow links. 438 */ 439 lstat() 440 { 441 442 stat1(0); 443 } 444 445 stat1(follow) 446 int follow; 447 { 448 register struct inode *ip; 449 register struct a { 450 char *fname; 451 struct stat *ub; 452 } *uap; 453 struct stat sb; 454 455 uap = (struct a *)u.u_ap; 456 ip = namei(uchar, LOOKUP, follow); 457 if (ip == NULL) 458 return; 459 (void) ino_stat(ip, &sb); 460 iput(ip); 461 u.u_error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb)); 462 } 463 464 /* 465 * Return target name of a symbolic link 466 */ 467 readlink() 468 { 469 register struct inode *ip; 470 register struct a { 471 char *name; 472 char *buf; 473 int count; 474 } *uap = (struct a *)u.u_ap; 475 int resid; 476 477 ip = namei(uchar, LOOKUP, 0); 478 if (ip == NULL) 479 return; 480 if ((ip->i_mode&IFMT) != IFLNK) { 481 u.u_error = ENXIO; 482 goto out; 483 } 484 u.u_error = rdwri(UIO_READ, ip, uap->buf, uap->count, 0, 0, &resid); 485 out: 486 iput(ip); 487 u.u_r.r_val1 = uap->count - resid; 488 } 489 490 /* 491 * Change mode of a file given path name. 492 */ 493 chmod() 494 { 495 struct inode *ip; 496 struct a { 497 char *fname; 498 int fmode; 499 } *uap; 500 501 uap = (struct a *)u.u_ap; 502 if ((ip = owner(1)) == NULL) 503 return; 504 chmod1(ip, uap->fmode); 505 iput(ip); 506 } 507 508 /* 509 * Change mode of a file given a file descriptor. 510 */ 511 fchmod() 512 { 513 struct a { 514 int fd; 515 int fmode; 516 } *uap; 517 register struct inode *ip; 518 register struct file *fp; 519 520 uap = (struct a *)u.u_ap; 521 fp = getinode(uap->fd); 522 if (fp == NULL) 523 return; 524 ip = (struct inode *)fp->f_data; 525 if (u.u_uid != ip->i_uid && !suser()) 526 return; 527 ilock(ip); 528 chmod1(ip, uap->fmode); 529 iunlock(ip); 530 } 531 532 /* 533 * Change the mode on a file. 534 * Inode must be locked before calling. 535 */ 536 chmod1(ip, mode) 537 register struct inode *ip; 538 register int mode; 539 { 540 541 ip->i_mode &= ~07777; 542 if (u.u_uid) { 543 mode &= ~ISVTX; 544 if (!groupmember(ip->i_gid)) 545 mode &= ~ISGID; 546 } 547 ip->i_mode |= mode&07777; 548 ip->i_flag |= ICHG; 549 if (ip->i_flag&ITEXT && (ip->i_mode&ISVTX)==0) 550 xrele(ip); 551 } 552 553 /* 554 * Set ownership given a path name. 555 */ 556 chown() 557 { 558 struct inode *ip; 559 struct a { 560 char *fname; 561 int uid; 562 int gid; 563 } *uap; 564 565 uap = (struct a *)u.u_ap; 566 if (!suser() || (ip = owner(0)) == NULL) 567 return; 568 u.u_error = chown1(ip, uap->uid, uap->gid); 569 iput(ip); 570 } 571 572 /* 573 * Set ownership given a file descriptor. 574 */ 575 fchown() 576 { 577 struct a { 578 int fd; 579 int uid; 580 int gid; 581 } *uap; 582 register struct inode *ip; 583 register struct file *fp; 584 585 uap = (struct a *)u.u_ap; 586 fp = getinode(uap->fd); 587 if (fp == NULL) 588 return; 589 ip = (struct inode *)fp->f_data; 590 if (!suser()) 591 return; 592 ilock(ip); 593 u.u_error = chown1(ip, uap->uid, uap->gid); 594 iunlock(ip); 595 } 596 597 /* 598 * Perform chown operation on inode ip; 599 * inode must be locked prior to call. 600 */ 601 chown1(ip, uid, gid) 602 register struct inode *ip; 603 int uid, gid; 604 { 605 #ifdef QUOTA 606 register long change; 607 #endif 608 609 if (uid == -1) 610 uid = ip->i_uid; 611 if (gid == -1) 612 gid = ip->i_gid; 613 #ifdef QUOTA 614 if (ip->i_uid == uid) /* this just speeds things a little */ 615 change = 0; 616 else 617 change = ip->i_blocks; 618 (void) chkdq(ip, -change, 1); 619 (void) chkiq(ip->i_dev, ip, ip->i_uid, 1); 620 dqrele(ip->i_dquot); 621 #endif 622 ip->i_uid = uid; 623 ip->i_gid = gid; 624 ip->i_flag |= ICHG; 625 if (u.u_ruid != 0) 626 ip->i_mode &= ~(ISUID|ISGID); 627 #ifdef QUOTA 628 ip->i_dquot = inoquota(ip); 629 (void) chkdq(ip, change, 1); 630 (void) chkiq(ip->i_dev, (struct inode *)NULL, uid, 1); 631 return (u.u_error); /* should == 0 ALWAYS !! */ 632 #else 633 return (0); 634 #endif 635 } 636 637 utimes() 638 { 639 register struct a { 640 char *fname; 641 struct timeval *tptr; 642 } *uap = (struct a *)u.u_ap; 643 register struct inode *ip; 644 struct timeval tv[2]; 645 646 if ((ip = owner(1)) == NULL) 647 return; 648 u.u_error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)); 649 if (u.u_error == 0) { 650 ip->i_flag |= IACC|IUPD|ICHG; 651 iupdat(ip, &tv[0], &tv[1], 0); 652 } 653 iput(ip); 654 } 655 656 /* 657 * Flush any pending I/O. 658 */ 659 sync() 660 { 661 662 update(); 663 } 664 665 /* 666 * Truncate a file given its path name. 667 */ 668 truncate() 669 { 670 struct a { 671 char *fname; 672 u_long length; 673 } *uap = (struct a *)u.u_ap; 674 struct inode *ip; 675 676 ip = namei(uchar, LOOKUP, 1); 677 if (ip == NULL) 678 return; 679 if (access(ip, IWRITE)) 680 goto bad; 681 if ((ip->i_mode&IFMT) == IFDIR) { 682 u.u_error = EISDIR; 683 goto bad; 684 } 685 itrunc(ip, uap->length); 686 bad: 687 iput(ip); 688 } 689 690 /* 691 * Truncate a file given a file descriptor. 692 */ 693 ftruncate() 694 { 695 struct a { 696 int fd; 697 u_long length; 698 } *uap = (struct a *)u.u_ap; 699 struct inode *ip; 700 struct file *fp; 701 702 fp = getinode(uap->fd); 703 if (fp == NULL) 704 return; 705 if ((fp->f_flag&FWRITE) == 0) { 706 u.u_error = EINVAL; 707 return; 708 } 709 ip = (struct inode *)fp->f_data; 710 ilock(ip); 711 itrunc(ip, uap->length); 712 iunlock(ip); 713 } 714 715 /* 716 * Synch an open file. 717 */ 718 fsync() 719 { 720 struct a { 721 int fd; 722 } *uap = (struct a *)u.u_ap; 723 struct inode *ip; 724 struct file *fp; 725 726 fp = getinode(uap->fd); 727 if (fp == NULL) 728 return; 729 ip = (struct inode *)fp->f_data; 730 ilock(ip); 731 syncip(ip); 732 iunlock(ip); 733 } 734 735 /* 736 * Rename system call. 737 * rename("foo", "bar"); 738 * is essentially 739 * unlink("bar"); 740 * link("foo", "bar"); 741 * unlink("foo"); 742 * but ``atomically''. Can't do full commit without saving state in the 743 * inode on disk which isn't feasible at this time. Best we can do is 744 * always guarantee the target exists. 745 * 746 * Basic algorithm is: 747 * 748 * 1) Bump link count on source while we're linking it to the 749 * target. This also insure the inode won't be deleted out 750 * from underneath us while we work. 751 * 2) Link source to destination. If destination already exists, 752 * delete it first. 753 * 3) Unlink source reference to inode if still around. 754 * 4) If a directory was moved and the parent of the destination 755 * is different from the source, patch the ".." entry in the 756 * directory. 757 * 758 * Source and destination must either both be directories, or both 759 * not be directories. If target is a directory, it must be empty. 760 */ 761 rename() 762 { 763 struct a { 764 char *from; 765 char *to; 766 } *uap; 767 register struct inode *ip, *xp, *dp; 768 int oldparent, parentdifferent, doingdirectory; 769 int error = 0; 770 771 uap = (struct a *)u.u_ap; 772 ip = namei(uchar, DELETE | LOCKPARENT, 0); 773 if (ip == NULL) 774 return; 775 dp = u.u_pdir; 776 oldparent = 0, doingdirectory = 0; 777 if ((ip->i_mode&IFMT) == IFDIR) { 778 register struct direct *d; 779 780 d = &u.u_dent; 781 /* 782 * Avoid ".", "..", and aliases of "." for obvious reasons. 783 */ 784 if ((d->d_namlen == 1 && d->d_name[0] == '.') || 785 (d->d_namlen == 2 && bcmp(d->d_name, "..", 2) == 0) || 786 (dp == ip)) { 787 iput(dp); 788 if (dp == ip) 789 irele(ip); 790 else 791 iput(ip); 792 u.u_error = EINVAL; 793 return; 794 } 795 oldparent = dp->i_number; 796 doingdirectory++; 797 } 798 iput(dp); 799 800 /* 801 * 1) Bump link count while we're moving stuff 802 * around. If we crash somewhere before 803 * completing our work, the link count 804 * may be wrong, but correctable. 805 */ 806 ip->i_nlink++; 807 ip->i_flag |= ICHG; 808 iupdat(ip, &time, &time, 1); 809 iunlock(ip); 810 811 /* 812 * When the target exists, both the directory 813 * and target inodes are returned locked. 814 */ 815 u.u_dirp = (caddr_t)uap->to; 816 xp = namei(uchar, CREATE | LOCKPARENT, 0); 817 if (u.u_error) { 818 error = u.u_error; 819 goto out; 820 } 821 dp = u.u_pdir; 822 /* 823 * If ".." must be changed (ie the directory gets a new 824 * parent) then the source directory must not be in the 825 * directory heirarchy above the target, as this would 826 * orphan everything below the source directory. Also 827 * the user must have write permission in the source so 828 * as to be able to change "..". We must repeat the call 829 * to namei, as the parent directory is unlocked by the 830 * call to checkpath(). 831 */ 832 parentdifferent = oldparent != dp->i_number; 833 if (doingdirectory && parentdifferent) { 834 if (access(ip, IWRITE)) 835 goto bad; 836 do { 837 dp = u.u_pdir; 838 if (xp != NULL) 839 iput(xp); 840 u.u_error = checkpath(ip, dp); 841 if (u.u_error) 842 goto out; 843 u.u_dirp = (caddr_t)uap->to; 844 xp = namei(uchar, CREATE | LOCKPARENT, 0); 845 if (u.u_error) { 846 error = u.u_error; 847 goto out; 848 } 849 } while (dp != u.u_pdir); 850 } 851 /* 852 * 2) If target doesn't exist, link the target 853 * to the source and unlink the source. 854 * Otherwise, rewrite the target directory 855 * entry to reference the source inode and 856 * expunge the original entry's existence. 857 */ 858 if (xp == NULL) { 859 if (dp->i_dev != ip->i_dev) { 860 error = EXDEV; 861 goto bad; 862 } 863 /* 864 * Account for ".." in directory. 865 * When source and destination have the 866 * same parent we don't fool with the 867 * link count -- this isn't required 868 * because we do a similar check below. 869 */ 870 if (doingdirectory && parentdifferent) { 871 dp->i_nlink++; 872 dp->i_flag |= ICHG; 873 iupdat(dp, &time, &time, 1); 874 } 875 error = direnter(ip); 876 if (error) 877 goto out; 878 } else { 879 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) { 880 error = EXDEV; 881 goto bad; 882 } 883 /* 884 * Short circuit rename(foo, foo). 885 */ 886 if (xp->i_number == ip->i_number) 887 goto bad; 888 /* 889 * Target must be empty if a directory 890 * and have no links to it. 891 * Also, insure source and target are 892 * compatible (both directories, or both 893 * not directories). 894 */ 895 if ((xp->i_mode&IFMT) == IFDIR) { 896 if (!dirempty(xp) || xp->i_nlink > 2) { 897 error = ENOTEMPTY; 898 goto bad; 899 } 900 if (!doingdirectory) { 901 error = ENOTDIR; 902 goto bad; 903 } 904 } else if (doingdirectory) { 905 error = EISDIR; 906 goto bad; 907 } 908 dirrewrite(dp, ip); 909 if (u.u_error) { 910 error = u.u_error; 911 goto bad1; 912 } 913 /* 914 * Adjust the link count of the target to 915 * reflect the dirrewrite above. If this is 916 * a directory it is empty and there are 917 * no links to it, so we can squash the inode and 918 * any space associated with it. We disallowed 919 * renaming over top of a directory with links to 920 * it above, as we've no way to determine if 921 * we've got a link or the directory itself, and 922 * if we get a link, then ".." will be screwed up. 923 */ 924 xp->i_nlink--; 925 if (doingdirectory) { 926 if (--xp->i_nlink != 0) 927 panic("rename: linked directory"); 928 itrunc(xp, (u_long)0); 929 } 930 xp->i_flag |= ICHG; 931 iput(xp); 932 xp = NULL; 933 } 934 935 /* 936 * 3) Unlink the source. 937 */ 938 u.u_dirp = uap->from; 939 dp = namei(uchar, DELETE, 0); 940 /* 941 * Insure directory entry still exists and 942 * has not changed since the start of all 943 * this. If either has occured, forget about 944 * about deleting the original entry and just 945 * adjust the link count in the inode. 946 */ 947 if (dp == NULL || u.u_dent.d_ino != ip->i_number) { 948 ip->i_nlink--; 949 ip->i_flag |= ICHG; 950 } else { 951 /* 952 * If source is a directory, must adjust 953 * link count of parent directory also. 954 * If target didn't exist and source and 955 * target have the same parent, then we 956 * needn't touch the link count, it all 957 * balances out in the end. Otherwise, we 958 * must do so to reflect deletion of ".." 959 * done above. 960 */ 961 if (doingdirectory && (xp != NULL || parentdifferent)) { 962 dp->i_nlink--; 963 dp->i_flag |= ICHG; 964 } 965 if (dirremove()) { 966 ip->i_nlink--; 967 ip->i_flag |= ICHG; 968 } 969 if (error == 0) /* conservative */ 970 error = u.u_error; 971 } 972 irele(ip); 973 if (dp) 974 iput(dp); 975 976 /* 977 * 4) Renaming a directory with the parent 978 * different requires ".." to be rewritten. 979 * The window is still there for ".." to 980 * be inconsistent, but this is unavoidable, 981 * and a lot shorter than when it was done 982 * in a user process. 983 */ 984 if (doingdirectory && parentdifferent && error == 0) { 985 struct dirtemplate dirbuf; 986 987 u.u_dirp = uap->to; 988 ip = namei(uchar, LOOKUP | LOCKPARENT, 0); 989 if (ip == NULL) { 990 printf("rename: .. went away\n"); 991 return; 992 } 993 dp = u.u_pdir; 994 if ((ip->i_mode&IFMT) != IFDIR) { 995 printf("rename: .. not a directory\n"); 996 goto stuck; 997 } 998 error = rdwri(UIO_READ, ip, (caddr_t)&dirbuf, 999 sizeof (struct dirtemplate), (off_t)0, 1, (int *)0); 1000 if (error == 0) { 1001 dirbuf.dotdot_ino = dp->i_number; 1002 (void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf, 1003 sizeof (struct dirtemplate), (off_t)0, 1, (int *)0); 1004 } 1005 stuck: 1006 irele(dp); 1007 iput(ip); 1008 } 1009 goto done; 1010 1011 bad: 1012 iput(dp); 1013 bad1: 1014 if (xp) 1015 iput(xp); 1016 out: 1017 ip->i_nlink--; 1018 ip->i_flag |= ICHG; 1019 irele(ip); 1020 done: 1021 if (error) 1022 u.u_error = error; 1023 } 1024 1025 /* 1026 * Make a new file. 1027 */ 1028 struct inode * 1029 maknode(mode) 1030 int mode; 1031 { 1032 register struct inode *ip; 1033 ino_t ipref; 1034 1035 if ((mode & IFMT) == IFDIR) 1036 ipref = dirpref(u.u_pdir->i_fs); 1037 else 1038 ipref = u.u_pdir->i_number; 1039 ip = ialloc(u.u_pdir, ipref, mode); 1040 if (ip == NULL) { 1041 iput(u.u_pdir); 1042 return (NULL); 1043 } 1044 #ifdef QUOTA 1045 if (ip->i_dquot != NODQUOT) 1046 panic("maknode: dquot"); 1047 #endif 1048 ip->i_flag |= IACC|IUPD|ICHG; 1049 if ((mode & IFMT) == 0) 1050 mode |= IFREG; 1051 ip->i_mode = mode & ~u.u_cmask; 1052 ip->i_nlink = 1; 1053 ip->i_uid = u.u_uid; 1054 ip->i_gid = u.u_pdir->i_gid; 1055 if (ip->i_mode & ISGID && !groupmember(ip->i_gid)) 1056 ip->i_mode &= ~ISGID; 1057 #ifdef QUOTA 1058 ip->i_dquot = inoquota(ip); 1059 #endif 1060 1061 /* 1062 * Make sure inode goes to disk before directory entry. 1063 */ 1064 iupdat(ip, &time, &time, 1); 1065 u.u_error = direnter(ip); 1066 if (u.u_error) { 1067 /* 1068 * Write error occurred trying to update directory 1069 * so must deallocate the inode. 1070 */ 1071 ip->i_nlink = 0; 1072 ip->i_flag |= ICHG; 1073 iput(ip); 1074 return (NULL); 1075 } 1076 return (ip); 1077 } 1078 1079 /* 1080 * A virgin directory (no blushing please). 1081 */ 1082 struct dirtemplate mastertemplate = { 1083 0, 12, 1, ".", 1084 0, DIRBLKSIZ - 12, 2, ".." 1085 }; 1086 1087 /* 1088 * Mkdir system call 1089 */ 1090 mkdir() 1091 { 1092 struct a { 1093 char *name; 1094 int dmode; 1095 } *uap; 1096 register struct inode *ip, *dp; 1097 struct dirtemplate dirtemplate; 1098 1099 uap = (struct a *)u.u_ap; 1100 ip = namei(uchar, CREATE, 0); 1101 if (u.u_error) 1102 return; 1103 if (ip != NULL) { 1104 iput(ip); 1105 u.u_error = EEXIST; 1106 return; 1107 } 1108 dp = u.u_pdir; 1109 uap->dmode &= 0777; 1110 uap->dmode |= IFDIR; 1111 /* 1112 * Must simulate part of maknode here 1113 * in order to acquire the inode, but 1114 * not have it entered in the parent 1115 * directory. The entry is made later 1116 * after writing "." and ".." entries out. 1117 */ 1118 ip = ialloc(dp, dirpref(dp->i_fs), uap->dmode); 1119 if (ip == NULL) { 1120 iput(dp); 1121 return; 1122 } 1123 #ifdef QUOTA 1124 if (ip->i_dquot != NODQUOT) 1125 panic("mkdir: dquot"); 1126 #endif 1127 ip->i_flag |= IACC|IUPD|ICHG; 1128 ip->i_mode = uap->dmode & ~u.u_cmask; 1129 ip->i_nlink = 2; 1130 ip->i_uid = u.u_uid; 1131 ip->i_gid = dp->i_gid; 1132 #ifdef QUOTA 1133 ip->i_dquot = inoquota(ip); 1134 #endif 1135 iupdat(ip, &time, &time, 1); 1136 1137 /* 1138 * Bump link count in parent directory 1139 * to reflect work done below. Should 1140 * be done before reference is created 1141 * so reparation is possible if we crash. 1142 */ 1143 dp->i_nlink++; 1144 dp->i_flag |= ICHG; 1145 iupdat(dp, &time, &time, 1); 1146 1147 /* 1148 * Initialize directory with "." 1149 * and ".." from static template. 1150 */ 1151 dirtemplate = mastertemplate; 1152 dirtemplate.dot_ino = ip->i_number; 1153 dirtemplate.dotdot_ino = dp->i_number; 1154 u.u_error = rdwri(UIO_WRITE, ip, (caddr_t)&dirtemplate, 1155 sizeof (dirtemplate), (off_t)0, 1, (int *)0); 1156 if (u.u_error) { 1157 dp->i_nlink--; 1158 dp->i_flag |= ICHG; 1159 goto bad; 1160 } 1161 /* 1162 * Directory all set up, now 1163 * install the entry for it in 1164 * the parent directory. 1165 */ 1166 u.u_error = direnter(ip); 1167 dp = NULL; 1168 if (u.u_error) { 1169 u.u_dirp = uap->name; 1170 dp = namei(uchar, LOOKUP, 0); 1171 if (dp) { 1172 dp->i_nlink--; 1173 dp->i_flag |= ICHG; 1174 } 1175 } 1176 bad: 1177 /* 1178 * No need to do an explicit itrunc here, 1179 * irele will do this for us because we set 1180 * the link count to 0. 1181 */ 1182 if (u.u_error) { 1183 ip->i_nlink = 0; 1184 ip->i_flag |= ICHG; 1185 } 1186 if (dp) 1187 iput(dp); 1188 iput(ip); 1189 } 1190 1191 /* 1192 * Rmdir system call. 1193 */ 1194 rmdir() 1195 { 1196 struct a { 1197 char *name; 1198 }; 1199 register struct inode *ip, *dp; 1200 1201 ip = namei(uchar, DELETE | LOCKPARENT, 0); 1202 if (ip == NULL) 1203 return; 1204 dp = u.u_pdir; 1205 /* 1206 * No rmdir "." please. 1207 */ 1208 if (dp == ip) { 1209 irele(dp); 1210 iput(ip); 1211 u.u_error = EINVAL; 1212 return; 1213 } 1214 if ((ip->i_mode&IFMT) != IFDIR) { 1215 u.u_error = ENOTDIR; 1216 goto out; 1217 } 1218 /* 1219 * Don't remove a mounted on directory. 1220 */ 1221 if (ip->i_dev != dp->i_dev) { 1222 u.u_error = EBUSY; 1223 goto out; 1224 } 1225 /* 1226 * Verify the directory is empty (and valid). 1227 * (Rmdir ".." won't be valid since 1228 * ".." will contain a reference to 1229 * the current directory and thus be 1230 * non-empty.) 1231 */ 1232 if (ip->i_nlink != 2 || !dirempty(ip)) { 1233 u.u_error = ENOTEMPTY; 1234 goto out; 1235 } 1236 /* 1237 * Delete reference to directory before purging 1238 * inode. If we crash in between, the directory 1239 * will be reattached to lost+found, 1240 */ 1241 if (dirremove() == 0) 1242 goto out; 1243 dp->i_nlink--; 1244 dp->i_flag |= ICHG; 1245 iput(dp); 1246 dp = NULL; 1247 /* 1248 * Truncate inode. The only stuff left 1249 * in the directory is "." and "..". The 1250 * "." reference is inconsequential since 1251 * we're quashing it. The ".." reference 1252 * has already been adjusted above. We've 1253 * removed the "." reference and the reference 1254 * in the parent directory, but there may be 1255 * other hard links so decrement by 2 and 1256 * worry about them later. 1257 */ 1258 ip->i_nlink -= 2; 1259 itrunc(ip, (u_long)0); 1260 out: 1261 if (dp) 1262 iput(dp); 1263 iput(ip); 1264 } 1265 1266 struct file * 1267 getinode(fdes) 1268 int fdes; 1269 { 1270 register struct file *fp; 1271 1272 fp = getf(fdes); 1273 if (fp == 0) 1274 return (0); 1275 if (fp->f_type != DTYPE_INODE) { 1276 u.u_error = EINVAL; 1277 return (0); 1278 } 1279 return (fp); 1280 } 1281 1282 /* 1283 * mode mask for creation of files 1284 */ 1285 umask() 1286 { 1287 register struct a { 1288 int mask; 1289 } *uap; 1290 1291 uap = (struct a *)u.u_ap; 1292 u.u_r.r_val1 = u.u_cmask; 1293 u.u_cmask = uap->mask & 07777; 1294 } 1295