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