1 /* lfs_vnops.c 4.37 82/09/06 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/dir.h" 6 #include "../h/user.h" 7 #include "../h/kernel.h" 8 #include "../h/file.h" 9 #include "../h/stat.h" 10 #include "../h/inode.h" 11 #include "../h/fs.h" 12 #include "../h/buf.h" 13 #include "../h/proc.h" 14 #include "../h/inline.h" 15 /* no reason to inline expand these guys here */ 16 #undef ilock 17 #undef iunlock 18 #include "../h/quota.h" 19 #include "../h/descrip.h" 20 #include "../h/uio.h" 21 #include "../h/socket.h" 22 23 chdir() 24 { 25 26 chdirec(&u.u_cdir); 27 } 28 29 chroot() 30 { 31 32 if (suser()) 33 chdirec(&u.u_rdir); 34 } 35 36 chdirec(ipp) 37 register struct inode **ipp; 38 { 39 register struct inode *ip; 40 struct a { 41 char *fname; 42 }; 43 44 ip = namei(uchar, 0, 1); 45 if(ip == NULL) 46 return; 47 if((ip->i_mode&IFMT) != IFDIR) { 48 u.u_error = ENOTDIR; 49 goto bad; 50 } 51 if(access(ip, IEXEC)) 52 goto bad; 53 iunlock(ip); 54 if (*ipp) 55 irele(*ipp); 56 *ipp = ip; 57 return; 58 59 bad: 60 iput(ip); 61 } 62 63 /* 64 * Open system call. 65 */ 66 open() 67 { 68 register struct inode *ip; 69 register struct a { 70 char *fname; 71 int flags; 72 int mode; 73 } *uap; 74 int checkpermissions = 1; 75 76 uap = (struct a *)u.u_ap; 77 if (uap->flags&FCREATE) { 78 ip = namei(uchar, 1, 1); 79 if (ip == NULL) { 80 if (u.u_error) 81 return; 82 ip = maknode(uap->mode&07777&(~ISVTX)); 83 checkpermissions = 0; 84 uap->flags &= ~FTRUNCATE; 85 } 86 } else 87 ip = namei(uchar, 0, 1); 88 if (ip == NULL) 89 return; 90 open1(ip, ++uap->flags, checkpermissions); 91 } 92 93 #ifndef NOCOMPAT 94 /* 95 * Creat system call. 96 */ 97 ocreat() 98 { 99 register struct inode *ip; 100 register struct a { 101 char *fname; 102 int fmode; 103 } *uap; 104 105 uap = (struct a *)u.u_ap; 106 ip = namei(uchar, 1, 1); 107 if (ip == NULL) { 108 if (u.u_error) 109 return; 110 ip = maknode(uap->fmode&07777&(~ISVTX)); 111 if (ip == NULL) 112 return; 113 open1(ip, FWRITE, 0); 114 } else 115 open1(ip, FWRITE|FTRUNCATE, 0); 116 } 117 #endif 118 119 /* 120 * Common code for open and creat. 121 * Check permissions (if we haven't done so already), 122 * allocate an open file structure, and call 123 * the device open routine, if any. 124 */ 125 open1(ip, mode, checkpermissions) 126 register struct inode *ip; 127 register mode; 128 { 129 register struct file *fp; 130 int i, flags; 131 132 if (checkpermissions) { 133 if (mode&FREAD) 134 if (access(ip, IREAD)) 135 goto bad; 136 if (mode&FWRITE) { 137 if (access(ip, IWRITE)) 138 goto bad; 139 if ((ip->i_mode&IFMT) == IFDIR) { 140 u.u_error = EISDIR; 141 goto bad; 142 } 143 } 144 } 145 146 /* 147 * Check locking on inode. Release "inode lock" 148 * while doing so in case we block inside flocki. 149 */ 150 flags = 0; 151 if (mode&(FRDLOCK|FWRLOCK)) { 152 iunlock(ip); 153 flags = flocki(ip, 0, mode); 154 ilock(ip); 155 if (u.u_error) 156 goto bad; 157 } 158 if (mode&FTRUNCATE) 159 itrunc(ip, 0); 160 iunlock(ip); 161 if ((fp = falloc()) == NULL) 162 goto out; 163 fp->f_flag = mode & FMODES; 164 fp->f_type = DTYPE_FILE; 165 i = u.u_r.r_val1; 166 fp->f_inode = ip; 167 openi(ip, mode); 168 if (u.u_error == 0) { 169 u.u_pofile[i] = flags; 170 return; 171 } 172 u.u_ofile[i] = NULL; 173 fp->f_count--; 174 out: 175 irele(ip); 176 return; 177 bad: 178 iput(ip); 179 } 180 181 /* 182 * Mknod system call 183 */ 184 mknod() 185 { 186 register struct inode *ip; 187 register struct a { 188 char *fname; 189 int fmode; 190 int dev; 191 } *uap; 192 193 uap = (struct a *)u.u_ap; 194 if (suser()) { 195 ip = namei(uchar, 1, 0); 196 if (ip != NULL) { 197 u.u_error = EEXIST; 198 goto out; 199 } 200 } 201 if (u.u_error) 202 return; 203 ip = maknode(uap->fmode); 204 if (ip == NULL) 205 return; 206 if (uap->dev) { 207 /* 208 * Want to be able to use this to make badblock 209 * inodes, so don't truncate the dev number. 210 */ 211 ip->i_rdev = uap->dev; 212 ip->i_flag |= IACC|IUPD|ICHG; 213 } 214 215 out: 216 iput(ip); 217 } 218 219 /* 220 * link system call 221 */ 222 link() 223 { 224 register struct inode *ip, *xp; 225 register struct a { 226 char *target; 227 char *linkname; 228 } *uap; 229 230 uap = (struct a *)u.u_ap; 231 ip = namei(uchar, 0, 1); /* well, this routine is doomed anyhow */ 232 if (ip == NULL) 233 return; 234 if ((ip->i_mode&IFMT)==IFDIR && !suser()) { 235 iput(ip); 236 return; 237 } 238 ip->i_nlink++; 239 ip->i_flag |= ICHG; 240 iupdat(ip, &time.tv_sec, &time.tv_sec, 1); 241 iunlock(ip); 242 u.u_dirp = (caddr_t)uap->linkname; 243 xp = namei(uchar, 1, 0); 244 if (xp != NULL) { 245 u.u_error = EEXIST; 246 iput(xp); 247 goto out; 248 } 249 if (u.u_error) 250 goto out; 251 if (u.u_pdir->i_dev != ip->i_dev) { 252 iput(u.u_pdir); 253 u.u_error = EXDEV; 254 goto out; 255 } 256 direnter(ip); 257 out: 258 if (u.u_error) { 259 ip->i_nlink--; 260 ip->i_flag |= ICHG; 261 } 262 irele(ip); 263 } 264 265 /* 266 * symlink -- make a symbolic link 267 */ 268 symlink() 269 { 270 register struct a { 271 char *target; 272 char *linkname; 273 } *uap; 274 register struct inode *ip; 275 register char *tp; 276 register c, nc; 277 278 uap = (struct a *)u.u_ap; 279 tp = uap->target; 280 nc = 0; 281 while (c = fubyte(tp)) { 282 if (c < 0) { 283 u.u_error = EFAULT; 284 return; 285 } 286 tp++; 287 nc++; 288 } 289 u.u_dirp = uap->linkname; 290 ip = namei(uchar, 1, 0); 291 if (ip) { 292 iput(ip); 293 u.u_error = EEXIST; 294 return; 295 } 296 if (u.u_error) 297 return; 298 ip = maknode(IFLNK | 0777); 299 if (ip == NULL) 300 return; 301 u.u_error = rdwri(UIO_WRITE, ip, uap->target, nc, 0, 0, (int *)0); 302 iput(ip); 303 } 304 305 /* 306 * Unlink system call. 307 * Hard to avoid races here, especially 308 * in unlinking directories. 309 */ 310 unlink() 311 { 312 register struct inode *ip, *pp; 313 struct a { 314 char *fname; 315 }; 316 int unlinkingdot = 0; 317 318 pp = namei(uchar, 2, 0); 319 if (pp == NULL) 320 return; 321 322 /* 323 * Check for unlink(".") 324 * to avoid hanging on the iget 325 */ 326 if (pp->i_number == u.u_dent.d_ino) { 327 ip = pp; 328 ip->i_count++; 329 unlinkingdot++; 330 } else 331 ip = iget(pp->i_dev, pp->i_fs, u.u_dent.d_ino); 332 if(ip == NULL) 333 goto out1; 334 if((ip->i_mode&IFMT)==IFDIR && !suser()) 335 goto out; 336 /* 337 * Don't unlink a mounted file. 338 */ 339 if (ip->i_dev != pp->i_dev) { 340 u.u_error = EBUSY; 341 goto out; 342 } 343 if (ip->i_flag&ITEXT) 344 xrele(ip); /* try once to free text */ 345 if (dirremove()) { 346 ip->i_nlink--; 347 ip->i_flag |= ICHG; 348 } 349 out: 350 if (unlinkingdot) 351 irele(ip); 352 else 353 iput(ip); 354 out1: 355 iput(pp); 356 } 357 358 /* 359 * Seek system call 360 */ 361 lseek() 362 { 363 register struct file *fp; 364 register struct a { 365 int fd; 366 off_t off; 367 int sbase; 368 } *uap; 369 370 uap = (struct a *)u.u_ap; 371 fp = getf(uap->fd); 372 if (fp == NULL) 373 return; 374 if (fp->f_type == DTYPE_SOCKET) { 375 u.u_error = ESPIPE; 376 return; 377 } 378 if (uap->sbase == FSEEK_RELATIVE) 379 uap->off += fp->f_offset; 380 else if (uap->sbase == FSEEK_EOF) 381 uap->off += fp->f_inode->i_size; 382 fp->f_offset = uap->off; 383 u.u_r.r_off = uap->off; 384 } 385 386 /* 387 * Access system call 388 */ 389 saccess() 390 { 391 register svuid, svgid; 392 register struct inode *ip; 393 register struct a { 394 char *fname; 395 int fmode; 396 } *uap; 397 398 uap = (struct a *)u.u_ap; 399 svuid = u.u_uid; 400 svgid = u.u_gid; 401 u.u_uid = u.u_ruid; 402 u.u_gid = u.u_rgid; 403 ip = namei(uchar, 0, 1); 404 if (ip != NULL) { 405 if (uap->fmode&FACCESS_READ && access(ip, IREAD)) 406 goto done; 407 if (uap->fmode&FACCESS_WRITE && access(ip, IWRITE)) 408 goto done; 409 if (uap->fmode&FACCESS_EXECUTE && access(ip, IEXEC)) 410 goto done; 411 done: 412 iput(ip); 413 } 414 u.u_uid = svuid; 415 u.u_gid = svgid; 416 } 417 418 /* 419 * the fstat system call. 420 */ 421 fstat() 422 { 423 register struct file *fp; 424 register struct a { 425 int fd; 426 struct stat *sb; 427 } *uap; 428 429 uap = (struct a *)u.u_ap; 430 fp = getf(uap->fd); 431 if (fp == NULL) 432 return; 433 if (fp->f_type == DTYPE_SOCKET) 434 u.u_error = sostat(fp->f_socket, uap->sb); 435 else 436 stat1(fp->f_inode, uap->sb); 437 } 438 439 /* 440 * Stat system call. This version follows links. 441 */ 442 stat() 443 { 444 register struct inode *ip; 445 register struct a { 446 char *fname; 447 struct stat *sb; 448 } *uap; 449 450 uap = (struct a *)u.u_ap; 451 ip = namei(uchar, 0, 1); 452 if (ip == NULL) 453 return; 454 stat1(ip, uap->sb); 455 iput(ip); 456 } 457 458 /* 459 * Lstat system call. This version does not follow links. 460 */ 461 lstat() 462 { 463 register struct inode *ip; 464 register struct a { 465 char *fname; 466 struct stat *sb; 467 } *uap; 468 469 uap = (struct a *)u.u_ap; 470 ip = namei(uchar, 0, 0); 471 if (ip == NULL) 472 return; 473 stat1(ip, uap->sb); 474 iput(ip); 475 } 476 477 /* 478 * The basic routine for fstat and stat: 479 * get the inode and pass appropriate parts back. 480 */ 481 stat1(ip, ub) 482 register struct inode *ip; 483 struct stat *ub; 484 { 485 struct stat ds; 486 487 IUPDAT(ip, &time.tv_sec, &time.tv_sec, 0); 488 /* 489 * Copy from inode table 490 */ 491 ds.st_dev = ip->i_dev; 492 ds.st_ino = ip->i_number; 493 ds.st_mode = ip->i_mode; 494 ds.st_nlink = ip->i_nlink; 495 ds.st_uid = ip->i_uid; 496 ds.st_gid = ip->i_gid; 497 ds.st_rdev = (dev_t)ip->i_rdev; 498 ds.st_size = ip->i_size; 499 ds.st_atime = ip->i_atime; 500 ds.st_mtime = ip->i_mtime; 501 ds.st_ctime = ip->i_ctime; 502 /* this doesn't belong here */ 503 if ((ip->i_mode&IFMT) == IFBLK) 504 ds.st_blksize = BLKDEV_IOSIZE; 505 else if ((ip->i_mode&IFMT) == IFCHR) 506 ds.st_blksize = MAXBSIZE; 507 else 508 ds.st_blksize = ip->i_fs->fs_bsize; 509 if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0) 510 u.u_error = EFAULT; 511 } 512 513 /* 514 * Return target name of a symbolic link 515 */ 516 readlink() 517 { 518 register struct inode *ip; 519 register struct a { 520 char *name; 521 char *buf; 522 int count; 523 } *uap = (struct a *)u.u_ap; 524 int resid; 525 526 ip = namei(uchar, 0, 0); 527 if (ip == NULL) 528 return; 529 if ((ip->i_mode&IFMT) != IFLNK) { 530 u.u_error = ENXIO; 531 goto out; 532 } 533 u.u_error = rdwri(UIO_READ, ip, uap->buf, uap->count, 0, 0, &resid); 534 out: 535 iput(ip); 536 u.u_r.r_val1 = uap->count - resid; 537 } 538 539 chmod() 540 { 541 struct inode *ip; 542 struct a { 543 char *fname; 544 int fmode; 545 } *uap; 546 547 uap = (struct a *)u.u_ap; 548 if ((ip = owner(1)) == NULL) 549 return; 550 chmod1(ip, uap->fmode); 551 } 552 553 fchmod() 554 { 555 struct a { 556 int fd; 557 int fmode; 558 } *uap; 559 register struct inode *ip; 560 register struct file *fp; 561 562 uap = (struct a *)u.u_ap; 563 fp = getf(uap->fd); 564 if (fp == NULL) 565 return; 566 if (fp->f_type == DTYPE_SOCKET) { 567 u.u_error = EINVAL; 568 return; 569 } 570 ip = fp->f_inode; 571 ilock(ip); 572 if (u.u_uid != ip->i_uid && !suser()) { 573 iunlock(ip); 574 return; 575 } 576 chmod1(ip, uap->fmode); 577 } 578 579 chmod1(ip, mode) 580 register struct inode *ip; 581 register int mode; 582 { 583 register int *gp; 584 585 ip->i_mode &= ~07777; 586 if (u.u_uid) { 587 mode &= ~ISVTX; 588 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 589 if (*gp == ip->i_gid) 590 goto ok; 591 mode &= ~ISGID; 592 ok: 593 ; 594 #ifdef MUSH 595 if (u.u_quota->q_syflags & QF_UMASK && u.u_uid != 0 && 596 (ip->i_mode & IFMT) != IFCHR) 597 mode &= ~u.u_cmask; 598 #endif 599 } 600 ip->i_mode |= mode&07777; 601 ip->i_flag |= ICHG; 602 if (ip->i_flag&ITEXT && (ip->i_mode&ISVTX)==0) 603 xrele(ip); 604 iput(ip); 605 } 606 607 chown() 608 { 609 struct inode *ip; 610 struct a { 611 char *fname; 612 int uid; 613 int gid; 614 } *uap; 615 616 uap = (struct a *)u.u_ap; 617 if (!suser() || (ip = owner(0)) == NULL) 618 return; 619 chown1(ip, uap->uid, uap->gid); 620 } 621 622 fchown() 623 { 624 struct a { 625 int fd; 626 int uid; 627 int gid; 628 } *uap; 629 register struct inode *ip; 630 register struct file *fp; 631 632 uap = (struct a *)u.u_ap; 633 fp = getf(uap->fd); 634 if (fp == NULL) 635 return; 636 if (fp->f_type == DTYPE_SOCKET) { 637 u.u_error = EINVAL; 638 return; 639 } 640 ip = fp->f_inode; 641 ilock(ip); 642 if (!suser()) { 643 iunlock(ip); 644 return; 645 } 646 chown1(ip, uap->uid, uap->gid); 647 } 648 649 /* 650 * Perform chown operation on inode ip; 651 * inode must be locked prior to call. 652 */ 653 chown1(ip, uid, gid) 654 register struct inode *ip; 655 int uid, gid; 656 { 657 #ifdef QUOTA 658 register long change; 659 660 /* 661 * This doesn't allow for holes in files (which hopefully don't 662 * happen often in files that we chown), and is not accurate anyway 663 * (eg: it totally ignores 3 level indir blk files - but hopefully 664 * noone who can make a file that big will have a quota) 665 */ 666 if (ip->i_uid == uid) 667 change = 0; 668 else { 669 register struct fs *fs = ip->i_fs; 670 671 if (ip->i_size > (change = NDADDR * fs->fs_bsize)) { 672 register off_t size; 673 674 size = blkroundup(fs, ip->i_size) - change; 675 change += size; 676 change += fs->fs_bsize; 677 /* this assumes NIADDR <= 2 */ 678 if (size > NINDIR(fs) * fs->fs_bsize) 679 change += fs->fs_bsize; 680 } else 681 change = fragroundup(fs, ip->i_size); 682 change /= DEV_BSIZE; 683 } 684 chkdq(ip, -change, 1); 685 chkiq(ip->i_dev, ip, ip->i_uid, 1); 686 dqrele(ip->i_dquot); 687 #endif 688 /* 689 * keep uid/gid's in sane range -- no err, 690 * so chown(file, uid, -1) will do something useful 691 */ 692 if (uid >= 0 && uid <= 32767) /* should have a constant */ 693 ip->i_uid = uid; 694 if (gid >= 0 && gid <= 32767) /* same here */ 695 ip->i_gid = gid; 696 ip->i_flag |= ICHG; 697 if (u.u_ruid != 0) 698 ip->i_mode &= ~(ISUID|ISGID); 699 #ifdef QUOTA 700 ip->i_dquot = inoquota(ip); 701 chkdq(ip, change, 1); 702 chkiq(ip->i_dev, NULL, uid, 1); 703 #endif 704 iput(ip); 705 } 706 707 /* 708 * Set IUPD and IACC times on file. 709 * Can't set ICHG. 710 */ 711 outime() 712 { 713 register struct a { 714 char *fname; 715 time_t *tptr; 716 } *uap; 717 register struct inode *ip; 718 time_t tv[2]; 719 720 uap = (struct a *)u.u_ap; 721 if ((ip = owner(1)) == NULL) 722 return; 723 if (copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof(tv))) { 724 u.u_error = EFAULT; 725 } else { 726 ip->i_flag |= IACC|IUPD|ICHG; 727 iupdat(ip, &tv[0], &tv[1], 0); 728 } 729 iput(ip); 730 } 731 732 sync() 733 { 734 735 update(0); 736 } 737 738 flock() 739 { 740 struct a { 741 int fd; 742 int how; 743 } *uap; 744 register struct file *fp; 745 register int cmd, flags; 746 747 uap = (struct a *)u.u_ap; 748 fp = getf(uap->fd); 749 if (fp == NULL) 750 return; 751 if (fp->f_type == DTYPE_SOCKET) { /* XXX */ 752 u.u_error = EINVAL; 753 return; 754 } 755 cmd = uap->how; 756 flags = u.u_pofile[uap->fd] & (RDLOCK|WRLOCK); 757 if (cmd&FUNLOCK) { 758 if (flags == 0) { 759 u.u_error = EINVAL; 760 return; 761 } 762 funlocki(fp->f_inode, flags); 763 u.u_pofile[uap->fd] &= ~(RDLOCK|WRLOCK); 764 return; 765 } 766 /* 767 * No reason to write lock a file we've already 768 * write locked, similarly with a read lock. 769 */ 770 if ((flags&WRLOCK) && (cmd&FWRLOCK) || 771 (flags&RDLOCK) && (cmd&FRDLOCK)) 772 return; 773 u.u_pofile[uap->fd] = flocki(fp->f_inode, u.u_pofile[uap->fd], cmd); 774 } 775 776 truncate() 777 { 778 struct a { 779 char *fname; 780 int length; 781 } *uap = (struct a *)u.u_ap; 782 struct inode *ip; 783 784 ip = namei(uchar, 0, 1); 785 if (ip == NULL) 786 return; 787 if (access(ip, IWRITE)) 788 goto bad; 789 if ((ip->i_mode&IFMT) == IFDIR) { 790 u.u_error = EISDIR; 791 goto bad; 792 } 793 itrunc(ip, uap->length); 794 return; 795 bad: 796 iput(ip); 797 } 798 799 ftruncate() 800 { 801 struct a { 802 int fd; 803 int length; 804 } *uap = (struct a *)u.u_ap; 805 struct inode *ip; 806 struct file *fp; 807 808 fp = getf(uap->fd); 809 if (fp == NULL) 810 return; 811 if (fp->f_type == DTYPE_SOCKET) { 812 u.u_error = EINVAL; 813 return; 814 } 815 if ((fp->f_flag&FWRITE) == 0) { 816 u.u_error = EINVAL; 817 return; 818 } 819 ip = fp->f_inode; 820 ilock(ip); 821 itrunc(ip, uap->length); 822 } 823 824 rename() 825 { 826 #ifdef notdef 827 struct a { 828 char *from; 829 char *to; 830 } *uap; 831 #endif 832 833 } 834 835 /* 836 * Make a new file. 837 */ 838 struct inode * 839 maknode(mode) 840 int mode; 841 { 842 register struct inode *ip; 843 ino_t ipref; 844 845 if ((mode & IFMT) == IFDIR) 846 ipref = dirpref(u.u_pdir->i_fs); 847 else 848 ipref = u.u_pdir->i_number; 849 ip = ialloc(u.u_pdir, ipref, mode); 850 if (ip == NULL) { 851 iput(u.u_pdir); 852 return (NULL); 853 } 854 #ifdef QUOTA 855 if (ip->i_dquot != NODQUOT) 856 panic("maknode: dquot"); 857 #endif 858 ip->i_flag |= IACC|IUPD|ICHG; 859 if ((mode & IFMT) == 0) 860 mode |= IFREG; 861 ip->i_mode = mode & ~u.u_cmask; 862 ip->i_nlink = 1; 863 ip->i_uid = u.u_uid; 864 ip->i_gid = u.u_pdir->i_gid; 865 #ifdef QUOTA 866 ip->i_dquot = inoquota(ip); 867 #endif 868 869 /* 870 * Make sure inode goes to disk before directory entry. 871 */ 872 iupdat(ip, &time.tv_sec, &time.tv_sec, 1); 873 direnter(ip); 874 if (u.u_error) { 875 /* 876 * write error occurred trying to update directory 877 * so must deallocate the inode 878 */ 879 ip->i_nlink = 0; 880 ip->i_flag |= ICHG; 881 iput(ip); 882 return (NULL); 883 } 884 return (ip); 885 } 886