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 * @(#)lfs_vnops.c 7.4 (Berkeley) 01/24/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 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 register struct nameidata *ndp = &u.u_nd; 604 605 ndp->ni_nameiop = LOOKUP | NOFOLLOW; 606 ndp->ni_segflg = UIO_USERSPACE; 607 ndp->ni_dirp = uap->fname; 608 ip = namei(ndp); 609 if (ip == NULL) 610 return; 611 u.u_error = chown1(ip, uap->uid, uap->gid); 612 iput(ip); 613 } 614 615 /* 616 * Set ownership given a file descriptor. 617 */ 618 fchown() 619 { 620 struct a { 621 int fd; 622 int uid; 623 int gid; 624 } *uap = (struct a *)u.u_ap; 625 register struct inode *ip; 626 register struct file *fp; 627 628 fp = getinode(uap->fd); 629 if (fp == NULL) 630 return; 631 ip = (struct inode *)fp->f_data; 632 ILOCK(ip); 633 u.u_error = chown1(ip, uap->uid, uap->gid); 634 IUNLOCK(ip); 635 } 636 637 /* 638 * Perform chown operation on inode ip; 639 * inode must be locked prior to call. 640 */ 641 chown1(ip, uid, gid) 642 register struct inode *ip; 643 int uid, gid; 644 { 645 #ifdef QUOTA 646 register long change; 647 #endif 648 649 if (ip->i_fs->fs_ronly) 650 return (EROFS); 651 if (uid == -1) 652 uid = ip->i_uid; 653 if (gid == -1) 654 gid = ip->i_gid; 655 /* 656 * If we don't own the file, are trying to change the owner 657 * of the file, or are not a member of the target group, 658 * the caller must be superuser or the call fails. 659 */ 660 if ((u.u_uid != ip->i_uid || uid != ip->i_uid || 661 !groupmember((gid_t)gid)) && !suser()) 662 return (u.u_error); 663 #ifdef QUOTA 664 if (ip->i_uid == uid) /* this just speeds things a little */ 665 change = 0; 666 else 667 change = ip->i_blocks; 668 (void) chkdq(ip, -change, 1); 669 (void) chkiq(ip->i_dev, ip, ip->i_uid, 1); 670 dqrele(ip->i_dquot); 671 #endif 672 ip->i_uid = uid; 673 ip->i_gid = gid; 674 ip->i_flag |= ICHG; 675 if (u.u_ruid != 0) 676 ip->i_mode &= ~(ISUID|ISGID); 677 #ifdef QUOTA 678 ip->i_dquot = inoquota(ip); 679 (void) chkdq(ip, change, 1); 680 (void) chkiq(ip->i_dev, (struct inode *)NULL, (uid_t)uid, 1); 681 return (u.u_error); /* should == 0 ALWAYS !! */ 682 #else 683 return (0); 684 #endif 685 } 686 687 utimes() 688 { 689 register struct a { 690 char *fname; 691 struct timeval *tptr; 692 } *uap = (struct a *)u.u_ap; 693 register struct inode *ip; 694 struct timeval tv[2]; 695 696 if ((ip = owner(uap->fname, FOLLOW)) == NULL) 697 return; 698 if (ip->i_fs->fs_ronly) { 699 u.u_error = EROFS; 700 iput(ip); 701 return; 702 } 703 u.u_error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)); 704 if (u.u_error == 0) { 705 ip->i_flag |= IACC|IUPD|ICHG; 706 iupdat(ip, &tv[0], &tv[1], 0); 707 } 708 iput(ip); 709 } 710 711 /* 712 * Flush any pending I/O. 713 */ 714 sync() 715 { 716 717 update(); 718 } 719 720 /* 721 * Truncate a file given its path name. 722 */ 723 truncate() 724 { 725 struct a { 726 char *fname; 727 off_t length; 728 } *uap = (struct a *)u.u_ap; 729 struct inode *ip; 730 register struct nameidata *ndp = &u.u_nd; 731 732 ndp->ni_nameiop = LOOKUP | FOLLOW; 733 ndp->ni_segflg = UIO_USERSPACE; 734 ndp->ni_dirp = uap->fname; 735 ip = namei(ndp); 736 if (ip == NULL) 737 return; 738 if (access(ip, IWRITE)) 739 goto bad; 740 if ((ip->i_mode&IFMT) == IFDIR) { 741 u.u_error = EISDIR; 742 goto bad; 743 } 744 itrunc(ip, (u_long)uap->length); 745 bad: 746 iput(ip); 747 } 748 749 /* 750 * Truncate a file given a file descriptor. 751 */ 752 ftruncate() 753 { 754 struct a { 755 int fd; 756 off_t length; 757 } *uap = (struct a *)u.u_ap; 758 struct inode *ip; 759 struct file *fp; 760 761 fp = getinode(uap->fd); 762 if (fp == NULL) 763 return; 764 if ((fp->f_flag&FWRITE) == 0) { 765 u.u_error = EINVAL; 766 return; 767 } 768 ip = (struct inode *)fp->f_data; 769 ILOCK(ip); 770 itrunc(ip, (u_long)uap->length); 771 IUNLOCK(ip); 772 } 773 774 /* 775 * Synch an open file. 776 */ 777 fsync() 778 { 779 struct a { 780 int fd; 781 } *uap = (struct a *)u.u_ap; 782 struct inode *ip; 783 struct file *fp; 784 785 fp = getinode(uap->fd); 786 if (fp == NULL) 787 return; 788 ip = (struct inode *)fp->f_data; 789 ILOCK(ip); 790 if (fp->f_flag&FWRITE) 791 ip->i_flag |= ICHG; 792 syncip(ip); 793 IUNLOCK(ip); 794 } 795 796 /* 797 * Rename system call. 798 * rename("foo", "bar"); 799 * is essentially 800 * unlink("bar"); 801 * link("foo", "bar"); 802 * unlink("foo"); 803 * but ``atomically''. Can't do full commit without saving state in the 804 * inode on disk which isn't feasible at this time. Best we can do is 805 * always guarantee the target exists. 806 * 807 * Basic algorithm is: 808 * 809 * 1) Bump link count on source while we're linking it to the 810 * target. This also insure the inode won't be deleted out 811 * from underneath us while we work (it may be truncated by 812 * a concurrent `trunc' or `open' for creation). 813 * 2) Link source to destination. If destination already exists, 814 * delete it first. 815 * 3) Unlink source reference to inode if still around. If a 816 * directory was moved and the parent of the destination 817 * is different from the source, patch the ".." entry in the 818 * directory. 819 * 820 * Source and destination must either both be directories, or both 821 * not be directories. If target is a directory, it must be empty. 822 */ 823 rename() 824 { 825 struct a { 826 char *from; 827 char *to; 828 } *uap = (struct a *)u.u_ap; 829 register struct inode *ip, *xp, *dp; 830 struct dirtemplate dirbuf; 831 int doingdirectory = 0, oldparent = 0, newparent = 0; 832 register struct nameidata *ndp = &u.u_nd; 833 int error = 0; 834 835 ndp->ni_nameiop = DELETE | LOCKPARENT; 836 ndp->ni_segflg = UIO_USERSPACE; 837 ndp->ni_dirp = uap->from; 838 ip = namei(ndp); 839 if (ip == NULL) 840 return; 841 dp = ndp->ni_pdir; 842 if ((ip->i_mode&IFMT) == IFDIR) { 843 register struct direct *d; 844 845 d = &ndp->ni_dent; 846 /* 847 * Avoid ".", "..", and aliases of "." for obvious reasons. 848 */ 849 if ((d->d_namlen == 1 && d->d_name[0] == '.') || 850 (d->d_namlen == 2 && bcmp(d->d_name, "..", 2) == 0) || 851 (dp == ip) || (ip->i_flag & IRENAME)) { 852 iput(dp); 853 if (dp == ip) 854 irele(ip); 855 else 856 iput(ip); 857 u.u_error = EINVAL; 858 return; 859 } 860 ip->i_flag |= IRENAME; 861 oldparent = dp->i_number; 862 doingdirectory++; 863 } 864 iput(dp); 865 866 /* 867 * 1) Bump link count while we're moving stuff 868 * around. If we crash somewhere before 869 * completing our work, the link count 870 * may be wrong, but correctable. 871 */ 872 ip->i_nlink++; 873 ip->i_flag |= ICHG; 874 iupdat(ip, &time, &time, 1); 875 IUNLOCK(ip); 876 877 /* 878 * When the target exists, both the directory 879 * and target inodes are returned locked. 880 */ 881 ndp->ni_nameiop = CREATE | LOCKPARENT | NOCACHE; 882 ndp->ni_dirp = (caddr_t)uap->to; 883 xp = namei(ndp); 884 if (u.u_error) { 885 error = u.u_error; 886 goto out; 887 } 888 dp = ndp->ni_pdir; 889 /* 890 * If ".." must be changed (ie the directory gets a new 891 * parent) then the source directory must not be in the 892 * directory heirarchy above the target, as this would 893 * orphan everything below the source directory. Also 894 * the user must have write permission in the source so 895 * as to be able to change "..". We must repeat the call 896 * to namei, as the parent directory is unlocked by the 897 * call to checkpath(). 898 */ 899 if (oldparent != dp->i_number) 900 newparent = dp->i_number; 901 if (doingdirectory && newparent) { 902 if (access(ip, IWRITE)) 903 goto bad; 904 do { 905 dp = ndp->ni_pdir; 906 if (xp != NULL) 907 iput(xp); 908 u.u_error = checkpath(ip, dp); 909 if (u.u_error) 910 goto out; 911 xp = namei(ndp); 912 if (u.u_error) { 913 error = u.u_error; 914 goto out; 915 } 916 } while (dp != ndp->ni_pdir); 917 } 918 /* 919 * 2) If target doesn't exist, link the target 920 * to the source and unlink the source. 921 * Otherwise, rewrite the target directory 922 * entry to reference the source inode and 923 * expunge the original entry's existence. 924 */ 925 if (xp == NULL) { 926 if (dp->i_dev != ip->i_dev) { 927 error = EXDEV; 928 goto bad; 929 } 930 /* 931 * Account for ".." in new directory. 932 * When source and destination have the same 933 * parent we don't fool with the link count. 934 */ 935 if (doingdirectory && newparent) { 936 dp->i_nlink++; 937 dp->i_flag |= ICHG; 938 iupdat(dp, &time, &time, 1); 939 } 940 error = direnter(ip, ndp); 941 if (error) 942 goto out; 943 } else { 944 if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) { 945 error = EXDEV; 946 goto bad; 947 } 948 /* 949 * Short circuit rename(foo, foo). 950 */ 951 if (xp->i_number == ip->i_number) 952 goto bad; 953 /* 954 * If the parent directory is "sticky", then the user must 955 * own the parent directory, or the destination of the rename, 956 * otherwise the destination may not be changed (except by 957 * root). This implements append-only directories. 958 */ 959 if ((dp->i_mode & ISVTX) && u.u_uid != 0 && 960 u.u_uid != dp->i_uid && xp->i_uid != u.u_uid) { 961 error = EPERM; 962 goto bad; 963 } 964 /* 965 * Target must be empty if a directory 966 * and have no links to it. 967 * Also, insure source and target are 968 * compatible (both directories, or both 969 * not directories). 970 */ 971 if ((xp->i_mode&IFMT) == IFDIR) { 972 if (!dirempty(xp, dp->i_number) || xp->i_nlink > 2) { 973 error = ENOTEMPTY; 974 goto bad; 975 } 976 if (!doingdirectory) { 977 error = ENOTDIR; 978 goto bad; 979 } 980 cacheinval(dp); 981 } else if (doingdirectory) { 982 error = EISDIR; 983 goto bad; 984 } 985 dirrewrite(dp, ip, ndp); 986 if (u.u_error) { 987 error = u.u_error; 988 goto bad1; 989 } 990 /* 991 * Adjust the link count of the target to 992 * reflect the dirrewrite above. If this is 993 * a directory it is empty and there are 994 * no links to it, so we can squash the inode and 995 * any space associated with it. We disallowed 996 * renaming over top of a directory with links to 997 * it above, as the remaining link would point to 998 * a directory without "." or ".." entries. 999 */ 1000 xp->i_nlink--; 1001 if (doingdirectory) { 1002 if (--xp->i_nlink != 0) 1003 panic("rename: linked directory"); 1004 itrunc(xp, (u_long)0); 1005 } 1006 xp->i_flag |= ICHG; 1007 iput(xp); 1008 xp = NULL; 1009 } 1010 1011 /* 1012 * 3) Unlink the source. 1013 */ 1014 ndp->ni_nameiop = DELETE | LOCKPARENT; 1015 ndp->ni_segflg = UIO_USERSPACE; 1016 ndp->ni_dirp = uap->from; 1017 xp = namei(ndp); 1018 if (xp != NULL) 1019 dp = ndp->ni_pdir; 1020 else 1021 dp = NULL; 1022 /* 1023 * Insure that the directory entry still exists and has not 1024 * changed while the new name has been entered. If the source is 1025 * a file then the entry may have been unlinked or renamed. In 1026 * either case there is no further work to be done. If the source 1027 * is a directory then it cannot have been rmdir'ed; its link 1028 * count of three would cause a rmdir to fail with ENOTEMPTY. 1029 * The IRENAME flag insures that it cannot be moved by another 1030 * rename. 1031 */ 1032 if (xp != ip) { 1033 if (doingdirectory) 1034 panic("rename: lost dir entry"); 1035 } else { 1036 /* 1037 * If the source is a directory with a 1038 * new parent, the link count of the old 1039 * parent directory must be decremented 1040 * and ".." set to point to the new parent. 1041 */ 1042 if (doingdirectory && newparent) { 1043 dp->i_nlink--; 1044 dp->i_flag |= ICHG; 1045 error = rdwri(UIO_READ, xp, (caddr_t)&dirbuf, 1046 sizeof (struct dirtemplate), (off_t)0, 1, 1047 (int *)0); 1048 if (error == 0) { 1049 if (dirbuf.dotdot_namlen != 2 || 1050 dirbuf.dotdot_name[0] != '.' || 1051 dirbuf.dotdot_name[1] != '.') { 1052 printf("rename: mangled dir\n"); 1053 } else { 1054 dirbuf.dotdot_ino = newparent; 1055 (void) rdwri(UIO_WRITE, xp, 1056 (caddr_t)&dirbuf, 1057 sizeof (struct dirtemplate), 1058 (off_t)0, 1, (int *)0); 1059 cacheinval(dp); 1060 } 1061 } 1062 } 1063 if (dirremove(ndp)) { 1064 xp->i_nlink--; 1065 xp->i_flag |= ICHG; 1066 } 1067 xp->i_flag &= ~IRENAME; 1068 if (error == 0) /* XXX conservative */ 1069 error = u.u_error; 1070 } 1071 if (dp) 1072 iput(dp); 1073 if (xp) 1074 iput(xp); 1075 irele(ip); 1076 if (error) 1077 u.u_error = error; 1078 return; 1079 1080 bad: 1081 iput(dp); 1082 bad1: 1083 if (xp) 1084 iput(xp); 1085 out: 1086 ip->i_nlink--; 1087 ip->i_flag |= ICHG; 1088 irele(ip); 1089 if (error) 1090 u.u_error = error; 1091 } 1092 1093 /* 1094 * Make a new file. 1095 */ 1096 struct inode * 1097 maknode(mode, ndp) 1098 int mode; 1099 register struct nameidata *ndp; 1100 { 1101 register struct inode *ip; 1102 register struct inode *pdir = ndp->ni_pdir; 1103 ino_t ipref; 1104 1105 if ((mode & IFMT) == IFDIR) 1106 ipref = dirpref(pdir->i_fs); 1107 else 1108 ipref = pdir->i_number; 1109 ip = ialloc(pdir, ipref, mode); 1110 if (ip == NULL) { 1111 iput(pdir); 1112 return (NULL); 1113 } 1114 #ifdef QUOTA 1115 if (ip->i_dquot != NODQUOT) 1116 panic("maknode: dquot"); 1117 #endif 1118 ip->i_flag |= IACC|IUPD|ICHG; 1119 if ((mode & IFMT) == 0) 1120 mode |= IFREG; 1121 ip->i_mode = mode & ~u.u_cmask; 1122 ip->i_nlink = 1; 1123 ip->i_uid = u.u_uid; 1124 ip->i_gid = pdir->i_gid; 1125 if (ip->i_mode & ISGID && !groupmember(ip->i_gid) && !suser()) 1126 ip->i_mode &= ~ISGID; 1127 #ifdef QUOTA 1128 ip->i_dquot = inoquota(ip); 1129 #endif 1130 1131 /* 1132 * Make sure inode goes to disk before directory entry. 1133 */ 1134 iupdat(ip, &time, &time, 1); 1135 u.u_error = direnter(ip, ndp); 1136 if (u.u_error) { 1137 /* 1138 * Write error occurred trying to update directory 1139 * so must deallocate the inode. 1140 */ 1141 ip->i_nlink = 0; 1142 ip->i_flag |= ICHG; 1143 iput(ip); 1144 return (NULL); 1145 } 1146 return (ip); 1147 } 1148 1149 /* 1150 * A virgin directory (no blushing please). 1151 */ 1152 struct dirtemplate mastertemplate = { 1153 0, 12, 1, ".", 1154 0, DIRBLKSIZ - 12, 2, ".." 1155 }; 1156 1157 /* 1158 * Mkdir system call 1159 */ 1160 mkdir() 1161 { 1162 struct a { 1163 char *name; 1164 int dmode; 1165 } *uap = (struct a *)u.u_ap; 1166 register struct inode *ip, *dp; 1167 struct dirtemplate dirtemplate; 1168 register struct nameidata *ndp = &u.u_nd; 1169 1170 ndp->ni_nameiop = CREATE; 1171 ndp->ni_segflg = UIO_USERSPACE; 1172 ndp->ni_dirp = uap->name; 1173 ip = namei(ndp); 1174 if (u.u_error) 1175 return; 1176 if (ip != NULL) { 1177 iput(ip); 1178 u.u_error = EEXIST; 1179 return; 1180 } 1181 dp = ndp->ni_pdir; 1182 uap->dmode &= 0777; 1183 uap->dmode |= IFDIR; 1184 /* 1185 * Must simulate part of maknode here 1186 * in order to acquire the inode, but 1187 * not have it entered in the parent 1188 * directory. The entry is made later 1189 * after writing "." and ".." entries out. 1190 */ 1191 ip = ialloc(dp, dirpref(dp->i_fs), uap->dmode); 1192 if (ip == NULL) { 1193 iput(dp); 1194 return; 1195 } 1196 #ifdef QUOTA 1197 if (ip->i_dquot != NODQUOT) 1198 panic("mkdir: dquot"); 1199 #endif 1200 ip->i_flag |= IACC|IUPD|ICHG; 1201 ip->i_mode = uap->dmode & ~u.u_cmask; 1202 ip->i_nlink = 2; 1203 ip->i_uid = u.u_uid; 1204 ip->i_gid = dp->i_gid; 1205 #ifdef QUOTA 1206 ip->i_dquot = inoquota(ip); 1207 #endif 1208 iupdat(ip, &time, &time, 1); 1209 1210 /* 1211 * Bump link count in parent directory 1212 * to reflect work done below. Should 1213 * be done before reference is created 1214 * so reparation is possible if we crash. 1215 */ 1216 dp->i_nlink++; 1217 dp->i_flag |= ICHG; 1218 iupdat(dp, &time, &time, 1); 1219 1220 /* 1221 * Initialize directory with "." 1222 * and ".." from static template. 1223 */ 1224 dirtemplate = mastertemplate; 1225 dirtemplate.dot_ino = ip->i_number; 1226 dirtemplate.dotdot_ino = dp->i_number; 1227 u.u_error = rdwri(UIO_WRITE, ip, (caddr_t)&dirtemplate, 1228 sizeof (dirtemplate), (off_t)0, 1, (int *)0); 1229 if (u.u_error) { 1230 dp->i_nlink--; 1231 dp->i_flag |= ICHG; 1232 goto bad; 1233 } 1234 if (DIRBLKSIZ > ip->i_fs->fs_fsize) 1235 panic("mkdir: blksize"); /* XXX - should grow with bmap() */ 1236 else 1237 ip->i_size = DIRBLKSIZ; 1238 /* 1239 * Directory all set up, now 1240 * install the entry for it in 1241 * the parent directory. 1242 */ 1243 u.u_error = direnter(ip, ndp); 1244 dp = NULL; 1245 if (u.u_error) { 1246 ndp->ni_nameiop = LOOKUP | NOCACHE; 1247 ndp->ni_segflg = UIO_USERSPACE; 1248 ndp->ni_dirp = uap->name; 1249 dp = namei(ndp); 1250 if (dp) { 1251 dp->i_nlink--; 1252 dp->i_flag |= ICHG; 1253 } 1254 } 1255 bad: 1256 /* 1257 * No need to do an explicit itrunc here, 1258 * irele will do this for us because we set 1259 * the link count to 0. 1260 */ 1261 if (u.u_error) { 1262 ip->i_nlink = 0; 1263 ip->i_flag |= ICHG; 1264 } 1265 if (dp) 1266 iput(dp); 1267 iput(ip); 1268 } 1269 1270 /* 1271 * Rmdir system call. 1272 */ 1273 rmdir() 1274 { 1275 struct a { 1276 char *name; 1277 } *uap = (struct a *)u.u_ap; 1278 register struct inode *ip, *dp; 1279 register struct nameidata *ndp = &u.u_nd; 1280 1281 ndp->ni_nameiop = DELETE | LOCKPARENT; 1282 ndp->ni_segflg = UIO_USERSPACE; 1283 ndp->ni_dirp = uap->name; 1284 ip = namei(ndp); 1285 if (ip == NULL) 1286 return; 1287 dp = ndp->ni_pdir; 1288 /* 1289 * No rmdir "." please. 1290 */ 1291 if (dp == ip) { 1292 irele(dp); 1293 iput(ip); 1294 u.u_error = EINVAL; 1295 return; 1296 } 1297 if ((ip->i_mode&IFMT) != IFDIR) { 1298 u.u_error = ENOTDIR; 1299 goto out; 1300 } 1301 /* 1302 * Don't remove a mounted on directory. 1303 */ 1304 if (ip->i_dev != dp->i_dev) { 1305 u.u_error = EBUSY; 1306 goto out; 1307 } 1308 /* 1309 * Verify the directory is empty (and valid). 1310 * (Rmdir ".." won't be valid since 1311 * ".." will contain a reference to 1312 * the current directory and thus be 1313 * non-empty.) 1314 */ 1315 if (ip->i_nlink != 2 || !dirempty(ip, dp->i_number)) { 1316 u.u_error = ENOTEMPTY; 1317 goto out; 1318 } 1319 /* 1320 * Delete reference to directory before purging 1321 * inode. If we crash in between, the directory 1322 * will be reattached to lost+found, 1323 */ 1324 if (dirremove(ndp) == 0) 1325 goto out; 1326 dp->i_nlink--; 1327 dp->i_flag |= ICHG; 1328 cacheinval(dp); 1329 iput(dp); 1330 dp = NULL; 1331 /* 1332 * Truncate inode. The only stuff left 1333 * in the directory is "." and "..". The 1334 * "." reference is inconsequential since 1335 * we're quashing it. The ".." reference 1336 * has already been adjusted above. We've 1337 * removed the "." reference and the reference 1338 * in the parent directory, but there may be 1339 * other hard links so decrement by 2 and 1340 * worry about them later. 1341 */ 1342 ip->i_nlink -= 2; 1343 itrunc(ip, (u_long)0); 1344 cacheinval(ip); 1345 out: 1346 if (dp) 1347 iput(dp); 1348 iput(ip); 1349 } 1350 1351 struct file * 1352 getinode(fdes) 1353 int fdes; 1354 { 1355 struct file *fp; 1356 1357 if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL) { 1358 u.u_error = EBADF; 1359 return ((struct file *)0); 1360 } 1361 if (fp->f_type != DTYPE_INODE) { 1362 u.u_error = EINVAL; 1363 return ((struct file *)0); 1364 } 1365 return (fp); 1366 } 1367 1368 /* 1369 * mode mask for creation of files 1370 */ 1371 umask() 1372 { 1373 register struct a { 1374 int mask; 1375 } *uap = (struct a *)u.u_ap; 1376 1377 u.u_r.r_val1 = u.u_cmask; 1378 u.u_cmask = uap->mask & 07777; 1379 } 1380