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