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.23 (Berkeley) 03/04/86 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, (off_t)0, 0, 335 (int *)0); 336 /* handle u.u_error != 0 */ 337 iput(ip); 338 } 339 340 /* 341 * Unlink system call. 342 * Hard to avoid races here, especially 343 * in unlinking directories. 344 */ 345 unlink() 346 { 347 struct a { 348 char *fname; 349 } *uap = (struct a *)u.u_ap; 350 register struct inode *ip, *dp; 351 register struct nameidata *ndp = &u.u_nd; 352 353 ndp->ni_nameiop = DELETE | LOCKPARENT; 354 ndp->ni_segflg = UIO_USERSPACE; 355 ndp->ni_dirp = uap->fname; 356 ip = namei(ndp); 357 if (ip == NULL) 358 return; 359 dp = ndp->ni_pdir; 360 if ((ip->i_mode&IFMT) == IFDIR && !suser()) 361 goto out; 362 /* 363 * Don't unlink a mounted file. 364 */ 365 if (ip->i_dev != dp->i_dev) { 366 u.u_error = EBUSY; 367 goto out; 368 } 369 if (ip->i_flag&ITEXT) 370 xrele(ip); /* try once to free text */ 371 if (dirremove(ndp)) { 372 ip->i_nlink--; 373 ip->i_flag |= ICHG; 374 } 375 out: 376 if (dp == ip) 377 irele(ip); 378 else 379 iput(ip); 380 iput(dp); 381 } 382 383 /* 384 * Seek system call 385 */ 386 lseek() 387 { 388 register struct file *fp; 389 register struct a { 390 int fd; 391 off_t off; 392 int sbase; 393 } *uap = (struct a *)u.u_ap; 394 395 GETF(fp, uap->fd); 396 if (fp->f_type != DTYPE_INODE) { 397 u.u_error = ESPIPE; 398 return; 399 } 400 switch (uap->sbase) { 401 402 case L_INCR: 403 fp->f_offset += uap->off; 404 break; 405 406 case L_XTND: 407 fp->f_offset = uap->off + ((struct inode *)fp->f_data)->i_size; 408 break; 409 410 case L_SET: 411 fp->f_offset = uap->off; 412 break; 413 414 default: 415 u.u_error = EINVAL; 416 return; 417 } 418 u.u_r.r_off = fp->f_offset; 419 } 420 421 /* 422 * Access system call 423 */ 424 saccess() 425 { 426 register svuid, svgid; 427 register struct inode *ip; 428 register struct a { 429 char *fname; 430 int fmode; 431 } *uap = (struct a *)u.u_ap; 432 register struct nameidata *ndp = &u.u_nd; 433 434 svuid = u.u_uid; 435 svgid = u.u_gid; 436 u.u_uid = u.u_ruid; 437 u.u_gid = u.u_rgid; 438 ndp->ni_nameiop = LOOKUP | FOLLOW; 439 ndp->ni_segflg = UIO_USERSPACE; 440 ndp->ni_dirp = uap->fname; 441 ip = namei(ndp); 442 if (ip != NULL) { 443 if ((uap->fmode&R_OK) && access(ip, IREAD)) 444 goto done; 445 if ((uap->fmode&W_OK) && access(ip, IWRITE)) 446 goto done; 447 if ((uap->fmode&X_OK) && access(ip, IEXEC)) 448 goto done; 449 done: 450 iput(ip); 451 } 452 u.u_uid = svuid; 453 u.u_gid = svgid; 454 } 455 456 /* 457 * Stat system call. This version follows links. 458 */ 459 stat() 460 { 461 462 stat1(FOLLOW); 463 } 464 465 /* 466 * Lstat system call. This version does not follow links. 467 */ 468 lstat() 469 { 470 471 stat1(NOFOLLOW); 472 } 473 474 stat1(follow) 475 int follow; 476 { 477 register struct inode *ip; 478 register struct a { 479 char *fname; 480 struct stat *ub; 481 } *uap = (struct a *)u.u_ap; 482 struct stat sb; 483 register struct nameidata *ndp = &u.u_nd; 484 485 ndp->ni_nameiop = LOOKUP | follow; 486 ndp->ni_segflg = UIO_USERSPACE; 487 ndp->ni_dirp = uap->fname; 488 ip = namei(ndp); 489 if (ip == NULL) 490 return; 491 (void) ino_stat(ip, &sb); 492 iput(ip); 493 u.u_error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb)); 494 } 495 496 /* 497 * Return target name of a symbolic link 498 */ 499 readlink() 500 { 501 register struct inode *ip; 502 register struct a { 503 char *name; 504 char *buf; 505 int count; 506 } *uap = (struct a *)u.u_ap; 507 register struct nameidata *ndp = &u.u_nd; 508 int resid; 509 510 ndp->ni_nameiop = LOOKUP; 511 ndp->ni_segflg = UIO_USERSPACE; 512 ndp->ni_dirp = uap->name; 513 ip = namei(ndp); 514 if (ip == NULL) 515 return; 516 if ((ip->i_mode&IFMT) != IFLNK) { 517 u.u_error = EINVAL; 518 goto out; 519 } 520 u.u_error = rdwri(UIO_READ, ip, uap->buf, uap->count, (off_t)0, 0, 521 &resid); 522 out: 523 iput(ip); 524 u.u_r.r_val1 = uap->count - resid; 525 } 526 527 /* 528 * Change mode of a file given path name. 529 */ 530 chmod() 531 { 532 struct inode *ip; 533 struct a { 534 char *fname; 535 int fmode; 536 } *uap = (struct a *)u.u_ap; 537 538 if ((ip = owner(uap->fname, FOLLOW)) == NULL) 539 return; 540 u.u_error = chmod1(ip, uap->fmode); 541 iput(ip); 542 } 543 544 /* 545 * Change mode of a file given a file descriptor. 546 */ 547 fchmod() 548 { 549 struct a { 550 int fd; 551 int fmode; 552 } *uap = (struct a *)u.u_ap; 553 register struct inode *ip; 554 register struct file *fp; 555 556 fp = getinode(uap->fd); 557 if (fp == NULL) 558 return; 559 ip = (struct inode *)fp->f_data; 560 if (u.u_uid != ip->i_uid && !suser()) 561 return; 562 ILOCK(ip); 563 u.u_error = chmod1(ip, uap->fmode); 564 IUNLOCK(ip); 565 } 566 567 /* 568 * Change the mode on a file. 569 * Inode must be locked before calling. 570 */ 571 chmod1(ip, mode) 572 register struct inode *ip; 573 register int mode; 574 { 575 576 if (ip->i_fs->fs_ronly) 577 return (EROFS); 578 ip->i_mode &= ~07777; 579 if (u.u_uid) { 580 if ((ip->i_mode & IFMT) != IFDIR) 581 mode &= ~ISVTX; 582 if (!groupmember(ip->i_gid)) 583 mode &= ~ISGID; 584 } 585 ip->i_mode |= mode&07777; 586 ip->i_flag |= ICHG; 587 if (ip->i_flag&ITEXT && (ip->i_mode&ISVTX)==0) 588 xrele(ip); 589 return (0); 590 } 591 592 /* 593 * Set ownership given a path name. 594 */ 595 chown() 596 { 597 struct inode *ip; 598 struct a { 599 char *fname; 600 int uid; 601 int gid; 602 } *uap = (struct a *)u.u_ap; 603 604 if ((ip = owner(uap->fname, NOFOLLOW)) == NULL) 605 return; 606 u.u_error = chown1(ip, uap->uid, uap->gid); 607 iput(ip); 608 } 609 610 /* 611 * Set ownership given a file descriptor. 612 */ 613 fchown() 614 { 615 struct a { 616 int fd; 617 int uid; 618 int gid; 619 } *uap = (struct a *)u.u_ap; 620 register struct inode *ip; 621 register struct file *fp; 622 623 fp = getinode(uap->fd); 624 if (fp == NULL) 625 return; 626 ip = (struct inode *)fp->f_data; 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 if (uid != ip->i_uid && !suser()) 651 return (u.u_error); 652 if (gid != ip->i_gid && !groupmember((gid_t)gid) && !suser()) 653 return (u.u_error); 654 #ifdef QUOTA 655 if (ip->i_uid == uid) /* this just speeds things a little */ 656 change = 0; 657 else 658 change = ip->i_blocks; 659 (void) chkdq(ip, -change, 1); 660 (void) chkiq(ip->i_dev, ip, ip->i_uid, 1); 661 dqrele(ip->i_dquot); 662 #endif 663 ip->i_uid = uid; 664 ip->i_gid = gid; 665 ip->i_flag |= ICHG; 666 if (u.u_ruid != 0) 667 ip->i_mode &= ~(ISUID|ISGID); 668 #ifdef QUOTA 669 ip->i_dquot = inoquota(ip); 670 (void) chkdq(ip, change, 1); 671 (void) chkiq(ip->i_dev, (struct inode *)NULL, (uid_t)uid, 1); 672 return (u.u_error); /* should == 0 ALWAYS !! */ 673 #else 674 return (0); 675 #endif 676 } 677 678 utimes() 679 { 680 register struct a { 681 char *fname; 682 struct timeval *tptr; 683 } *uap = (struct a *)u.u_ap; 684 register struct inode *ip; 685 struct timeval tv[2]; 686 687 if ((ip = owner(uap->fname, FOLLOW)) == NULL) 688 return; 689 if (ip->i_fs->fs_ronly) { 690 u.u_error = EROFS; 691 iput(ip); 692 return; 693 } 694 u.u_error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)); 695 if (u.u_error == 0) { 696 ip->i_flag |= IACC|IUPD|ICHG; 697 iupdat(ip, &tv[0], &tv[1], 0); 698 } 699 iput(ip); 700 } 701 702 /* 703 * Flush any pending I/O. 704 */ 705 sync() 706 { 707 708 update(); 709 } 710 711 /* 712 * Truncate a file given its path name. 713 */ 714 truncate() 715 { 716 struct a { 717 char *fname; 718 off_t length; 719 } *uap = (struct a *)u.u_ap; 720 struct inode *ip; 721 register struct nameidata *ndp = &u.u_nd; 722 723 ndp->ni_nameiop = LOOKUP | FOLLOW; 724 ndp->ni_segflg = UIO_USERSPACE; 725 ndp->ni_dirp = uap->fname; 726 ip = namei(ndp); 727 if (ip == NULL) 728 return; 729 if (access(ip, IWRITE)) 730 goto bad; 731 if ((ip->i_mode&IFMT) == IFDIR) { 732 u.u_error = EISDIR; 733 goto bad; 734 } 735 itrunc(ip, (u_long)uap->length); 736 bad: 737 iput(ip); 738 } 739 740 /* 741 * Truncate a file given a file descriptor. 742 */ 743 ftruncate() 744 { 745 struct a { 746 int fd; 747 off_t length; 748 } *uap = (struct a *)u.u_ap; 749 struct inode *ip; 750 struct file *fp; 751 752 fp = getinode(uap->fd); 753 if (fp == NULL) 754 return; 755 if ((fp->f_flag&FWRITE) == 0) { 756 u.u_error = EINVAL; 757 return; 758 } 759 ip = (struct inode *)fp->f_data; 760 ILOCK(ip); 761 itrunc(ip, (u_long)uap->length); 762 IUNLOCK(ip); 763 } 764 765 /* 766 * Synch an open file. 767 */ 768 fsync() 769 { 770 struct a { 771 int fd; 772 } *uap = (struct a *)u.u_ap; 773 struct inode *ip; 774 struct file *fp; 775 776 fp = getinode(uap->fd); 777 if (fp == NULL) 778 return; 779 ip = (struct inode *)fp->f_data; 780 ILOCK(ip); 781 syncip(ip); 782 IUNLOCK(ip); 783 } 784 785 /* 786 * Rename system call. 787 * rename("foo", "bar"); 788 * is essentially 789 * unlink("bar"); 790 * link("foo", "bar"); 791 * unlink("foo"); 792 * but ``atomically''. Can't do full commit without saving state in the 793 * inode on disk which isn't feasible at this time. Best we can do is 794 * always guarantee the target exists. 795 * 796 * Basic algorithm is: 797 * 798 * 1) Bump link count on source while we're linking it to the 799 * target. This also insure the inode won't be deleted out 800 * from underneath us while we work (it may be truncated by 801 * a concurrent `trunc' or `open' for creation). 802 * 2) Link source to destination. If destination already exists, 803 * delete it first. 804 * 3) Unlink source reference to inode if still around. If a 805 * directory was moved and the parent of the destination 806 * is different from the source, patch the ".." entry in the 807 * directory. 808 * 809 * Source and destination must either both be directories, or both 810 * not be directories. If target is a directory, it must be empty. 811 */ 812 rename() 813 { 814 struct a { 815 char *from; 816 char *to; 817 } *uap = (struct a *)u.u_ap; 818 register struct inode *ip, *xp, *dp; 819 struct dirtemplate dirbuf; 820 int doingdirectory = 0, oldparent = 0, newparent = 0; 821 register struct nameidata *ndp = &u.u_nd; 822 int error = 0; 823 824 ndp->ni_nameiop = DELETE | LOCKPARENT; 825 ndp->ni_segflg = UIO_USERSPACE; 826 ndp->ni_dirp = uap->from; 827 ip = namei(ndp); 828 if (ip == NULL) 829 return; 830 dp = ndp->ni_pdir; 831 if ((ip->i_mode&IFMT) == IFDIR) { 832 register struct direct *d; 833 834 d = &ndp->ni_dent; 835 /* 836 * Avoid ".", "..", and aliases of "." for obvious reasons. 837 */ 838 if ((d->d_namlen == 1 && d->d_name[0] == '.') || 839 (d->d_namlen == 2 && bcmp(d->d_name, "..", 2) == 0) || 840 (dp == ip) || (ip->i_flag & IRENAME)) { 841 iput(dp); 842 if (dp == ip) 843 irele(ip); 844 else 845 iput(ip); 846 u.u_error = EINVAL; 847 return; 848 } 849 ip->i_flag |= IRENAME; 850 oldparent = dp->i_number; 851 doingdirectory++; 852 } 853 iput(dp); 854 855 /* 856 * 1) Bump link count while we're moving stuff 857 * around. If we crash somewhere before 858 * completing our work, the link count 859 * may be wrong, but correctable. 860 */ 861 ip->i_nlink++; 862 ip->i_flag |= ICHG; 863 iupdat(ip, &time, &time, 1); 864 IUNLOCK(ip); 865 866 /* 867 * When the target exists, both the directory 868 * and target inodes are returned locked. 869 */ 870 ndp->ni_nameiop = CREATE | LOCKPARENT | NOCACHE; 871 ndp->ni_dirp = (caddr_t)uap->to; 872 xp = namei(ndp); 873 if (u.u_error) { 874 error = u.u_error; 875 goto out; 876 } 877 dp = ndp->ni_pdir; 878 /* 879 * If ".." must be changed (ie the directory gets a new 880 * parent) then the source directory must not be in the 881 * directory heirarchy above the target, as this would 882 * orphan everything below the source directory. Also 883 * the user must have write permission in the source so 884 * as to be able to change "..". We must repeat the call 885 * to namei, as the parent directory is unlocked by the 886 * call to checkpath(). 887 */ 888 if (oldparent != dp->i_number) 889 newparent = dp->i_number; 890 if (doingdirectory && newparent) { 891 if (access(ip, IWRITE)) 892 goto bad; 893 do { 894 dp = ndp->ni_pdir; 895 if (xp != NULL) 896 iput(xp); 897 u.u_error = checkpath(ip, dp); 898 if (u.u_error) 899 goto out; 900 xp = namei(ndp); 901 if (u.u_error) { 902 error = u.u_error; 903 goto out; 904 } 905 } while (dp != ndp->ni_pdir); 906 } 907 /* 908 * 2) If target doesn't exist, link the target 909 * to the source and unlink the source. 910 * Otherwise, rewrite the target directory 911 * entry to reference the source inode and 912 * expunge the original entry's existence. 913 */ 914 if (xp == NULL) { 915 if (dp->i_dev != ip->i_dev) { 916 error = EXDEV; 917 goto bad; 918 } 919 /* 920 * Account for ".." in new directory. 921 * When source and destination have the same 922 * parent we don't fool with the link count. 923 */ 924 if (doingdirectory && newparent) { 925 dp->i_nlink++; 926 dp->i_flag |= ICHG; 927 iupdat(dp, &time, &time, 1); 928 } 929 error = direnter(ip, ndp); 930 if (error) 931 goto out; 932 } else { 933 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) { 934 error = EXDEV; 935 goto bad; 936 } 937 /* 938 * Short circuit rename(foo, foo). 939 */ 940 if (xp->i_number == ip->i_number) 941 goto bad; 942 /* 943 * If the parent directory is "sticky", then the user must 944 * own the parent directory, or the destination of the rename, 945 * otherwise the destination may not be changed (except by 946 * root). This implements append-only directories. 947 */ 948 if ((dp->i_mode & ISVTX) && u.u_uid != 0 && 949 u.u_uid != dp->i_uid && xp->i_uid != u.u_uid) { 950 error = EPERM; 951 goto bad; 952 } 953 /* 954 * Target must be empty if a directory 955 * and have no links to it. 956 * Also, insure source and target are 957 * compatible (both directories, or both 958 * not directories). 959 */ 960 if ((xp->i_mode&IFMT) == IFDIR) { 961 if (!dirempty(xp, dp->i_number) || xp->i_nlink > 2) { 962 error = ENOTEMPTY; 963 goto bad; 964 } 965 if (!doingdirectory) { 966 error = ENOTDIR; 967 goto bad; 968 } 969 cacheinval(dp); 970 } else if (doingdirectory) { 971 error = EISDIR; 972 goto bad; 973 } 974 dirrewrite(dp, ip, ndp); 975 if (u.u_error) { 976 error = u.u_error; 977 goto bad1; 978 } 979 /* 980 * Adjust the link count of the target to 981 * reflect the dirrewrite above. If this is 982 * a directory it is empty and there are 983 * no links to it, so we can squash the inode and 984 * any space associated with it. We disallowed 985 * renaming over top of a directory with links to 986 * it above, as the remaining link would point to 987 * a directory without "." or ".." entries. 988 */ 989 xp->i_nlink--; 990 if (doingdirectory) { 991 if (--xp->i_nlink != 0) 992 panic("rename: linked directory"); 993 itrunc(xp, (u_long)0); 994 } 995 xp->i_flag |= ICHG; 996 iput(xp); 997 xp = NULL; 998 } 999 1000 /* 1001 * 3) Unlink the source. 1002 */ 1003 ndp->ni_nameiop = DELETE | LOCKPARENT; 1004 ndp->ni_segflg = UIO_USERSPACE; 1005 ndp->ni_dirp = uap->from; 1006 xp = namei(ndp); 1007 if (xp != NULL) 1008 dp = ndp->ni_pdir; 1009 else 1010 dp = NULL; 1011 /* 1012 * Insure that the directory entry still exists and has not 1013 * changed while the new name has been entered. If the source is 1014 * a file then the entry may have been unlinked or renamed. In 1015 * either case there is no further work to be done. If the source 1016 * is a directory then it cannot have been rmdir'ed; its link 1017 * count of three would cause a rmdir to fail with ENOTEMPTY. 1018 * The IRENAME flag insures that it cannot be moved by another 1019 * rename. 1020 */ 1021 if (xp != ip) { 1022 if (doingdirectory) 1023 panic("rename: lost dir entry"); 1024 } else { 1025 /* 1026 * If the source is a directory with a 1027 * new parent, the link count of the old 1028 * parent directory must be decremented 1029 * and ".." set to point to the new parent. 1030 */ 1031 if (doingdirectory && newparent) { 1032 dp->i_nlink--; 1033 dp->i_flag |= ICHG; 1034 error = rdwri(UIO_READ, xp, (caddr_t)&dirbuf, 1035 sizeof (struct dirtemplate), (off_t)0, 1, 1036 (int *)0); 1037 if (error == 0) { 1038 if (dirbuf.dotdot_namlen != 2 || 1039 dirbuf.dotdot_name[0] != '.' || 1040 dirbuf.dotdot_name[1] != '.') { 1041 printf("rename: mangled dir\n"); 1042 } else { 1043 dirbuf.dotdot_ino = newparent; 1044 (void) rdwri(UIO_WRITE, xp, 1045 (caddr_t)&dirbuf, 1046 sizeof (struct dirtemplate), 1047 (off_t)0, 1, (int *)0); 1048 cacheinval(dp); 1049 } 1050 } 1051 } 1052 if (dirremove(ndp)) { 1053 xp->i_nlink--; 1054 xp->i_flag |= ICHG; 1055 } 1056 xp->i_flag &= ~IRENAME; 1057 if (error == 0) /* XXX conservative */ 1058 error = u.u_error; 1059 } 1060 if (dp) 1061 iput(dp); 1062 if (xp) 1063 iput(xp); 1064 irele(ip); 1065 if (error) 1066 u.u_error = error; 1067 return; 1068 1069 bad: 1070 iput(dp); 1071 bad1: 1072 if (xp) 1073 iput(xp); 1074 out: 1075 ip->i_nlink--; 1076 ip->i_flag |= ICHG; 1077 irele(ip); 1078 if (error) 1079 u.u_error = error; 1080 } 1081 1082 /* 1083 * Make a new file. 1084 */ 1085 struct inode * 1086 maknode(mode, ndp) 1087 int mode; 1088 register struct nameidata *ndp; 1089 { 1090 register struct inode *ip; 1091 register struct inode *pdir = ndp->ni_pdir; 1092 ino_t ipref; 1093 1094 if ((mode & IFMT) == IFDIR) 1095 ipref = dirpref(pdir->i_fs); 1096 else 1097 ipref = pdir->i_number; 1098 ip = ialloc(pdir, ipref, mode); 1099 if (ip == NULL) { 1100 iput(pdir); 1101 return (NULL); 1102 } 1103 #ifdef QUOTA 1104 if (ip->i_dquot != NODQUOT) 1105 panic("maknode: dquot"); 1106 #endif 1107 ip->i_flag |= IACC|IUPD|ICHG; 1108 if ((mode & IFMT) == 0) 1109 mode |= IFREG; 1110 ip->i_mode = mode & ~u.u_cmask; 1111 ip->i_nlink = 1; 1112 ip->i_uid = u.u_uid; 1113 ip->i_gid = pdir->i_gid; 1114 if (ip->i_mode & ISGID && !groupmember(ip->i_gid)) 1115 ip->i_mode &= ~ISGID; 1116 #ifdef QUOTA 1117 ip->i_dquot = inoquota(ip); 1118 #endif 1119 1120 /* 1121 * Make sure inode goes to disk before directory entry. 1122 */ 1123 iupdat(ip, &time, &time, 1); 1124 u.u_error = direnter(ip, ndp); 1125 if (u.u_error) { 1126 /* 1127 * Write error occurred trying to update directory 1128 * so must deallocate the inode. 1129 */ 1130 ip->i_nlink = 0; 1131 ip->i_flag |= ICHG; 1132 iput(ip); 1133 return (NULL); 1134 } 1135 return (ip); 1136 } 1137 1138 /* 1139 * A virgin directory (no blushing please). 1140 */ 1141 struct dirtemplate mastertemplate = { 1142 0, 12, 1, ".", 1143 0, DIRBLKSIZ - 12, 2, ".." 1144 }; 1145 1146 /* 1147 * Mkdir system call 1148 */ 1149 mkdir() 1150 { 1151 struct a { 1152 char *name; 1153 int dmode; 1154 } *uap = (struct a *)u.u_ap; 1155 register struct inode *ip, *dp; 1156 struct dirtemplate dirtemplate; 1157 register struct nameidata *ndp = &u.u_nd; 1158 1159 ndp->ni_nameiop = CREATE; 1160 ndp->ni_segflg = UIO_USERSPACE; 1161 ndp->ni_dirp = uap->name; 1162 ip = namei(ndp); 1163 if (u.u_error) 1164 return; 1165 if (ip != NULL) { 1166 iput(ip); 1167 u.u_error = EEXIST; 1168 return; 1169 } 1170 dp = ndp->ni_pdir; 1171 uap->dmode &= 0777; 1172 uap->dmode |= IFDIR; 1173 /* 1174 * Must simulate part of maknode here 1175 * in order to acquire the inode, but 1176 * not have it entered in the parent 1177 * directory. The entry is made later 1178 * after writing "." and ".." entries out. 1179 */ 1180 ip = ialloc(dp, dirpref(dp->i_fs), uap->dmode); 1181 if (ip == NULL) { 1182 iput(dp); 1183 return; 1184 } 1185 #ifdef QUOTA 1186 if (ip->i_dquot != NODQUOT) 1187 panic("mkdir: dquot"); 1188 #endif 1189 ip->i_flag |= IACC|IUPD|ICHG; 1190 ip->i_mode = uap->dmode & ~u.u_cmask; 1191 ip->i_nlink = 2; 1192 ip->i_uid = u.u_uid; 1193 ip->i_gid = dp->i_gid; 1194 #ifdef QUOTA 1195 ip->i_dquot = inoquota(ip); 1196 #endif 1197 iupdat(ip, &time, &time, 1); 1198 1199 /* 1200 * Bump link count in parent directory 1201 * to reflect work done below. Should 1202 * be done before reference is created 1203 * so reparation is possible if we crash. 1204 */ 1205 dp->i_nlink++; 1206 dp->i_flag |= ICHG; 1207 iupdat(dp, &time, &time, 1); 1208 1209 /* 1210 * Initialize directory with "." 1211 * and ".." from static template. 1212 */ 1213 dirtemplate = mastertemplate; 1214 dirtemplate.dot_ino = ip->i_number; 1215 dirtemplate.dotdot_ino = dp->i_number; 1216 u.u_error = rdwri(UIO_WRITE, ip, (caddr_t)&dirtemplate, 1217 sizeof (dirtemplate), (off_t)0, 1, (int *)0); 1218 if (u.u_error) { 1219 dp->i_nlink--; 1220 dp->i_flag |= ICHG; 1221 goto bad; 1222 } 1223 if (DIRBLKSIZ > ip->i_fs->fs_fsize) 1224 panic("mkdir: blksize"); /* XXX - should grow with bmap() */ 1225 else 1226 ip->i_size = DIRBLKSIZ; 1227 /* 1228 * Directory all set up, now 1229 * install the entry for it in 1230 * the parent directory. 1231 */ 1232 u.u_error = direnter(ip, ndp); 1233 dp = NULL; 1234 if (u.u_error) { 1235 ndp->ni_nameiop = LOOKUP | NOCACHE; 1236 ndp->ni_segflg = UIO_USERSPACE; 1237 ndp->ni_dirp = uap->name; 1238 dp = namei(ndp); 1239 if (dp) { 1240 dp->i_nlink--; 1241 dp->i_flag |= ICHG; 1242 } 1243 } 1244 bad: 1245 /* 1246 * No need to do an explicit itrunc here, 1247 * irele will do this for us because we set 1248 * the link count to 0. 1249 */ 1250 if (u.u_error) { 1251 ip->i_nlink = 0; 1252 ip->i_flag |= ICHG; 1253 } 1254 if (dp) 1255 iput(dp); 1256 iput(ip); 1257 } 1258 1259 /* 1260 * Rmdir system call. 1261 */ 1262 rmdir() 1263 { 1264 struct a { 1265 char *name; 1266 } *uap = (struct a *)u.u_ap; 1267 register struct inode *ip, *dp; 1268 register struct nameidata *ndp = &u.u_nd; 1269 1270 ndp->ni_nameiop = DELETE | LOCKPARENT; 1271 ndp->ni_segflg = UIO_USERSPACE; 1272 ndp->ni_dirp = uap->name; 1273 ip = namei(ndp); 1274 if (ip == NULL) 1275 return; 1276 dp = ndp->ni_pdir; 1277 /* 1278 * No rmdir "." please. 1279 */ 1280 if (dp == ip) { 1281 irele(dp); 1282 iput(ip); 1283 u.u_error = EINVAL; 1284 return; 1285 } 1286 if ((ip->i_mode&IFMT) != IFDIR) { 1287 u.u_error = ENOTDIR; 1288 goto out; 1289 } 1290 /* 1291 * Don't remove a mounted on directory. 1292 */ 1293 if (ip->i_dev != dp->i_dev) { 1294 u.u_error = EBUSY; 1295 goto out; 1296 } 1297 /* 1298 * Verify the directory is empty (and valid). 1299 * (Rmdir ".." won't be valid since 1300 * ".." will contain a reference to 1301 * the current directory and thus be 1302 * non-empty.) 1303 */ 1304 if (ip->i_nlink != 2 || !dirempty(ip, dp->i_number)) { 1305 u.u_error = ENOTEMPTY; 1306 goto out; 1307 } 1308 /* 1309 * Delete reference to directory before purging 1310 * inode. If we crash in between, the directory 1311 * will be reattached to lost+found, 1312 */ 1313 if (dirremove(ndp) == 0) 1314 goto out; 1315 dp->i_nlink--; 1316 dp->i_flag |= ICHG; 1317 cacheinval(dp); 1318 iput(dp); 1319 dp = NULL; 1320 /* 1321 * Truncate inode. The only stuff left 1322 * in the directory is "." and "..". The 1323 * "." reference is inconsequential since 1324 * we're quashing it. The ".." reference 1325 * has already been adjusted above. We've 1326 * removed the "." reference and the reference 1327 * in the parent directory, but there may be 1328 * other hard links so decrement by 2 and 1329 * worry about them later. 1330 */ 1331 ip->i_nlink -= 2; 1332 itrunc(ip, (u_long)0); 1333 cacheinval(ip); 1334 out: 1335 if (dp) 1336 iput(dp); 1337 iput(ip); 1338 } 1339 1340 struct file * 1341 getinode(fdes) 1342 int fdes; 1343 { 1344 struct file *fp; 1345 1346 if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL) { 1347 u.u_error = EBADF; 1348 return ((struct file *)0); 1349 } 1350 if (fp->f_type != DTYPE_INODE) { 1351 u.u_error = EINVAL; 1352 return ((struct file *)0); 1353 } 1354 return (fp); 1355 } 1356 1357 /* 1358 * mode mask for creation of files 1359 */ 1360 umask() 1361 { 1362 register struct a { 1363 int mask; 1364 } *uap = (struct a *)u.u_ap; 1365 1366 u.u_r.r_val1 = u.u_cmask; 1367 u.u_cmask = uap->mask & 07777; 1368 } 1369