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