1 /* lfs_vnops.c 4.54 83/03/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/descrip.h" 16 #include "../h/uio.h" 17 #include "../h/socket.h" 18 #include "../h/socketvar.h" 19 #include "../h/nami.h" 20 21 /* 22 * Change current working directory (``.''). 23 */ 24 chdir() 25 { 26 27 chdirec(&u.u_cdir); 28 } 29 30 /* 31 * Change notion of root (``/'') directory. 32 */ 33 chroot() 34 { 35 36 if (suser()) 37 chdirec(&u.u_rdir); 38 } 39 40 /* 41 * Common routine for chroot and chdir. 42 */ 43 chdirec(ipp) 44 register struct inode **ipp; 45 { 46 register struct inode *ip; 47 struct a { 48 char *fname; 49 }; 50 51 ip = namei(uchar, LOOKUP, 1); 52 if (ip == NULL) 53 return; 54 if ((ip->i_mode&IFMT) != IFDIR) { 55 u.u_error = ENOTDIR; 56 goto bad; 57 } 58 if (access(ip, IEXEC)) 59 goto bad; 60 iunlock(ip); 61 if (*ipp) 62 irele(*ipp); 63 *ipp = ip; 64 return; 65 66 bad: 67 iput(ip); 68 } 69 70 /* 71 * Open system call. 72 */ 73 open() 74 { 75 register struct inode *ip; 76 register struct a { 77 char *fname; 78 int flags; 79 int mode; 80 } *uap; 81 int checkpermissions = 1, flags; 82 83 uap = (struct a *)u.u_ap; 84 flags = uap->flags + 1; 85 if ((flags&FTRUNCATE) && (flags&FWRITE) == 0) { 86 u.u_error = EINVAL; 87 return; 88 } 89 if (flags&FCREATE) { 90 ip = namei(uchar, CREATE, 1); 91 if (ip == NULL) { 92 if (u.u_error) 93 return; 94 ip = maknode(uap->mode&07777&(~ISVTX)); 95 checkpermissions = 0; 96 flags &= ~FTRUNCATE; 97 } 98 } else 99 ip = namei(uchar, LOOKUP, 1); 100 if (ip == NULL) 101 return; 102 open1(ip, flags, checkpermissions); 103 } 104 105 #ifndef NOCOMPAT 106 /* 107 * Creat system call. 108 */ 109 ocreat() 110 { 111 register struct inode *ip; 112 register struct a { 113 char *fname; 114 int fmode; 115 } *uap; 116 117 uap = (struct a *)u.u_ap; 118 ip = namei(uchar, CREATE, 1); 119 if (ip == NULL) { 120 if (u.u_error) 121 return; 122 ip = maknode(uap->fmode&07777&(~ISVTX)); 123 if (ip == NULL) 124 return; 125 open1(ip, FWRITE, 0); 126 } else 127 open1(ip, FWRITE|FTRUNCATE, 1); 128 } 129 #endif 130 131 /* 132 * Common code for open and creat. 133 * Check permissions (if we haven't done so already), 134 * allocate an open file structure, and call 135 * the device open routine, if any. 136 */ 137 open1(ip, mode, checkpermissions) 138 register struct inode *ip; 139 register mode; 140 { 141 register struct file *fp; 142 int i, flags; 143 144 if (checkpermissions) { 145 if (mode&FREAD) 146 if (access(ip, IREAD)) 147 goto bad; 148 if (mode&FWRITE) { 149 if (access(ip, IWRITE)) 150 goto bad; 151 if ((ip->i_mode&IFMT) == IFDIR) { 152 u.u_error = EISDIR; 153 goto bad; 154 } 155 } 156 } 157 158 /* 159 * Check locking on inode. Release "inode lock" 160 * while doing so in case we block inside flocki. 161 */ 162 flags = 0; 163 if (mode&(FSHLOCK|FEXLOCK)) { 164 iunlock(ip); 165 flags = flocki(ip, 0, mode); 166 ilock(ip); 167 if (u.u_error) 168 goto bad; 169 } 170 if (mode&FTRUNCATE) 171 itrunc(ip, (u_long)0); 172 iunlock(ip); 173 if ((fp = falloc()) == NULL) 174 goto out; 175 fp->f_flag = mode & FMODES; 176 fp->f_type = DTYPE_FILE; 177 i = u.u_r.r_val1; 178 fp->f_inode = ip; 179 u.u_error = openi(ip, mode); 180 if (u.u_error == 0) { 181 u.u_pofile[i] = flags; 182 return; 183 } 184 u.u_ofile[i] = NULL; 185 fp->f_count--; 186 out: 187 irele(ip); 188 return; 189 bad: 190 iput(ip); 191 } 192 193 /* 194 * Mknod system call 195 */ 196 mknod() 197 { 198 register struct inode *ip; 199 register struct a { 200 char *fname; 201 int fmode; 202 int dev; 203 } *uap; 204 205 uap = (struct a *)u.u_ap; 206 if (suser()) { 207 ip = namei(uchar, CREATE, 0); 208 if (ip != NULL) { 209 u.u_error = EEXIST; 210 goto out; 211 } 212 } 213 if (u.u_error) 214 return; 215 ip = maknode(uap->fmode); 216 if (ip == NULL) 217 return; 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 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 fp = getf(uap->fd); 371 if (fp == NULL) 372 return; 373 if (fp->f_type == DTYPE_SOCKET) { 374 u.u_error = ESPIPE; 375 return; 376 } 377 if (uap->sbase == FSEEK_RELATIVE) 378 uap->off += fp->f_offset; 379 else if (uap->sbase == FSEEK_EOF) 380 uap->off += fp->f_inode->i_size; 381 fp->f_offset = uap->off; 382 u.u_r.r_off = uap->off; 383 } 384 385 /* 386 * Access system call 387 */ 388 saccess() 389 { 390 register svuid, svgid; 391 register struct inode *ip; 392 register struct a { 393 char *fname; 394 int fmode; 395 } *uap; 396 397 uap = (struct a *)u.u_ap; 398 svuid = u.u_uid; 399 svgid = u.u_gid; 400 u.u_uid = u.u_ruid; 401 u.u_gid = u.u_rgid; 402 ip = namei(uchar, LOOKUP, 1); 403 if (ip != NULL) { 404 if ((uap->fmode&FACCESS_READ) && access(ip, IREAD)) 405 goto done; 406 if ((uap->fmode&FACCESS_WRITE) && access(ip, IWRITE)) 407 goto done; 408 if ((uap->fmode&FACCESS_EXECUTE) && access(ip, IEXEC)) 409 goto done; 410 done: 411 iput(ip); 412 } 413 u.u_uid = svuid; 414 u.u_gid = svgid; 415 } 416 417 /* 418 * the fstat system call. 419 */ 420 fstat() 421 { 422 register struct file *fp; 423 register struct a { 424 int fd; 425 struct stat *sb; 426 } *uap; 427 428 uap = (struct a *)u.u_ap; 429 fp = getf(uap->fd); 430 if (fp == NULL) 431 return; 432 if (fp->f_type == DTYPE_SOCKET) 433 u.u_error = sostat(fp->f_socket, uap->sb); 434 else 435 stat1(fp->f_inode, uap->sb); 436 } 437 438 /* 439 * Stat system call. This version follows links. 440 */ 441 stat() 442 { 443 register struct inode *ip; 444 register struct a { 445 char *fname; 446 struct stat *sb; 447 } *uap; 448 449 uap = (struct a *)u.u_ap; 450 ip = namei(uchar, LOOKUP, 1); 451 if (ip == NULL) 452 return; 453 stat1(ip, uap->sb); 454 iput(ip); 455 } 456 457 /* 458 * Lstat system call. This version does not follow links. 459 */ 460 lstat() 461 { 462 register struct inode *ip; 463 register struct a { 464 char *fname; 465 struct stat *sb; 466 } *uap; 467 468 uap = (struct a *)u.u_ap; 469 ip = namei(uchar, LOOKUP, 0); 470 if (ip == NULL) 471 return; 472 stat1(ip, uap->sb); 473 iput(ip); 474 } 475 476 /* 477 * The basic routine for fstat and stat: 478 * get the inode and pass appropriate parts back. 479 */ 480 stat1(ip, ub) 481 register struct inode *ip; 482 struct stat *ub; 483 { 484 struct stat ds; 485 486 IUPDAT(ip, &time, &time, 0); 487 /* 488 * Copy from inode table 489 */ 490 ds.st_dev = ip->i_dev; 491 ds.st_ino = ip->i_number; 492 ds.st_mode = ip->i_mode; 493 ds.st_nlink = ip->i_nlink; 494 ds.st_uid = ip->i_uid; 495 ds.st_gid = ip->i_gid; 496 ds.st_rdev = (dev_t)ip->i_rdev; 497 ds.st_size = ip->i_size; 498 ds.st_atime = ip->i_atime; 499 ds.st_spare1 = 0; 500 ds.st_mtime = ip->i_mtime; 501 ds.st_spare2 = 0; 502 ds.st_ctime = ip->i_ctime; 503 ds.st_spare3 = 0; 504 /* this doesn't belong here */ 505 if ((ip->i_mode&IFMT) == IFBLK) 506 ds.st_blksize = BLKDEV_IOSIZE; 507 else if ((ip->i_mode&IFMT) == IFCHR) 508 ds.st_blksize = MAXBSIZE; 509 else 510 ds.st_blksize = ip->i_fs->fs_bsize; 511 ds.st_spare4[0] = ds.st_spare4[1] = ds.st_spare4[2] = 0; 512 u.u_error = copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)); 513 } 514 515 /* 516 * Return target name of a symbolic link 517 */ 518 readlink() 519 { 520 register struct inode *ip; 521 register struct a { 522 char *name; 523 char *buf; 524 int count; 525 } *uap = (struct a *)u.u_ap; 526 int resid; 527 528 ip = namei(uchar, LOOKUP, 0); 529 if (ip == NULL) 530 return; 531 if ((ip->i_mode&IFMT) != IFLNK) { 532 u.u_error = ENXIO; 533 goto out; 534 } 535 u.u_error = rdwri(UIO_READ, ip, uap->buf, uap->count, 0, 0, &resid); 536 out: 537 iput(ip); 538 u.u_r.r_val1 = uap->count - resid; 539 } 540 541 /* 542 * Change mode of a file given path name. 543 */ 544 chmod() 545 { 546 struct inode *ip; 547 struct a { 548 char *fname; 549 int fmode; 550 } *uap; 551 552 uap = (struct a *)u.u_ap; 553 if ((ip = owner(1)) == NULL) 554 return; 555 chmod1(ip, uap->fmode); 556 iput(ip); 557 } 558 559 /* 560 * Change mode of a file given a file descriptor. 561 */ 562 fchmod() 563 { 564 struct a { 565 int fd; 566 int fmode; 567 } *uap; 568 register struct inode *ip; 569 register struct file *fp; 570 571 uap = (struct a *)u.u_ap; 572 fp = getf(uap->fd); 573 if (fp == NULL) 574 return; 575 if (fp->f_type == DTYPE_SOCKET) { 576 u.u_error = EINVAL; 577 return; 578 } 579 ip = fp->f_inode; 580 if (u.u_uid != ip->i_uid && !suser()) 581 return; 582 ilock(ip); 583 chmod1(ip, uap->fmode); 584 iunlock(ip); 585 } 586 587 /* 588 * Change the mode on a file. 589 * Inode must be locked before calling. 590 */ 591 chmod1(ip, mode) 592 register struct inode *ip; 593 register int mode; 594 { 595 register int *gp; 596 597 ip->i_mode &= ~07777; 598 if (u.u_uid) { 599 mode &= ~ISVTX; 600 if (!groupmember(ip->i_gid)) 601 mode &= ~ISGID; 602 #ifdef MUSH 603 if (u.u_quota->q_syflags & QF_UMASK && 604 (ip->i_mode & IFMT) != IFCHR) 605 mode &= ~u.u_cmask; 606 #endif 607 } 608 ip->i_mode |= mode&07777; 609 ip->i_flag |= ICHG; 610 if (ip->i_flag&ITEXT && (ip->i_mode&ISVTX)==0) 611 xrele(ip); 612 } 613 614 /* 615 * Set ownership given a path name. 616 */ 617 chown() 618 { 619 struct inode *ip; 620 struct a { 621 char *fname; 622 int uid; 623 int gid; 624 } *uap; 625 626 uap = (struct a *)u.u_ap; 627 if ((ip = owner(0)) == NULL) 628 return; 629 u.u_error = chown1(ip, uap->uid, uap->gid); 630 iput(ip); 631 } 632 633 /* 634 * Set ownership given a file descriptor. 635 */ 636 fchown() 637 { 638 struct a { 639 int fd; 640 int uid; 641 int gid; 642 } *uap; 643 register struct inode *ip; 644 register struct file *fp; 645 646 uap = (struct a *)u.u_ap; 647 fp = getf(uap->fd); 648 if (fp == NULL) 649 return; 650 if (fp->f_type == DTYPE_SOCKET) { 651 u.u_error = EINVAL; 652 return; 653 } 654 ip = fp->f_inode; 655 if (ip->i_uid != u.u_uid && !suser()) 656 return; 657 ilock(ip); 658 u.u_error = chown1(ip, uap->uid, uap->gid); 659 iunlock(ip); 660 } 661 662 /* 663 * Perform chown operation on inode ip; 664 * inode must be locked prior to call. 665 */ 666 chown1(ip, uid, gid) 667 register struct inode *ip; 668 int uid, gid; 669 { 670 #ifdef QUOTA 671 register long change; 672 #endif 673 674 if (uid == -1) 675 uid = ip->i_uid; 676 if (gid == -1) 677 gid = ip->i_gid; 678 if (u.u_uid && ip->i_gid != gid && !groupmember(gid)) 679 return (EPERM); 680 #ifdef QUOTA 681 /* 682 * This doesn't allow for holes in files (which hopefully don't 683 * happen often in files that we chown), and is not accurate anyway 684 * (eg: it totally ignores 3 level indir blk files - but hopefully 685 * noone who can make a file that big will have a quota) 686 */ 687 if (ip->i_uid == uid) 688 change = 0; 689 else { 690 register struct fs *fs = ip->i_fs; 691 692 if (ip->i_size > (change = NDADDR * fs->fs_bsize)) { 693 register off_t size; 694 695 size = blkroundup(fs, ip->i_size) - change; 696 change += size; 697 change += fs->fs_bsize; 698 /* this assumes NIADDR <= 2 */ 699 if (size > NINDIR(fs) * fs->fs_bsize) 700 change += fs->fs_bsize; 701 } else 702 change = fragroundup(fs, ip->i_size); 703 change /= DEV_BSIZE; 704 } 705 (void)chkdq(ip, -change, 1); 706 (void)chkiq(ip->i_dev, ip, ip->i_uid, 1); 707 dqrele(ip->i_dquot); 708 #endif 709 ip->i_uid = uid; 710 ip->i_gid = gid; 711 ip->i_flag |= ICHG; 712 if (u.u_ruid != 0) 713 ip->i_mode &= ~(ISUID|ISGID); 714 #ifdef QUOTA 715 ip->i_dquot = inoquota(ip); 716 (void)chkdq(ip, change, 1); 717 (void)chkiq(ip->i_dev, (struct inode *)NULL, uid, 1); 718 return (u.u_error); 719 #endif 720 return (0); 721 } 722 723 #ifndef NOCOMPAT 724 /* 725 * Set IUPD and IACC times on file. 726 * Can't set ICHG. 727 */ 728 outime() 729 { 730 register struct a { 731 char *fname; 732 time_t *tptr; 733 } *uap = (struct a *)u.u_ap; 734 register struct inode *ip; 735 time_t tv[2]; 736 struct timeval tv0, tv1; 737 738 if ((ip = owner(1)) == NULL) 739 return; 740 u.u_error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)); 741 if (u.u_error == 0) { 742 ip->i_flag |= IACC|IUPD|ICHG; 743 tv0.tv_sec = tv[0]; tv0.tv_usec = 0; 744 tv1.tv_sec = tv[1]; tv1.tv_usec = 0; 745 iupdat(ip, &tv0, &tv1, 0); 746 } 747 iput(ip); 748 } 749 #endif 750 751 utimes() 752 { 753 register struct a { 754 char *fname; 755 struct timeval *tptr; 756 } *uap = (struct a *)u.u_ap; 757 register struct inode *ip; 758 struct timeval tv[2]; 759 760 if ((ip = owner(1)) == NULL) 761 return; 762 u.u_error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)); 763 if (u.u_error == 0) { 764 ip->i_flag |= IACC|IUPD|ICHG; 765 iupdat(ip, &tv[0], &tv[1], 0); 766 } 767 iput(ip); 768 } 769 770 /* 771 * Flush any pending I/O. 772 */ 773 sync() 774 { 775 776 update(); 777 } 778 779 /* 780 * Apply an advisory lock on a file descriptor. 781 */ 782 flock() 783 { 784 struct a { 785 int fd; 786 int how; 787 } *uap; 788 register struct file *fp; 789 register int cmd, flags; 790 791 uap = (struct a *)u.u_ap; 792 fp = getf(uap->fd); 793 if (fp == NULL) 794 return; 795 if (fp->f_type == DTYPE_SOCKET) { /* XXX */ 796 u.u_error = EINVAL; 797 return; 798 } 799 cmd = uap->how; 800 flags = u.u_pofile[uap->fd] & (UF_SHLOCK|UF_EXLOCK); 801 if (cmd&FUNLOCK) { 802 if (flags == 0) { 803 u.u_error = EINVAL; 804 return; 805 } 806 funlocki(fp->f_inode, flags); 807 u.u_pofile[uap->fd] &= ~(UF_SHLOCK|UF_EXLOCK); 808 return; 809 } 810 /* 811 * No reason to write lock a file we've already 812 * write locked, similarly with a read lock. 813 */ 814 if ((flags&UF_EXLOCK) && (cmd&FEXLOCK) || 815 (flags&UF_SHLOCK) && (cmd&FSHLOCK)) 816 return; 817 u.u_pofile[uap->fd] = flocki(fp->f_inode, u.u_pofile[uap->fd], cmd); 818 } 819 820 /* 821 * Truncate a file given its path name. 822 */ 823 truncate() 824 { 825 struct a { 826 char *fname; 827 u_long length; 828 } *uap = (struct a *)u.u_ap; 829 struct inode *ip; 830 831 ip = namei(uchar, LOOKUP, 1); 832 if (ip == NULL) 833 return; 834 if (access(ip, IWRITE)) 835 goto bad; 836 if ((ip->i_mode&IFMT) == IFDIR) { 837 u.u_error = EISDIR; 838 goto bad; 839 } 840 itrunc(ip, uap->length); 841 bad: 842 iput(ip); 843 } 844 845 /* 846 * Truncate a file given a file descriptor. 847 */ 848 ftruncate() 849 { 850 struct a { 851 int fd; 852 u_long length; 853 } *uap = (struct a *)u.u_ap; 854 struct inode *ip; 855 struct file *fp; 856 857 fp = getf(uap->fd); 858 if (fp == NULL) 859 return; 860 if (fp->f_type == DTYPE_SOCKET) { 861 u.u_error = EINVAL; 862 return; 863 } 864 if ((fp->f_flag&FWRITE) == 0) { 865 u.u_error = EINVAL; 866 return; 867 } 868 ip = fp->f_inode; 869 ilock(ip); 870 itrunc(ip, uap->length); 871 iunlock(ip); 872 } 873 874 /* 875 * Synch an open file. 876 */ 877 fsync() 878 { 879 struct a { 880 int fd; 881 } *uap = (struct a *)u.u_ap; 882 struct inode *ip; 883 struct file *fp; 884 885 fp = getf(uap->fd); 886 if (fp == NULL) 887 return; 888 if (fp->f_type == DTYPE_SOCKET) { 889 u.u_error = EINVAL; 890 return; 891 } 892 ip = fp->f_inode; 893 ilock(ip); 894 syncip(ip); 895 iunlock(ip); 896 } 897 898 /* 899 * Rename system call. 900 * rename("foo", "bar"); 901 * is essentially 902 * unlink("bar"); 903 * link("foo", "bar"); 904 * unlink("foo"); 905 * but ``atomically''. Can't do full commit without saving state in the 906 * inode on disk which isn't feasible at this time. Best we can do is 907 * always guarantee the target exists. 908 * 909 * Basic algorithm is: 910 * 911 * 1) Bump link count on source while we're linking it to the 912 * target. This also insure the inode won't be deleted out 913 * from underneath us while we work. 914 * 2) Link source to destination. If destination already exists, 915 * delete it first. 916 * 3) Unlink source reference to inode if still around. 917 * 4) If a directory was moved and the parent of the destination 918 * is different from the source, patch the ".." entry in the 919 * directory. 920 * 921 * Source and destination must either both be directories, or both 922 * not be directories. If target is a directory, it must be empty. 923 */ 924 rename() 925 { 926 struct a { 927 char *from; 928 char *to; 929 } *uap; 930 register struct inode *ip, *xp, *dp; 931 int oldparent, parentdifferent, doingdirectory; 932 int error = 0; 933 934 uap = (struct a *)u.u_ap; 935 ip = namei(uchar, DELETE | LOCKPARENT, 0); 936 if (ip == NULL) 937 return; 938 dp = u.u_pdir; 939 oldparent = 0, doingdirectory = 0; 940 if ((ip->i_mode&IFMT) == IFDIR) { 941 register struct direct *d; 942 943 d = &u.u_dent; 944 /* 945 * Avoid ".", "..", and aliases of "." for obvious reasons. 946 */ 947 if ((d->d_namlen == 1 && d->d_name[0] == '.') || 948 (d->d_namlen == 2 && bcmp(d->d_name, "..", 2) == 0) || 949 (dp == ip)) { 950 iput(dp); 951 if (dp == ip) 952 irele(ip); 953 else 954 iput(ip); 955 u.u_error = EINVAL; 956 return; 957 } 958 oldparent = dp->i_number; 959 doingdirectory++; 960 } 961 iput(dp); 962 963 /* 964 * 1) Bump link count while we're moving stuff 965 * around. If we crash somewhere before 966 * completing our work, the link count 967 * may be wrong, but correctable. 968 */ 969 ip->i_nlink++; 970 ip->i_flag |= ICHG; 971 iupdat(ip, &time, &time, 1); 972 iunlock(ip); 973 974 /* 975 * When the target exists, both the directory 976 * and target inodes are returned locked. 977 */ 978 u.u_dirp = (caddr_t)uap->to; 979 xp = namei(uchar, CREATE | LOCKPARENT, 0); 980 if (u.u_error) { 981 error = u.u_error; 982 goto out; 983 } 984 dp = u.u_pdir; 985 /* 986 * If ".." must be changed (ie the directory gets a new 987 * parent) then the user must have write permission. 988 */ 989 parentdifferent = oldparent != dp->i_number; 990 if (doingdirectory && parentdifferent && access(ip, IWRITE)) 991 goto bad; 992 /* 993 * 2) If target doesn't exist, link the target 994 * to the source and unlink the source. 995 * Otherwise, rewrite the target directory 996 * entry to reference the source inode and 997 * expunge the original entry's existence. 998 */ 999 if (xp == NULL) { 1000 if (dp->i_dev != ip->i_dev) { 1001 error = EXDEV; 1002 goto bad; 1003 } 1004 /* 1005 * Disallow rename(foo, foo/bar). 1006 */ 1007 if (dp->i_number == ip->i_number) { 1008 error = EEXIST; 1009 goto bad; 1010 } 1011 /* 1012 * Account for ".." in directory. 1013 * When source and destination have the 1014 * same parent we don't fool with the 1015 * link count -- this isn't required 1016 * because we do a similar check below. 1017 */ 1018 if (doingdirectory && parentdifferent) { 1019 dp->i_nlink++; 1020 dp->i_flag |= ICHG; 1021 iupdat(dp, &time, &time, 1); 1022 } 1023 error = direnter(ip); 1024 if (error) 1025 goto out; 1026 } else { 1027 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) { 1028 error = EXDEV; 1029 goto bad; 1030 } 1031 /* 1032 * Short circuit rename(foo, foo). 1033 */ 1034 if (xp->i_number == ip->i_number) 1035 goto bad; 1036 /* 1037 * Target must be empty if a directory 1038 * and have no links to it. 1039 * Also, insure source and target are 1040 * compatible (both directories, or both 1041 * not directories). 1042 */ 1043 if ((xp->i_mode&IFMT) == IFDIR) { 1044 if (!dirempty(xp) || xp->i_nlink > 2) { 1045 error = ENOTEMPTY; 1046 goto bad; 1047 } 1048 if (!doingdirectory) { 1049 error = ENOTDIR; 1050 goto bad; 1051 } 1052 } else if (doingdirectory) { 1053 error = EISDIR; 1054 goto bad; 1055 } 1056 dirrewrite(dp, ip); 1057 if (u.u_error) { 1058 error = u.u_error; 1059 goto bad1; 1060 } 1061 /* 1062 * Adjust the link count of the target to 1063 * reflect the dirrewrite above. If this is 1064 * a directory it is empty and there are 1065 * no links to it, so we can squash the inode and 1066 * any space associated with it. We disallowed 1067 * renaming over top of a directory with links to 1068 * it above, as we've no way to determine if 1069 * we've got a link or the directory itself, and 1070 * if we get a link, then ".." will be screwed up. 1071 */ 1072 xp->i_nlink--; 1073 if (doingdirectory) { 1074 if (--xp->i_nlink != 0) 1075 panic("rename: linked directory"); 1076 itrunc(xp, (u_long)0); 1077 } 1078 xp->i_flag |= ICHG; 1079 iput(xp); 1080 xp = NULL; 1081 } 1082 1083 /* 1084 * 3) Unlink the source. 1085 */ 1086 u.u_dirp = uap->from; 1087 dp = namei(uchar, DELETE, 0); 1088 /* 1089 * Insure directory entry still exists and 1090 * has not changed since the start of all 1091 * this. If either has occured, forget about 1092 * about deleting the original entry and just 1093 * adjust the link count in the inode. 1094 */ 1095 if (dp == NULL || u.u_dent.d_ino != ip->i_number) { 1096 ip->i_nlink--; 1097 ip->i_flag |= ICHG; 1098 } else { 1099 /* 1100 * If source is a directory, must adjust 1101 * link count of parent directory also. 1102 * If target didn't exist and source and 1103 * target have the same parent, then we 1104 * needn't touch the link count, it all 1105 * balances out in the end. Otherwise, we 1106 * must do so to reflect deletion of ".." 1107 * done above. 1108 */ 1109 if (doingdirectory && (xp != NULL || parentdifferent)) { 1110 dp->i_nlink--; 1111 dp->i_flag |= ICHG; 1112 } 1113 if (dirremove()) { 1114 ip->i_nlink--; 1115 ip->i_flag |= ICHG; 1116 } 1117 if (error == 0) /* conservative */ 1118 error = u.u_error; 1119 } 1120 irele(ip); 1121 if (dp) 1122 iput(dp); 1123 1124 /* 1125 * 4) Renaming a directory with the parent 1126 * different requires ".." to be rewritten. 1127 * The window is still there for ".." to 1128 * be inconsistent, but this is unavoidable, 1129 * and a lot shorter than when it was done 1130 * in a user process. 1131 */ 1132 if (doingdirectory && parentdifferent && error == 0) { 1133 struct dirtemplate dirbuf; 1134 1135 u.u_dirp = uap->to; 1136 ip = namei(uchar, LOOKUP | LOCKPARENT, 0); 1137 if (ip == NULL) { 1138 printf("rename: .. went away\n"); 1139 return; 1140 } 1141 dp = u.u_pdir; 1142 if ((ip->i_mode&IFMT) != IFDIR) { 1143 printf("rename: .. not a directory\n"); 1144 goto stuck; 1145 } 1146 error = rdwri(UIO_READ, ip, (caddr_t)&dirbuf, 1147 sizeof (struct dirtemplate), (off_t)0, 1, (int *)0); 1148 if (error == 0) { 1149 dirbuf.dotdot_ino = dp->i_number; 1150 (void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf, 1151 sizeof (struct dirtemplate), (off_t)0, 1, (int *)0); 1152 } 1153 stuck: 1154 irele(dp); 1155 iput(ip); 1156 } 1157 goto done; 1158 1159 bad: 1160 iput(dp); 1161 bad1: 1162 if (xp) 1163 iput(xp); 1164 out: 1165 ip->i_nlink--; 1166 ip->i_flag |= ICHG; 1167 irele(ip); 1168 done: 1169 if (error) 1170 u.u_error = error; 1171 } 1172 1173 /* 1174 * Make a new file. 1175 */ 1176 struct inode * 1177 maknode(mode) 1178 int mode; 1179 { 1180 register struct inode *ip; 1181 ino_t ipref; 1182 1183 if ((mode & IFMT) == IFDIR) 1184 ipref = dirpref(u.u_pdir->i_fs); 1185 else 1186 ipref = u.u_pdir->i_number; 1187 ip = ialloc(u.u_pdir, ipref, mode); 1188 if (ip == NULL) { 1189 iput(u.u_pdir); 1190 return (NULL); 1191 } 1192 #ifdef QUOTA 1193 if (ip->i_dquot != NODQUOT) 1194 panic("maknode: dquot"); 1195 #endif 1196 ip->i_flag |= IACC|IUPD|ICHG; 1197 if ((mode & IFMT) == 0) 1198 mode |= IFREG; 1199 ip->i_mode = mode & ~u.u_cmask; 1200 ip->i_nlink = 1; 1201 ip->i_uid = u.u_uid; 1202 ip->i_gid = u.u_pdir->i_gid; 1203 if (ip->i_mode & ISGID && !groupmember(ip->i_gid)) 1204 ip->i_mode &= ~ISGID; 1205 #ifdef QUOTA 1206 ip->i_dquot = inoquota(ip); 1207 #endif 1208 1209 /* 1210 * Make sure inode goes to disk before directory entry. 1211 */ 1212 iupdat(ip, &time, &time, 1); 1213 u.u_error = direnter(ip); 1214 if (u.u_error) { 1215 /* 1216 * Write error occurred trying to update directory 1217 * so must deallocate the inode. 1218 */ 1219 ip->i_nlink = 0; 1220 ip->i_flag |= ICHG; 1221 iput(ip); 1222 return (NULL); 1223 } 1224 return (ip); 1225 } 1226