1 /* vfs_syscalls.c 4.57 83/05/27 */ 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) statinode(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 #ifndef NOCOMPAT 625 /* 626 * Set IUPD and IACC times on file. 627 * Can't set ICHG. 628 */ 629 outime() 630 { 631 register struct a { 632 char *fname; 633 time_t *tptr; 634 } *uap = (struct a *)u.u_ap; 635 register struct inode *ip; 636 time_t tv[2]; 637 struct timeval tv0, tv1; 638 639 if ((ip = owner(1)) == NULL) 640 return; 641 u.u_error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)); 642 if (u.u_error == 0) { 643 ip->i_flag |= IACC|IUPD|ICHG; 644 tv0.tv_sec = tv[0]; tv0.tv_usec = 0; 645 tv1.tv_sec = tv[1]; tv1.tv_usec = 0; 646 iupdat(ip, &tv0, &tv1, 0); 647 } 648 iput(ip); 649 } 650 #endif 651 652 utimes() 653 { 654 register struct a { 655 char *fname; 656 struct timeval *tptr; 657 } *uap = (struct a *)u.u_ap; 658 register struct inode *ip; 659 struct timeval tv[2]; 660 661 if ((ip = owner(1)) == NULL) 662 return; 663 u.u_error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)); 664 if (u.u_error == 0) { 665 ip->i_flag |= IACC|IUPD|ICHG; 666 iupdat(ip, &tv[0], &tv[1], 0); 667 } 668 iput(ip); 669 } 670 671 /* 672 * Flush any pending I/O. 673 */ 674 sync() 675 { 676 677 update(); 678 } 679 680 /* 681 * Apply an advisory lock on a file descriptor. 682 */ 683 flock() 684 { 685 register struct a { 686 int fd; 687 int how; 688 } *uap = (struct a *)u.u_ap; 689 register struct file *fp; 690 register int cmd, flags; 691 692 fp = getinode(uap->fd); 693 if (fp == NULL) 694 return; 695 cmd = uap->how; 696 flags = u.u_pofile[uap->fd] & (UF_SHLOCK|UF_EXLOCK); 697 if (cmd&LOCK_UN) { 698 if (flags == 0) { 699 u.u_error = EINVAL; 700 return; 701 } 702 funlocki((struct inode *)fp->f_data, flags); 703 u.u_pofile[uap->fd] &= ~(UF_SHLOCK|UF_EXLOCK); 704 return; 705 } 706 /* 707 * No reason to write lock a file we've already 708 * write locked, similarly with a read lock. 709 */ 710 if ((flags&UF_EXLOCK) && (cmd&LOCK_EX) || 711 (flags&UF_SHLOCK) && (cmd&LOCK_SH)) 712 return; 713 u.u_pofile[uap->fd] = 714 flocki((struct inode *)fp->f_data, u.u_pofile[uap->fd], cmd); 715 } 716 717 /* 718 * Truncate a file given its path name. 719 */ 720 truncate() 721 { 722 struct a { 723 char *fname; 724 u_long length; 725 } *uap = (struct a *)u.u_ap; 726 struct inode *ip; 727 728 ip = namei(uchar, LOOKUP, 1); 729 if (ip == NULL) 730 return; 731 if (access(ip, IWRITE)) 732 goto bad; 733 if ((ip->i_mode&IFMT) == IFDIR) { 734 u.u_error = EISDIR; 735 goto bad; 736 } 737 itrunc(ip, uap->length); 738 bad: 739 iput(ip); 740 } 741 742 /* 743 * Truncate a file given a file descriptor. 744 */ 745 ftruncate() 746 { 747 struct a { 748 int fd; 749 u_long length; 750 } *uap = (struct a *)u.u_ap; 751 struct inode *ip; 752 struct file *fp; 753 754 fp = getinode(uap->fd); 755 if (fp == NULL) 756 return; 757 if ((fp->f_flag&FWRITE) == 0) { 758 u.u_error = EINVAL; 759 return; 760 } 761 ip = (struct inode *)fp->f_data; 762 ilock(ip); 763 itrunc(ip, uap->length); 764 iunlock(ip); 765 } 766 767 /* 768 * Synch an open file. 769 */ 770 fsync() 771 { 772 struct a { 773 int fd; 774 } *uap = (struct a *)u.u_ap; 775 struct inode *ip; 776 struct file *fp; 777 778 fp = getinode(uap->fd); 779 if (fp == NULL) 780 return; 781 ip = (struct inode *)fp->f_data; 782 ilock(ip); 783 syncip(ip); 784 iunlock(ip); 785 } 786 787 /* 788 * Rename system call. 789 * rename("foo", "bar"); 790 * is essentially 791 * unlink("bar"); 792 * link("foo", "bar"); 793 * unlink("foo"); 794 * but ``atomically''. Can't do full commit without saving state in the 795 * inode on disk which isn't feasible at this time. Best we can do is 796 * always guarantee the target exists. 797 * 798 * Basic algorithm is: 799 * 800 * 1) Bump link count on source while we're linking it to the 801 * target. This also insure the inode won't be deleted out 802 * from underneath us while we work. 803 * 2) Link source to destination. If destination already exists, 804 * delete it first. 805 * 3) Unlink source reference to inode if still around. 806 * 4) If a directory was moved and the parent of the destination 807 * is different from the source, patch the ".." entry in the 808 * directory. 809 * 810 * Source and destination must either both be directories, or both 811 * not be directories. If target is a directory, it must be empty. 812 */ 813 rename() 814 { 815 struct a { 816 char *from; 817 char *to; 818 } *uap; 819 register struct inode *ip, *xp, *dp; 820 int oldparent, parentdifferent, doingdirectory; 821 int error = 0; 822 823 uap = (struct a *)u.u_ap; 824 ip = namei(uchar, DELETE | LOCKPARENT, 0); 825 if (ip == NULL) 826 return; 827 dp = u.u_pdir; 828 oldparent = 0, doingdirectory = 0; 829 if ((ip->i_mode&IFMT) == IFDIR) { 830 register struct direct *d; 831 832 d = &u.u_dent; 833 /* 834 * Avoid ".", "..", and aliases of "." for obvious reasons. 835 */ 836 if ((d->d_namlen == 1 && d->d_name[0] == '.') || 837 (d->d_namlen == 2 && bcmp(d->d_name, "..", 2) == 0) || 838 (dp == ip)) { 839 iput(dp); 840 if (dp == ip) 841 irele(ip); 842 else 843 iput(ip); 844 u.u_error = EINVAL; 845 return; 846 } 847 oldparent = dp->i_number; 848 doingdirectory++; 849 } 850 iput(dp); 851 852 /* 853 * 1) Bump link count while we're moving stuff 854 * around. If we crash somewhere before 855 * completing our work, the link count 856 * may be wrong, but correctable. 857 */ 858 ip->i_nlink++; 859 ip->i_flag |= ICHG; 860 iupdat(ip, &time, &time, 1); 861 iunlock(ip); 862 863 /* 864 * When the target exists, both the directory 865 * and target inodes are returned locked. 866 */ 867 u.u_dirp = (caddr_t)uap->to; 868 xp = namei(uchar, CREATE | LOCKPARENT, 0); 869 if (u.u_error) { 870 error = u.u_error; 871 goto out; 872 } 873 dp = u.u_pdir; 874 /* 875 * If ".." must be changed (ie the directory gets a new 876 * parent) then the user must have write permission. 877 */ 878 parentdifferent = oldparent != dp->i_number; 879 if (doingdirectory && parentdifferent && access(ip, IWRITE)) 880 goto bad; 881 /* 882 * 2) If target doesn't exist, link the target 883 * to the source and unlink the source. 884 * Otherwise, rewrite the target directory 885 * entry to reference the source inode and 886 * expunge the original entry's existence. 887 */ 888 if (xp == NULL) { 889 if (dp->i_dev != ip->i_dev) { 890 error = EXDEV; 891 goto bad; 892 } 893 /* 894 * Disallow rename(foo, foo/bar). 895 */ 896 if (dp->i_number == ip->i_number) { 897 error = EEXIST; 898 goto bad; 899 } 900 /* 901 * Account for ".." in directory. 902 * When source and destination have the 903 * same parent we don't fool with the 904 * link count -- this isn't required 905 * because we do a similar check below. 906 */ 907 if (doingdirectory && parentdifferent) { 908 dp->i_nlink++; 909 dp->i_flag |= ICHG; 910 iupdat(dp, &time, &time, 1); 911 } 912 error = direnter(ip); 913 if (error) 914 goto out; 915 } else { 916 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) { 917 error = EXDEV; 918 goto bad; 919 } 920 /* 921 * Short circuit rename(foo, foo). 922 */ 923 if (xp->i_number == ip->i_number) 924 goto bad; 925 /* 926 * Target must be empty if a directory 927 * and have no links to it. 928 * Also, insure source and target are 929 * compatible (both directories, or both 930 * not directories). 931 */ 932 if ((xp->i_mode&IFMT) == IFDIR) { 933 if (!dirempty(xp) || xp->i_nlink > 2) { 934 error = ENOTEMPTY; 935 goto bad; 936 } 937 if (!doingdirectory) { 938 error = ENOTDIR; 939 goto bad; 940 } 941 } else if (doingdirectory) { 942 error = EISDIR; 943 goto bad; 944 } 945 dirrewrite(dp, ip); 946 if (u.u_error) { 947 error = u.u_error; 948 goto bad1; 949 } 950 /* 951 * Adjust the link count of the target to 952 * reflect the dirrewrite above. If this is 953 * a directory it is empty and there are 954 * no links to it, so we can squash the inode and 955 * any space associated with it. We disallowed 956 * renaming over top of a directory with links to 957 * it above, as we've no way to determine if 958 * we've got a link or the directory itself, and 959 * if we get a link, then ".." will be screwed up. 960 */ 961 xp->i_nlink--; 962 if (doingdirectory) { 963 if (--xp->i_nlink != 0) 964 panic("rename: linked directory"); 965 itrunc(xp, (u_long)0); 966 } 967 xp->i_flag |= ICHG; 968 iput(xp); 969 xp = NULL; 970 } 971 972 /* 973 * 3) Unlink the source. 974 */ 975 u.u_dirp = uap->from; 976 dp = namei(uchar, DELETE, 0); 977 /* 978 * Insure directory entry still exists and 979 * has not changed since the start of all 980 * this. If either has occured, forget about 981 * about deleting the original entry and just 982 * adjust the link count in the inode. 983 */ 984 if (dp == NULL || u.u_dent.d_ino != ip->i_number) { 985 ip->i_nlink--; 986 ip->i_flag |= ICHG; 987 } else { 988 /* 989 * If source is a directory, must adjust 990 * link count of parent directory also. 991 * If target didn't exist and source and 992 * target have the same parent, then we 993 * needn't touch the link count, it all 994 * balances out in the end. Otherwise, we 995 * must do so to reflect deletion of ".." 996 * done above. 997 */ 998 if (doingdirectory && (xp != NULL || parentdifferent)) { 999 dp->i_nlink--; 1000 dp->i_flag |= ICHG; 1001 } 1002 if (dirremove()) { 1003 ip->i_nlink--; 1004 ip->i_flag |= ICHG; 1005 } 1006 if (error == 0) /* conservative */ 1007 error = u.u_error; 1008 } 1009 irele(ip); 1010 if (dp) 1011 iput(dp); 1012 1013 /* 1014 * 4) Renaming a directory with the parent 1015 * different requires ".." to be rewritten. 1016 * The window is still there for ".." to 1017 * be inconsistent, but this is unavoidable, 1018 * and a lot shorter than when it was done 1019 * in a user process. 1020 */ 1021 if (doingdirectory && parentdifferent && error == 0) { 1022 struct dirtemplate dirbuf; 1023 1024 u.u_dirp = uap->to; 1025 ip = namei(uchar, LOOKUP | LOCKPARENT, 0); 1026 if (ip == NULL) { 1027 printf("rename: .. went away\n"); 1028 return; 1029 } 1030 dp = u.u_pdir; 1031 if ((ip->i_mode&IFMT) != IFDIR) { 1032 printf("rename: .. not a directory\n"); 1033 goto stuck; 1034 } 1035 error = rdwri(UIO_READ, ip, (caddr_t)&dirbuf, 1036 sizeof (struct dirtemplate), (off_t)0, 1, (int *)0); 1037 if (error == 0) { 1038 dirbuf.dotdot_ino = dp->i_number; 1039 (void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf, 1040 sizeof (struct dirtemplate), (off_t)0, 1, (int *)0); 1041 } 1042 stuck: 1043 irele(dp); 1044 iput(ip); 1045 } 1046 goto done; 1047 1048 bad: 1049 iput(dp); 1050 bad1: 1051 if (xp) 1052 iput(xp); 1053 out: 1054 ip->i_nlink--; 1055 ip->i_flag |= ICHG; 1056 irele(ip); 1057 done: 1058 if (error) 1059 u.u_error = error; 1060 } 1061 1062 /* 1063 * Make a new file. 1064 */ 1065 struct inode * 1066 maknode(mode) 1067 int mode; 1068 { 1069 register struct inode *ip; 1070 ino_t ipref; 1071 1072 if ((mode & IFMT) == IFDIR) 1073 ipref = dirpref(u.u_pdir->i_fs); 1074 else 1075 ipref = u.u_pdir->i_number; 1076 ip = ialloc(u.u_pdir, ipref, mode); 1077 if (ip == NULL) { 1078 iput(u.u_pdir); 1079 return (NULL); 1080 } 1081 #ifdef QUOTA 1082 if (ip->i_dquot != NODQUOT) 1083 panic("maknode: dquot"); 1084 #endif 1085 ip->i_flag |= IACC|IUPD|ICHG; 1086 if ((mode & IFMT) == 0) 1087 mode |= IFREG; 1088 ip->i_mode = mode & ~u.u_cmask; 1089 ip->i_nlink = 1; 1090 ip->i_uid = u.u_uid; 1091 ip->i_gid = u.u_pdir->i_gid; 1092 if (ip->i_mode & ISGID && !groupmember(ip->i_gid)) 1093 ip->i_mode &= ~ISGID; 1094 #ifdef QUOTA 1095 ip->i_dquot = inoquota(ip); 1096 #endif 1097 1098 /* 1099 * Make sure inode goes to disk before directory entry. 1100 */ 1101 iupdat(ip, &time, &time, 1); 1102 u.u_error = direnter(ip); 1103 if (u.u_error) { 1104 /* 1105 * Write error occurred trying to update directory 1106 * so must deallocate the inode. 1107 */ 1108 ip->i_nlink = 0; 1109 ip->i_flag |= ICHG; 1110 iput(ip); 1111 return (NULL); 1112 } 1113 return (ip); 1114 } 1115 1116 /* 1117 * A virgin directory (no blushing please). 1118 */ 1119 struct dirtemplate mastertemplate = { 1120 0, 12, 1, ".", 1121 0, DIRBLKSIZ - 12, 2, ".." 1122 }; 1123 1124 /* 1125 * Mkdir system call 1126 */ 1127 mkdir() 1128 { 1129 struct a { 1130 char *name; 1131 int dmode; 1132 } *uap; 1133 register struct inode *ip, *dp; 1134 struct dirtemplate dirtemplate; 1135 1136 uap = (struct a *)u.u_ap; 1137 ip = namei(uchar, CREATE, 0); 1138 if (u.u_error) 1139 return; 1140 if (ip != NULL) { 1141 iput(ip); 1142 u.u_error = EEXIST; 1143 return; 1144 } 1145 dp = u.u_pdir; 1146 uap->dmode &= 0777; 1147 uap->dmode |= IFDIR; 1148 /* 1149 * Must simulate part of maknode here 1150 * in order to acquire the inode, but 1151 * not have it entered in the parent 1152 * directory. The entry is made later 1153 * after writing "." and ".." entries out. 1154 */ 1155 ip = ialloc(dp, dirpref(dp->i_fs), uap->dmode); 1156 if (ip == NULL) { 1157 iput(dp); 1158 return; 1159 } 1160 #ifdef QUOTA 1161 if (ip->i_dquot != NODQUOT) 1162 panic("mkdir: dquot"); 1163 #endif 1164 ip->i_flag |= IACC|IUPD|ICHG; 1165 ip->i_mode = uap->dmode & ~u.u_cmask; 1166 ip->i_nlink = 2; 1167 ip->i_uid = u.u_uid; 1168 ip->i_gid = dp->i_gid; 1169 #ifdef QUOTA 1170 ip->i_dquot = inoquota(ip); 1171 #endif 1172 iupdat(ip, &time, &time, 1); 1173 1174 /* 1175 * Bump link count in parent directory 1176 * to reflect work done below. Should 1177 * be done before reference is created 1178 * so reparation is possible if we crash. 1179 */ 1180 dp->i_nlink++; 1181 dp->i_flag |= ICHG; 1182 iupdat(dp, &time, &time, 1); 1183 1184 /* 1185 * Initialize directory with "." 1186 * and ".." from static template. 1187 */ 1188 dirtemplate = mastertemplate; 1189 dirtemplate.dot_ino = ip->i_number; 1190 dirtemplate.dotdot_ino = dp->i_number; 1191 u.u_error = rdwri(UIO_WRITE, ip, (caddr_t)&dirtemplate, 1192 sizeof (dirtemplate), (off_t)0, 1, (int *)0); 1193 if (u.u_error) { 1194 dp->i_nlink--; 1195 dp->i_flag |= ICHG; 1196 goto bad; 1197 } 1198 /* 1199 * Directory all set up, now 1200 * install the entry for it in 1201 * the parent directory. 1202 */ 1203 u.u_error = direnter(ip); 1204 dp = NULL; 1205 if (u.u_error) { 1206 u.u_dirp = uap->name; 1207 dp = namei(uchar, LOOKUP, 0); 1208 if (dp) { 1209 dp->i_nlink--; 1210 dp->i_flag |= ICHG; 1211 } 1212 } 1213 bad: 1214 /* 1215 * No need to do an explicit itrunc here, 1216 * irele will do this for us because we set 1217 * the link count to 0. 1218 */ 1219 if (u.u_error) { 1220 ip->i_nlink = 0; 1221 ip->i_flag |= ICHG; 1222 } 1223 if (dp) 1224 iput(dp); 1225 iput(ip); 1226 } 1227 1228 /* 1229 * Rmdir system call. 1230 */ 1231 rmdir() 1232 { 1233 struct a { 1234 char *name; 1235 }; 1236 register struct inode *ip, *dp; 1237 1238 ip = namei(uchar, DELETE | LOCKPARENT, 0); 1239 if (ip == NULL) 1240 return; 1241 dp = u.u_pdir; 1242 /* 1243 * No rmdir "." please. 1244 */ 1245 if (dp == ip) { 1246 irele(dp); 1247 iput(ip); 1248 u.u_error = EINVAL; 1249 return; 1250 } 1251 if ((ip->i_mode&IFMT) != IFDIR) { 1252 u.u_error = ENOTDIR; 1253 goto out; 1254 } 1255 /* 1256 * Don't remove a mounted on directory. 1257 */ 1258 if (ip->i_dev != dp->i_dev) { 1259 u.u_error = EBUSY; 1260 goto out; 1261 } 1262 /* 1263 * Verify the directory is empty (and valid). 1264 * (Rmdir ".." won't be valid since 1265 * ".." will contain a reference to 1266 * the current directory and thus be 1267 * non-empty.) 1268 */ 1269 if (ip->i_nlink != 2 || !dirempty(ip)) { 1270 u.u_error = ENOTEMPTY; 1271 goto out; 1272 } 1273 /* 1274 * Delete reference to directory before purging 1275 * inode. If we crash in between, the directory 1276 * will be reattached to lost+found, 1277 */ 1278 if (dirremove() == 0) 1279 goto out; 1280 dp->i_nlink--; 1281 dp->i_flag |= ICHG; 1282 iput(dp); 1283 dp = NULL; 1284 /* 1285 * Truncate inode. The only stuff left 1286 * in the directory is "." and "..". The 1287 * "." reference is inconsequential since 1288 * we're quashing it. The ".." reference 1289 * has already been adjusted above. We've 1290 * removed the "." reference and the reference 1291 * in the parent directory, but there may be 1292 * other hard links so decrement by 2 and 1293 * worry about them later. 1294 */ 1295 ip->i_nlink -= 2; 1296 itrunc(ip, (u_long)0); 1297 out: 1298 if (dp) 1299 iput(dp); 1300 iput(ip); 1301 } 1302 1303 struct file * 1304 getinode(fdes) 1305 int fdes; 1306 { 1307 register struct file *fp; 1308 1309 fp = getf(fdes); 1310 if (fp == 0) 1311 return (0); 1312 if (fp->f_type != DTYPE_INODE) { 1313 u.u_error = EINVAL; 1314 return (0); 1315 } 1316 return (fp); 1317 } 1318 1319 /* 1320 * mode mask for creation of files 1321 */ 1322 umask() 1323 { 1324 register struct a { 1325 int mask; 1326 } *uap; 1327 1328 uap = (struct a *)u.u_ap; 1329 u.u_r.r_val1 = u.u_cmask; 1330 u.u_cmask = uap->mask & 07777; 1331 } 1332