1 /* 2 * Copyright (c) 1982 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)vfs_syscalls.c 6.21 (Berkeley) 09/05/85 7 */ 8 9 #include "param.h" 10 #include "systm.h" 11 #include "dir.h" 12 #include "user.h" 13 #include "kernel.h" 14 #include "file.h" 15 #include "stat.h" 16 #include "inode.h" 17 #include "fs.h" 18 #include "buf.h" 19 #include "proc.h" 20 #include "quota.h" 21 #include "uio.h" 22 #include "socket.h" 23 #include "socketvar.h" 24 #include "mount.h" 25 26 extern struct fileops inodeops; 27 struct file *getinode(); 28 29 /* 30 * Change current working directory (``.''). 31 */ 32 chdir() 33 { 34 35 chdirec(&u.u_cdir); 36 } 37 38 /* 39 * Change notion of root (``/'') directory. 40 */ 41 chroot() 42 { 43 44 if (suser()) 45 chdirec(&u.u_rdir); 46 } 47 48 /* 49 * Common routine for chroot and chdir. 50 */ 51 chdirec(ipp) 52 register struct inode **ipp; 53 { 54 register struct inode *ip; 55 struct a { 56 char *fname; 57 } *uap = (struct a *)u.u_ap; 58 register struct nameidata *ndp = &u.u_nd; 59 60 ndp->ni_nameiop = LOOKUP | FOLLOW; 61 ndp->ni_segflg = UIO_USERSPACE; 62 ndp->ni_dirp = uap->fname; 63 ip = namei(ndp); 64 if (ip == NULL) 65 return; 66 if ((ip->i_mode&IFMT) != IFDIR) { 67 u.u_error = ENOTDIR; 68 goto bad; 69 } 70 if (access(ip, IEXEC)) 71 goto bad; 72 IUNLOCK(ip); 73 if (*ipp) 74 irele(*ipp); 75 *ipp = ip; 76 return; 77 78 bad: 79 iput(ip); 80 } 81 82 /* 83 * Open system call. 84 */ 85 open() 86 { 87 struct a { 88 char *fname; 89 int mode; 90 int crtmode; 91 } *uap = (struct a *) u.u_ap; 92 93 copen(uap->mode-FOPEN, uap->crtmode, uap->fname); 94 } 95 96 /* 97 * Creat system call. 98 */ 99 creat() 100 { 101 struct a { 102 char *fname; 103 int fmode; 104 } *uap = (struct a *)u.u_ap; 105 106 copen(FWRITE|FCREAT|FTRUNC, uap->fmode, uap->fname); 107 } 108 109 /* 110 * Common code for open and creat. 111 * Check permissions, allocate an open file structure, 112 * and call the device open routine if any. 113 */ 114 copen(mode, arg, fname) 115 register int mode; 116 int arg; 117 caddr_t fname; 118 { 119 register struct inode *ip; 120 register struct file *fp; 121 register struct nameidata *ndp = &u.u_nd; 122 int indx; 123 124 fp = falloc(); 125 if (fp == NULL) 126 return; 127 indx = u.u_r.r_val1; 128 ndp->ni_segflg = UIO_USERSPACE; 129 ndp->ni_dirp = fname; 130 if (mode&FCREAT) { 131 if (mode & FEXCL) 132 ndp->ni_nameiop = CREATE; 133 else 134 ndp->ni_nameiop = CREATE | FOLLOW; 135 ip = namei(ndp); 136 if (ip == NULL) { 137 if (u.u_error) 138 goto bad1; 139 ip = maknode(arg&07777&(~ISVTX), ndp); 140 if (ip == NULL) 141 goto bad1; 142 mode &= ~FTRUNC; 143 } else { 144 if (mode&FEXCL) { 145 u.u_error = EEXIST; 146 goto bad; 147 } 148 mode &= ~FCREAT; 149 } 150 } else { 151 ndp->ni_nameiop = LOOKUP | FOLLOW; 152 ip = namei(ndp); 153 if (ip == NULL) 154 goto bad1; 155 } 156 if ((ip->i_mode & IFMT) == IFSOCK) { 157 u.u_error = EOPNOTSUPP; 158 goto bad; 159 } 160 if ((mode&FCREAT) == 0) { 161 if (mode&FREAD) 162 if (access(ip, IREAD)) 163 goto bad; 164 if (mode&(FWRITE|FTRUNC)) { 165 if (access(ip, IWRITE)) 166 goto bad; 167 if ((ip->i_mode&IFMT) == IFDIR) { 168 u.u_error = EISDIR; 169 goto bad; 170 } 171 } 172 } 173 if (mode&FTRUNC) 174 itrunc(ip, (u_long)0); 175 IUNLOCK(ip); 176 fp->f_flag = mode&FMASK; 177 fp->f_type = DTYPE_INODE; 178 fp->f_ops = &inodeops; 179 fp->f_data = (caddr_t)ip; 180 if (setjmp(&u.u_qsave)) { 181 if (u.u_error == 0) 182 u.u_error = EINTR; 183 u.u_ofile[indx] = NULL; 184 closef(fp); 185 return; 186 } 187 u.u_error = openi(ip, mode); 188 if (u.u_error == 0) 189 return; 190 ILOCK(ip); 191 bad: 192 iput(ip); 193 bad1: 194 u.u_ofile[indx] = NULL; 195 fp->f_count--; 196 } 197 198 /* 199 * Mknod system call 200 */ 201 mknod() 202 { 203 register struct inode *ip; 204 register struct a { 205 char *fname; 206 int fmode; 207 int dev; 208 } *uap = (struct a *)u.u_ap; 209 register struct nameidata *ndp = &u.u_nd; 210 211 if (!suser()) 212 return; 213 ndp->ni_nameiop = CREATE; 214 ndp->ni_segflg = UIO_USERSPACE; 215 ndp->ni_dirp = uap->fname; 216 ip = namei(ndp); 217 if (ip != NULL) { 218 u.u_error = EEXIST; 219 goto out; 220 } 221 if (u.u_error) 222 return; 223 ip = maknode(uap->fmode, ndp); 224 if (ip == NULL) 225 return; 226 switch (ip->i_mode & IFMT) { 227 228 case IFMT: /* used by badsect to flag bad sectors */ 229 case IFCHR: 230 case IFBLK: 231 if (uap->dev) { 232 /* 233 * Want to be able to use this to make badblock 234 * inodes, so don't truncate the dev number. 235 */ 236 ip->i_rdev = uap->dev; 237 ip->i_flag |= IACC|IUPD|ICHG; 238 } 239 } 240 241 out: 242 iput(ip); 243 } 244 245 /* 246 * link system call 247 */ 248 link() 249 { 250 register struct inode *ip, *xp; 251 register struct a { 252 char *target; 253 char *linkname; 254 } *uap = (struct a *)u.u_ap; 255 register struct nameidata *ndp = &u.u_nd; 256 257 ndp->ni_nameiop = LOOKUP | FOLLOW; 258 ndp->ni_segflg = UIO_USERSPACE; 259 ndp->ni_dirp = uap->target; 260 ip = namei(ndp); /* well, this routine is doomed anyhow */ 261 if (ip == NULL) 262 return; 263 if ((ip->i_mode&IFMT) == IFDIR && !suser()) { 264 iput(ip); 265 return; 266 } 267 ip->i_nlink++; 268 ip->i_flag |= ICHG; 269 iupdat(ip, &time, &time, 1); 270 IUNLOCK(ip); 271 ndp->ni_nameiop = CREATE; 272 ndp->ni_segflg = UIO_USERSPACE; 273 ndp->ni_dirp = (caddr_t)uap->linkname; 274 xp = namei(ndp); 275 if (xp != NULL) { 276 u.u_error = EEXIST; 277 iput(xp); 278 goto out; 279 } 280 if (u.u_error) 281 goto out; 282 if (ndp->ni_pdir->i_dev != ip->i_dev) { 283 iput(ndp->ni_pdir); 284 u.u_error = EXDEV; 285 goto out; 286 } 287 u.u_error = direnter(ip, ndp); 288 out: 289 if (u.u_error) { 290 ip->i_nlink--; 291 ip->i_flag |= ICHG; 292 } 293 irele(ip); 294 } 295 296 /* 297 * symlink -- make a symbolic link 298 */ 299 symlink() 300 { 301 register struct a { 302 char *target; 303 char *linkname; 304 } *uap = (struct a *)u.u_ap; 305 register struct inode *ip; 306 register char *tp; 307 register c, nc; 308 register struct nameidata *ndp = &u.u_nd; 309 310 tp = uap->target; 311 nc = 0; 312 while (c = fubyte(tp)) { 313 if (c < 0) { 314 u.u_error = EFAULT; 315 return; 316 } 317 tp++; 318 nc++; 319 } 320 ndp->ni_nameiop = CREATE; 321 ndp->ni_segflg = UIO_USERSPACE; 322 ndp->ni_dirp = uap->linkname; 323 ip = namei(ndp); 324 if (ip) { 325 iput(ip); 326 u.u_error = EEXIST; 327 return; 328 } 329 if (u.u_error) 330 return; 331 ip = maknode(IFLNK | 0777, ndp); 332 if (ip == NULL) 333 return; 334 u.u_error = rdwri(UIO_WRITE, ip, uap->target, nc, 0, 0, (int *)0); 335 /* handle u.u_error != 0 */ 336 iput(ip); 337 } 338 339 /* 340 * Unlink system call. 341 * Hard to avoid races here, especially 342 * in unlinking directories. 343 */ 344 unlink() 345 { 346 struct a { 347 char *fname; 348 } *uap = (struct a *)u.u_ap; 349 register struct inode *ip, *dp; 350 register struct nameidata *ndp = &u.u_nd; 351 352 ndp->ni_nameiop = DELETE | LOCKPARENT; 353 ndp->ni_segflg = UIO_USERSPACE; 354 ndp->ni_dirp = uap->fname; 355 ip = namei(ndp); 356 if (ip == NULL) 357 return; 358 dp = ndp->ni_pdir; 359 if ((ip->i_mode&IFMT) == IFDIR && !suser()) 360 goto out; 361 /* 362 * Don't unlink a mounted file. 363 */ 364 if (ip->i_dev != dp->i_dev) { 365 u.u_error = EBUSY; 366 goto out; 367 } 368 if (ip->i_flag&ITEXT) 369 xrele(ip); /* try once to free text */ 370 if (dirremove(ndp)) { 371 ip->i_nlink--; 372 ip->i_flag |= ICHG; 373 } 374 out: 375 if (dp == ip) 376 irele(ip); 377 else 378 iput(ip); 379 iput(dp); 380 } 381 382 /* 383 * Seek system call 384 */ 385 lseek() 386 { 387 register struct file *fp; 388 register struct a { 389 int fd; 390 off_t off; 391 int sbase; 392 } *uap = (struct a *)u.u_ap; 393 394 GETF(fp, uap->fd); 395 if (fp->f_type != DTYPE_INODE) { 396 u.u_error = ESPIPE; 397 return; 398 } 399 switch (uap->sbase) { 400 401 case L_INCR: 402 fp->f_offset += uap->off; 403 break; 404 405 case L_XTND: 406 fp->f_offset = uap->off + ((struct inode *)fp->f_data)->i_size; 407 break; 408 409 case L_SET: 410 fp->f_offset = uap->off; 411 break; 412 413 default: 414 u.u_error = EINVAL; 415 return; 416 } 417 u.u_r.r_off = fp->f_offset; 418 } 419 420 /* 421 * Access system call 422 */ 423 saccess() 424 { 425 register svuid, svgid; 426 register struct inode *ip; 427 register struct a { 428 char *fname; 429 int fmode; 430 } *uap = (struct a *)u.u_ap; 431 register struct nameidata *ndp = &u.u_nd; 432 433 svuid = u.u_uid; 434 svgid = u.u_gid; 435 u.u_uid = u.u_ruid; 436 u.u_gid = u.u_rgid; 437 ndp->ni_nameiop = LOOKUP | FOLLOW; 438 ndp->ni_segflg = UIO_USERSPACE; 439 ndp->ni_dirp = uap->fname; 440 ip = namei(ndp); 441 if (ip != NULL) { 442 if ((uap->fmode&R_OK) && access(ip, IREAD)) 443 goto done; 444 if ((uap->fmode&W_OK) && access(ip, IWRITE)) 445 goto done; 446 if ((uap->fmode&X_OK) && access(ip, IEXEC)) 447 goto done; 448 done: 449 iput(ip); 450 } 451 u.u_uid = svuid; 452 u.u_gid = svgid; 453 } 454 455 /* 456 * Stat system call. This version follows links. 457 */ 458 stat() 459 { 460 461 stat1(FOLLOW); 462 } 463 464 /* 465 * Lstat system call. This version does not follow links. 466 */ 467 lstat() 468 { 469 470 stat1(NOFOLLOW); 471 } 472 473 stat1(follow) 474 int follow; 475 { 476 register struct inode *ip; 477 register struct a { 478 char *fname; 479 struct stat *ub; 480 } *uap = (struct a *)u.u_ap; 481 struct stat sb; 482 register struct nameidata *ndp = &u.u_nd; 483 484 ndp->ni_nameiop = LOOKUP | follow; 485 ndp->ni_segflg = UIO_USERSPACE; 486 ndp->ni_dirp = uap->fname; 487 ip = namei(ndp); 488 if (ip == NULL) 489 return; 490 (void) ino_stat(ip, &sb); 491 iput(ip); 492 u.u_error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb)); 493 } 494 495 /* 496 * Return target name of a symbolic link 497 */ 498 readlink() 499 { 500 register struct inode *ip; 501 register struct a { 502 char *name; 503 char *buf; 504 int count; 505 } *uap = (struct a *)u.u_ap; 506 register struct nameidata *ndp = &u.u_nd; 507 int resid; 508 509 ndp->ni_nameiop = LOOKUP; 510 ndp->ni_segflg = UIO_USERSPACE; 511 ndp->ni_dirp = uap->name; 512 ip = namei(ndp); 513 if (ip == NULL) 514 return; 515 if ((ip->i_mode&IFMT) != IFLNK) { 516 u.u_error = EINVAL; 517 goto out; 518 } 519 u.u_error = rdwri(UIO_READ, ip, uap->buf, uap->count, 0, 0, &resid); 520 out: 521 iput(ip); 522 u.u_r.r_val1 = uap->count - resid; 523 } 524 525 /* 526 * Change mode of a file given path name. 527 */ 528 chmod() 529 { 530 struct inode *ip; 531 struct a { 532 char *fname; 533 int fmode; 534 } *uap = (struct a *)u.u_ap; 535 536 if ((ip = owner(uap->fname, FOLLOW)) == NULL) 537 return; 538 u.u_error = chmod1(ip, uap->fmode); 539 iput(ip); 540 } 541 542 /* 543 * Change mode of a file given a file descriptor. 544 */ 545 fchmod() 546 { 547 struct a { 548 int fd; 549 int fmode; 550 } *uap = (struct a *)u.u_ap; 551 register struct inode *ip; 552 register struct file *fp; 553 554 fp = getinode(uap->fd); 555 if (fp == NULL) 556 return; 557 ip = (struct inode *)fp->f_data; 558 if (u.u_uid != ip->i_uid && !suser()) 559 return; 560 ILOCK(ip); 561 u.u_error = chmod1(ip, uap->fmode); 562 IUNLOCK(ip); 563 } 564 565 /* 566 * Change the mode on a file. 567 * Inode must be locked before calling. 568 */ 569 chmod1(ip, mode) 570 register struct inode *ip; 571 register int mode; 572 { 573 574 if (ip->i_fs->fs_ronly) 575 return (EROFS); 576 ip->i_mode &= ~07777; 577 if (u.u_uid) { 578 if ((ip->i_mode & IFMT) != IFDIR) 579 mode &= ~ISVTX; 580 if (!groupmember(ip->i_gid)) 581 mode &= ~ISGID; 582 } 583 ip->i_mode |= mode&07777; 584 ip->i_flag |= ICHG; 585 if (ip->i_flag&ITEXT && (ip->i_mode&ISVTX)==0) 586 xrele(ip); 587 return (0); 588 } 589 590 /* 591 * Set ownership given a path name. 592 */ 593 chown() 594 { 595 struct inode *ip; 596 struct a { 597 char *fname; 598 int uid; 599 int gid; 600 } *uap = (struct a *)u.u_ap; 601 602 if (!suser() || (ip = owner(uap->fname, NOFOLLOW)) == NULL) 603 return; 604 u.u_error = chown1(ip, uap->uid, uap->gid); 605 iput(ip); 606 } 607 608 /* 609 * Set ownership given a file descriptor. 610 */ 611 fchown() 612 { 613 struct a { 614 int fd; 615 int uid; 616 int gid; 617 } *uap = (struct a *)u.u_ap; 618 register struct inode *ip; 619 register struct file *fp; 620 621 fp = getinode(uap->fd); 622 if (fp == NULL) 623 return; 624 ip = (struct inode *)fp->f_data; 625 if (!suser()) 626 return; 627 ILOCK(ip); 628 u.u_error = chown1(ip, uap->uid, uap->gid); 629 IUNLOCK(ip); 630 } 631 632 /* 633 * Perform chown operation on inode ip; 634 * inode must be locked prior to call. 635 */ 636 chown1(ip, uid, gid) 637 register struct inode *ip; 638 int uid, gid; 639 { 640 #ifdef QUOTA 641 register long change; 642 #endif 643 644 if (ip->i_fs->fs_ronly) 645 return (EROFS); 646 if (uid == -1) 647 uid = ip->i_uid; 648 if (gid == -1) 649 gid = ip->i_gid; 650 #ifdef QUOTA 651 if (ip->i_uid == uid) /* this just speeds things a little */ 652 change = 0; 653 else 654 change = ip->i_blocks; 655 (void) chkdq(ip, -change, 1); 656 (void) chkiq(ip->i_dev, ip, ip->i_uid, 1); 657 dqrele(ip->i_dquot); 658 #endif 659 ip->i_uid = uid; 660 ip->i_gid = gid; 661 ip->i_flag |= ICHG; 662 if (u.u_ruid != 0) 663 ip->i_mode &= ~(ISUID|ISGID); 664 #ifdef QUOTA 665 ip->i_dquot = inoquota(ip); 666 (void) chkdq(ip, change, 1); 667 (void) chkiq(ip->i_dev, (struct inode *)NULL, uid, 1); 668 return (u.u_error); /* should == 0 ALWAYS !! */ 669 #else 670 return (0); 671 #endif 672 } 673 674 utimes() 675 { 676 register struct a { 677 char *fname; 678 struct timeval *tptr; 679 } *uap = (struct a *)u.u_ap; 680 register struct inode *ip; 681 struct timeval tv[2]; 682 683 if ((ip = owner(uap->fname, FOLLOW)) == NULL) 684 return; 685 if (ip->i_fs->fs_ronly) { 686 u.u_error = EROFS; 687 iput(ip); 688 return; 689 } 690 u.u_error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)); 691 if (u.u_error == 0) { 692 ip->i_flag |= IACC|IUPD|ICHG; 693 iupdat(ip, &tv[0], &tv[1], 0); 694 } 695 iput(ip); 696 } 697 698 /* 699 * Flush any pending I/O. 700 */ 701 sync() 702 { 703 704 update(); 705 } 706 707 /* 708 * Truncate a file given its path name. 709 */ 710 truncate() 711 { 712 struct a { 713 char *fname; 714 u_long length; 715 } *uap = (struct a *)u.u_ap; 716 struct inode *ip; 717 register struct nameidata *ndp = &u.u_nd; 718 719 ndp->ni_nameiop = LOOKUP | FOLLOW; 720 ndp->ni_segflg = UIO_USERSPACE; 721 ndp->ni_dirp = uap->fname; 722 ip = namei(ndp); 723 if (ip == NULL) 724 return; 725 if (access(ip, IWRITE)) 726 goto bad; 727 if ((ip->i_mode&IFMT) == IFDIR) { 728 u.u_error = EISDIR; 729 goto bad; 730 } 731 itrunc(ip, uap->length); 732 bad: 733 iput(ip); 734 } 735 736 /* 737 * Truncate a file given a file descriptor. 738 */ 739 ftruncate() 740 { 741 struct a { 742 int fd; 743 u_long length; 744 } *uap = (struct a *)u.u_ap; 745 struct inode *ip; 746 struct file *fp; 747 748 fp = getinode(uap->fd); 749 if (fp == NULL) 750 return; 751 if ((fp->f_flag&FWRITE) == 0) { 752 u.u_error = EINVAL; 753 return; 754 } 755 ip = (struct inode *)fp->f_data; 756 ILOCK(ip); 757 itrunc(ip, uap->length); 758 IUNLOCK(ip); 759 } 760 761 /* 762 * Synch an open file. 763 */ 764 fsync() 765 { 766 struct a { 767 int fd; 768 } *uap = (struct a *)u.u_ap; 769 struct inode *ip; 770 struct file *fp; 771 772 fp = getinode(uap->fd); 773 if (fp == NULL) 774 return; 775 ip = (struct inode *)fp->f_data; 776 ILOCK(ip); 777 syncip(ip); 778 IUNLOCK(ip); 779 } 780 781 /* 782 * Rename system call. 783 * rename("foo", "bar"); 784 * is essentially 785 * unlink("bar"); 786 * link("foo", "bar"); 787 * unlink("foo"); 788 * but ``atomically''. Can't do full commit without saving state in the 789 * inode on disk which isn't feasible at this time. Best we can do is 790 * always guarantee the target exists. 791 * 792 * Basic algorithm is: 793 * 794 * 1) Bump link count on source while we're linking it to the 795 * target. This also insure the inode won't be deleted out 796 * from underneath us while we work (it may be truncated by 797 * a concurrent `trunc' or `open' for creation). 798 * 2) Link source to destination. If destination already exists, 799 * delete it first. 800 * 3) Unlink source reference to inode if still around. If a 801 * directory was moved and the parent of the destination 802 * is different from the source, patch the ".." entry in the 803 * directory. 804 * 805 * Source and destination must either both be directories, or both 806 * not be directories. If target is a directory, it must be empty. 807 */ 808 rename() 809 { 810 struct a { 811 char *from; 812 char *to; 813 } *uap = (struct a *)u.u_ap; 814 register struct inode *ip, *xp, *dp; 815 struct dirtemplate dirbuf; 816 int doingdirectory = 0, oldparent = 0, newparent = 0; 817 register struct nameidata *ndp = &u.u_nd; 818 int error = 0; 819 820 ndp->ni_nameiop = DELETE | LOCKPARENT; 821 ndp->ni_segflg = UIO_USERSPACE; 822 ndp->ni_dirp = uap->from; 823 ip = namei(ndp); 824 if (ip == NULL) 825 return; 826 dp = ndp->ni_pdir; 827 if ((ip->i_mode&IFMT) == IFDIR) { 828 register struct direct *d; 829 830 d = &ndp->ni_dent; 831 /* 832 * Avoid ".", "..", and aliases of "." for obvious reasons. 833 */ 834 if ((d->d_namlen == 1 && d->d_name[0] == '.') || 835 (d->d_namlen == 2 && bcmp(d->d_name, "..", 2) == 0) || 836 (dp == ip) || (ip->i_flag & IRENAME)) { 837 iput(dp); 838 if (dp == ip) 839 irele(ip); 840 else 841 iput(ip); 842 u.u_error = EINVAL; 843 return; 844 } 845 ip->i_flag |= IRENAME; 846 oldparent = dp->i_number; 847 doingdirectory++; 848 } 849 iput(dp); 850 851 /* 852 * 1) Bump link count while we're moving stuff 853 * around. If we crash somewhere before 854 * completing our work, the link count 855 * may be wrong, but correctable. 856 */ 857 ip->i_nlink++; 858 ip->i_flag |= ICHG; 859 iupdat(ip, &time, &time, 1); 860 IUNLOCK(ip); 861 862 /* 863 * When the target exists, both the directory 864 * and target inodes are returned locked. 865 */ 866 ndp->ni_nameiop = CREATE | LOCKPARENT | NOCACHE; 867 ndp->ni_dirp = (caddr_t)uap->to; 868 xp = namei(ndp); 869 if (u.u_error) { 870 error = u.u_error; 871 goto out; 872 } 873 dp = ndp->ni_pdir; 874 /* 875 * If ".." must be changed (ie the directory gets a new 876 * parent) then the source directory must not be in the 877 * directory heirarchy above the target, as this would 878 * orphan everything below the source directory. Also 879 * the user must have write permission in the source so 880 * as to be able to change "..". We must repeat the call 881 * to namei, as the parent directory is unlocked by the 882 * call to checkpath(). 883 */ 884 if (oldparent != dp->i_number) 885 newparent = dp->i_number; 886 if (doingdirectory && newparent) { 887 if (access(ip, IWRITE)) 888 goto bad; 889 do { 890 dp = ndp->ni_pdir; 891 if (xp != NULL) 892 iput(xp); 893 u.u_error = checkpath(ip, dp); 894 if (u.u_error) 895 goto out; 896 xp = namei(ndp); 897 if (u.u_error) { 898 error = u.u_error; 899 goto out; 900 } 901 } while (dp != ndp->ni_pdir); 902 } 903 /* 904 * 2) If target doesn't exist, link the target 905 * to the source and unlink the source. 906 * Otherwise, rewrite the target directory 907 * entry to reference the source inode and 908 * expunge the original entry's existence. 909 */ 910 if (xp == NULL) { 911 if (dp->i_dev != ip->i_dev) { 912 error = EXDEV; 913 goto bad; 914 } 915 /* 916 * Account for ".." in new directory. 917 * When source and destination have the same 918 * parent we don't fool with the link count. 919 */ 920 if (doingdirectory && newparent) { 921 dp->i_nlink++; 922 dp->i_flag |= ICHG; 923 iupdat(dp, &time, &time, 1); 924 } 925 error = direnter(ip, ndp); 926 if (error) 927 goto out; 928 } else { 929 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) { 930 error = EXDEV; 931 goto bad; 932 } 933 /* 934 * Short circuit rename(foo, foo). 935 */ 936 if (xp->i_number == ip->i_number) 937 goto bad; 938 /* 939 * If the parent directory is "sticky", then the user must 940 * own the parent directory, or the destination of the rename, 941 * otherwise the destination may not be changed (except by 942 * root). This implements append-only directories. 943 */ 944 if ((dp->i_mode & ISVTX) && u.u_uid != 0 && 945 u.u_uid != dp->i_uid && xp->i_uid != u.u_uid) { 946 error = EPERM; 947 goto bad; 948 } 949 /* 950 * Target must be empty if a directory 951 * and have no links to it. 952 * Also, insure source and target are 953 * compatible (both directories, or both 954 * not directories). 955 */ 956 if ((xp->i_mode&IFMT) == IFDIR) { 957 if (!dirempty(xp, dp->i_number) || xp->i_nlink > 2) { 958 error = ENOTEMPTY; 959 goto bad; 960 } 961 if (!doingdirectory) { 962 error = ENOTDIR; 963 goto bad; 964 } 965 cacheinval(dp); 966 } else if (doingdirectory) { 967 error = EISDIR; 968 goto bad; 969 } 970 dirrewrite(dp, ip, ndp); 971 if (u.u_error) { 972 error = u.u_error; 973 goto bad1; 974 } 975 /* 976 * Adjust the link count of the target to 977 * reflect the dirrewrite above. If this is 978 * a directory it is empty and there are 979 * no links to it, so we can squash the inode and 980 * any space associated with it. We disallowed 981 * renaming over top of a directory with links to 982 * it above, as the remaining link would point to 983 * a directory without "." or ".." entries. 984 */ 985 xp->i_nlink--; 986 if (doingdirectory) { 987 if (--xp->i_nlink != 0) 988 panic("rename: linked directory"); 989 itrunc(xp, (u_long)0); 990 } 991 xp->i_flag |= ICHG; 992 iput(xp); 993 xp = NULL; 994 } 995 996 /* 997 * 3) Unlink the source. 998 */ 999 ndp->ni_nameiop = DELETE | LOCKPARENT; 1000 ndp->ni_segflg = UIO_USERSPACE; 1001 ndp->ni_dirp = uap->from; 1002 xp = namei(ndp); 1003 if (xp != NULL) 1004 dp = ndp->ni_pdir; 1005 else 1006 dp = NULL; 1007 /* 1008 * Insure that the directory entry still exists and has not 1009 * changed while the new name has been entered. If the source is 1010 * a file then the entry may have been unlinked or renamed. In 1011 * either case there is no further work to be done. If the source 1012 * is a directory then it cannot have been rmdir'ed; its link 1013 * count of three would cause a rmdir to fail with ENOTEMPTY. 1014 * The IRENAME flag insures that it cannot be moved by another 1015 * rename. 1016 */ 1017 if (xp != ip) { 1018 if (doingdirectory) 1019 panic("rename: lost dir entry"); 1020 } else { 1021 /* 1022 * If the source is a directory with a 1023 * new parent, the link count of the old 1024 * parent directory must be decremented 1025 * and ".." set to point to the new parent. 1026 */ 1027 if (doingdirectory && newparent) { 1028 dp->i_nlink--; 1029 dp->i_flag |= ICHG; 1030 error = rdwri(UIO_READ, xp, (caddr_t)&dirbuf, 1031 sizeof (struct dirtemplate), (off_t)0, 1, 1032 (int *)0); 1033 if (error == 0) { 1034 if (dirbuf.dotdot_namlen != 2 || 1035 dirbuf.dotdot_name[0] != '.' || 1036 dirbuf.dotdot_name[1] != '.') { 1037 printf("rename: mangled dir\n"); 1038 } else { 1039 dirbuf.dotdot_ino = newparent; 1040 (void) rdwri(UIO_WRITE, xp, 1041 (caddr_t)&dirbuf, 1042 sizeof (struct dirtemplate), 1043 (off_t)0, 1, (int *)0); 1044 cacheinval(dp); 1045 } 1046 } 1047 } 1048 if (dirremove(ndp)) { 1049 xp->i_nlink--; 1050 xp->i_flag |= ICHG; 1051 } 1052 xp->i_flag &= ~IRENAME; 1053 if (error == 0) /* XXX conservative */ 1054 error = u.u_error; 1055 } 1056 if (dp) 1057 iput(dp); 1058 if (xp) 1059 iput(xp); 1060 irele(ip); 1061 if (error) 1062 u.u_error = error; 1063 return; 1064 1065 bad: 1066 iput(dp); 1067 bad1: 1068 if (xp) 1069 iput(xp); 1070 out: 1071 ip->i_nlink--; 1072 ip->i_flag |= ICHG; 1073 irele(ip); 1074 if (error) 1075 u.u_error = error; 1076 } 1077 1078 /* 1079 * Make a new file. 1080 */ 1081 struct inode * 1082 maknode(mode, ndp) 1083 int mode; 1084 register struct nameidata *ndp; 1085 { 1086 register struct inode *ip; 1087 register struct inode *pdir = ndp->ni_pdir; 1088 ino_t ipref; 1089 1090 if ((mode & IFMT) == IFDIR) 1091 ipref = dirpref(pdir->i_fs); 1092 else 1093 ipref = pdir->i_number; 1094 ip = ialloc(pdir, ipref, mode); 1095 if (ip == NULL) { 1096 iput(pdir); 1097 return (NULL); 1098 } 1099 #ifdef QUOTA 1100 if (ip->i_dquot != NODQUOT) 1101 panic("maknode: dquot"); 1102 #endif 1103 ip->i_flag |= IACC|IUPD|ICHG; 1104 if ((mode & IFMT) == 0) 1105 mode |= IFREG; 1106 ip->i_mode = mode & ~u.u_cmask; 1107 ip->i_nlink = 1; 1108 ip->i_uid = u.u_uid; 1109 ip->i_gid = pdir->i_gid; 1110 if (ip->i_mode & ISGID && !groupmember(ip->i_gid)) 1111 ip->i_mode &= ~ISGID; 1112 #ifdef QUOTA 1113 ip->i_dquot = inoquota(ip); 1114 #endif 1115 1116 /* 1117 * Make sure inode goes to disk before directory entry. 1118 */ 1119 iupdat(ip, &time, &time, 1); 1120 u.u_error = direnter(ip, ndp); 1121 if (u.u_error) { 1122 /* 1123 * Write error occurred trying to update directory 1124 * so must deallocate the inode. 1125 */ 1126 ip->i_nlink = 0; 1127 ip->i_flag |= ICHG; 1128 iput(ip); 1129 return (NULL); 1130 } 1131 return (ip); 1132 } 1133 1134 /* 1135 * A virgin directory (no blushing please). 1136 */ 1137 struct dirtemplate mastertemplate = { 1138 0, 12, 1, ".", 1139 0, DIRBLKSIZ - 12, 2, ".." 1140 }; 1141 1142 /* 1143 * Mkdir system call 1144 */ 1145 mkdir() 1146 { 1147 struct a { 1148 char *name; 1149 int dmode; 1150 } *uap = (struct a *)u.u_ap; 1151 register struct inode *ip, *dp; 1152 struct dirtemplate dirtemplate; 1153 register struct nameidata *ndp = &u.u_nd; 1154 1155 ndp->ni_nameiop = CREATE; 1156 ndp->ni_segflg = UIO_USERSPACE; 1157 ndp->ni_dirp = uap->name; 1158 ip = namei(ndp); 1159 if (u.u_error) 1160 return; 1161 if (ip != NULL) { 1162 iput(ip); 1163 u.u_error = EEXIST; 1164 return; 1165 } 1166 dp = ndp->ni_pdir; 1167 uap->dmode &= 0777; 1168 uap->dmode |= IFDIR; 1169 /* 1170 * Must simulate part of maknode here 1171 * in order to acquire the inode, but 1172 * not have it entered in the parent 1173 * directory. The entry is made later 1174 * after writing "." and ".." entries out. 1175 */ 1176 ip = ialloc(dp, dirpref(dp->i_fs), uap->dmode); 1177 if (ip == NULL) { 1178 iput(dp); 1179 return; 1180 } 1181 #ifdef QUOTA 1182 if (ip->i_dquot != NODQUOT) 1183 panic("mkdir: dquot"); 1184 #endif 1185 ip->i_flag |= IACC|IUPD|ICHG; 1186 ip->i_mode = uap->dmode & ~u.u_cmask; 1187 ip->i_nlink = 2; 1188 ip->i_uid = u.u_uid; 1189 ip->i_gid = dp->i_gid; 1190 #ifdef QUOTA 1191 ip->i_dquot = inoquota(ip); 1192 #endif 1193 iupdat(ip, &time, &time, 1); 1194 1195 /* 1196 * Bump link count in parent directory 1197 * to reflect work done below. Should 1198 * be done before reference is created 1199 * so reparation is possible if we crash. 1200 */ 1201 dp->i_nlink++; 1202 dp->i_flag |= ICHG; 1203 iupdat(dp, &time, &time, 1); 1204 1205 /* 1206 * Initialize directory with "." 1207 * and ".." from static template. 1208 */ 1209 dirtemplate = mastertemplate; 1210 dirtemplate.dot_ino = ip->i_number; 1211 dirtemplate.dotdot_ino = dp->i_number; 1212 u.u_error = rdwri(UIO_WRITE, ip, (caddr_t)&dirtemplate, 1213 sizeof (dirtemplate), (off_t)0, 1, (int *)0); 1214 if (u.u_error) { 1215 dp->i_nlink--; 1216 dp->i_flag |= ICHG; 1217 goto bad; 1218 } 1219 if (DIRBLKSIZ > ip->i_fs->fs_fsize) 1220 panic("mkdir: blksize"); /* XXX - should grow with bmap() */ 1221 else 1222 ip->i_size = DIRBLKSIZ; 1223 /* 1224 * Directory all set up, now 1225 * install the entry for it in 1226 * the parent directory. 1227 */ 1228 u.u_error = direnter(ip, ndp); 1229 dp = NULL; 1230 if (u.u_error) { 1231 ndp->ni_nameiop = LOOKUP | NOCACHE; 1232 ndp->ni_segflg = UIO_USERSPACE; 1233 ndp->ni_dirp = uap->name; 1234 dp = namei(ndp); 1235 if (dp) { 1236 dp->i_nlink--; 1237 dp->i_flag |= ICHG; 1238 } 1239 } 1240 bad: 1241 /* 1242 * No need to do an explicit itrunc here, 1243 * irele will do this for us because we set 1244 * the link count to 0. 1245 */ 1246 if (u.u_error) { 1247 ip->i_nlink = 0; 1248 ip->i_flag |= ICHG; 1249 } 1250 if (dp) 1251 iput(dp); 1252 iput(ip); 1253 } 1254 1255 /* 1256 * Rmdir system call. 1257 */ 1258 rmdir() 1259 { 1260 struct a { 1261 char *name; 1262 } *uap = (struct a *)u.u_ap; 1263 register struct inode *ip, *dp; 1264 register struct nameidata *ndp = &u.u_nd; 1265 1266 ndp->ni_nameiop = DELETE | LOCKPARENT; 1267 ndp->ni_segflg = UIO_USERSPACE; 1268 ndp->ni_dirp = uap->name; 1269 ip = namei(ndp); 1270 if (ip == NULL) 1271 return; 1272 dp = ndp->ni_pdir; 1273 /* 1274 * No rmdir "." please. 1275 */ 1276 if (dp == ip) { 1277 irele(dp); 1278 iput(ip); 1279 u.u_error = EINVAL; 1280 return; 1281 } 1282 if ((ip->i_mode&IFMT) != IFDIR) { 1283 u.u_error = ENOTDIR; 1284 goto out; 1285 } 1286 /* 1287 * Don't remove a mounted on directory. 1288 */ 1289 if (ip->i_dev != dp->i_dev) { 1290 u.u_error = EBUSY; 1291 goto out; 1292 } 1293 /* 1294 * Verify the directory is empty (and valid). 1295 * (Rmdir ".." won't be valid since 1296 * ".." will contain a reference to 1297 * the current directory and thus be 1298 * non-empty.) 1299 */ 1300 if (ip->i_nlink != 2 || !dirempty(ip, dp->i_number)) { 1301 u.u_error = ENOTEMPTY; 1302 goto out; 1303 } 1304 /* 1305 * Delete reference to directory before purging 1306 * inode. If we crash in between, the directory 1307 * will be reattached to lost+found, 1308 */ 1309 if (dirremove(ndp) == 0) 1310 goto out; 1311 dp->i_nlink--; 1312 dp->i_flag |= ICHG; 1313 cacheinval(dp); 1314 iput(dp); 1315 dp = NULL; 1316 /* 1317 * Truncate inode. The only stuff left 1318 * in the directory is "." and "..". The 1319 * "." reference is inconsequential since 1320 * we're quashing it. The ".." reference 1321 * has already been adjusted above. We've 1322 * removed the "." reference and the reference 1323 * in the parent directory, but there may be 1324 * other hard links so decrement by 2 and 1325 * worry about them later. 1326 */ 1327 ip->i_nlink -= 2; 1328 itrunc(ip, (u_long)0); 1329 cacheinval(ip); 1330 out: 1331 if (dp) 1332 iput(dp); 1333 iput(ip); 1334 } 1335 1336 struct file * 1337 getinode(fdes) 1338 int fdes; 1339 { 1340 struct file *fp; 1341 1342 if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL) { 1343 u.u_error = EBADF; 1344 return ((struct file *)0); 1345 } 1346 if (fp->f_type != DTYPE_INODE) { 1347 u.u_error = EINVAL; 1348 return ((struct file *)0); 1349 } 1350 return (fp); 1351 } 1352 1353 /* 1354 * mode mask for creation of files 1355 */ 1356 umask() 1357 { 1358 register struct a { 1359 int mask; 1360 } *uap = (struct a *)u.u_ap; 1361 1362 u.u_r.r_val1 = u.u_cmask; 1363 u.u_cmask = uap->mask & 07777; 1364 } 1365