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