1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)vfs_syscalls.c 7.96 (Berkeley) 07/20/92 8 */ 9 10 #include "param.h" 11 #include "systm.h" 12 #include "namei.h" 13 #include "filedesc.h" 14 #include "kernel.h" 15 #include "file.h" 16 #include "stat.h" 17 #include "vnode.h" 18 #include "mount.h" 19 #include "proc.h" 20 #include "uio.h" 21 #include "malloc.h" 22 #include "dirent.h" 23 #include <vm/vm.h> 24 25 /* 26 * Virtual File System System Calls 27 */ 28 29 /* 30 * Mount system call. 31 */ 32 struct mount_args { 33 int type; 34 char *dir; 35 int flags; 36 caddr_t data; 37 }; 38 /* ARGSUSED */ 39 mount(p, uap, retval) 40 struct proc *p; 41 register struct mount_args *uap; 42 int *retval; 43 { 44 register struct vnode *vp; 45 register struct mount *mp; 46 int error, flag; 47 struct nameidata nd; 48 49 /* 50 * Must be super user 51 */ 52 if (error = suser(p->p_ucred, &p->p_acflag)) 53 return (error); 54 /* 55 * Get vnode to be covered 56 */ 57 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->dir, p); 58 if (error = namei(&nd)) 59 return (error); 60 vp = nd.ni_vp; 61 if (uap->flags & MNT_UPDATE) { 62 if ((vp->v_flag & VROOT) == 0) { 63 vput(vp); 64 return (EINVAL); 65 } 66 mp = vp->v_mount; 67 /* 68 * We allow going from read-only to read-write, 69 * but not from read-write to read-only. 70 */ 71 if ((mp->mnt_flag & MNT_RDONLY) == 0 && 72 (uap->flags & MNT_RDONLY) != 0) { 73 vput(vp); 74 return (EOPNOTSUPP); /* Needs translation */ 75 } 76 flag = mp->mnt_flag; 77 mp->mnt_flag |= MNT_UPDATE; 78 VOP_UNLOCK(vp); 79 goto update; 80 } 81 if (vp->v_usecount != 1 && (uap->flags & MNT_UNION) == 0) { 82 vput(vp); 83 return (EBUSY); 84 } 85 if (error = vinvalbuf(vp, 1, p->p_ucred, p)) 86 return (error); 87 if (vp->v_type != VDIR) { 88 vput(vp); 89 return (ENOTDIR); 90 } 91 if ((unsigned long)uap->type > MOUNT_MAXTYPE || 92 vfssw[uap->type] == (struct vfsops *)0) { 93 vput(vp); 94 return (ENODEV); 95 } 96 97 /* 98 * Allocate and initialize the file system. 99 */ 100 mp = (struct mount *)malloc((u_long)sizeof(struct mount), 101 M_MOUNT, M_WAITOK); 102 bzero((char *)mp, (u_long)sizeof(struct mount)); 103 mp->mnt_op = vfssw[uap->type]; 104 if (error = vfs_lock(mp)) { 105 free((caddr_t)mp, M_MOUNT); 106 vput(vp); 107 return (error); 108 } 109 if (vp->v_mountedhere != (struct mount *)0) { 110 vfs_unlock(mp); 111 free((caddr_t)mp, M_MOUNT); 112 vput(vp); 113 return (EBUSY); 114 } 115 vp->v_mountedhere = mp; 116 mp->mnt_vnodecovered = vp; 117 update: 118 /* 119 * Set the mount level flags. 120 */ 121 if (uap->flags & MNT_RDONLY) 122 mp->mnt_flag |= MNT_RDONLY; 123 else 124 mp->mnt_flag &= ~MNT_RDONLY; 125 if (uap->flags & MNT_NOSUID) 126 mp->mnt_flag |= MNT_NOSUID; 127 else 128 mp->mnt_flag &= ~MNT_NOSUID; 129 if (uap->flags & MNT_NOEXEC) 130 mp->mnt_flag |= MNT_NOEXEC; 131 else 132 mp->mnt_flag &= ~MNT_NOEXEC; 133 if (uap->flags & MNT_NODEV) 134 mp->mnt_flag |= MNT_NODEV; 135 else 136 mp->mnt_flag &= ~MNT_NODEV; 137 if (uap->flags & MNT_SYNCHRONOUS) 138 mp->mnt_flag |= MNT_SYNCHRONOUS; 139 else 140 mp->mnt_flag &= ~MNT_SYNCHRONOUS; 141 if (uap->flags & MNT_UNION) 142 mp->mnt_flag |= MNT_UNION; 143 else 144 mp->mnt_flag &= ~MNT_UNION; 145 /* 146 * Mount the filesystem. 147 */ 148 error = VFS_MOUNT(mp, uap->dir, uap->data, &nd, p); 149 if (mp->mnt_flag & MNT_UPDATE) { 150 mp->mnt_flag &= ~MNT_UPDATE; 151 vrele(vp); 152 if (error) 153 mp->mnt_flag = flag; 154 return (error); 155 } 156 /* 157 * Put the new filesystem on the mount list after root. 158 */ 159 mp->mnt_next = rootfs->mnt_next; 160 mp->mnt_prev = rootfs; 161 rootfs->mnt_next = mp; 162 mp->mnt_next->mnt_prev = mp; 163 cache_purge(vp); 164 if (!error) { 165 VOP_UNLOCK(vp); 166 vfs_unlock(mp); 167 error = VFS_START(mp, 0, p); 168 } else { 169 vfs_remove(mp); 170 free((caddr_t)mp, M_MOUNT); 171 vput(vp); 172 } 173 return (error); 174 } 175 176 /* 177 * Unmount system call. 178 * 179 * Note: unmount takes a path to the vnode mounted on as argument, 180 * not special file (as before). 181 */ 182 struct unmount_args { 183 char *pathp; 184 int flags; 185 }; 186 /* ARGSUSED */ 187 unmount(p, uap, retval) 188 struct proc *p; 189 register struct unmount_args *uap; 190 int *retval; 191 { 192 register struct vnode *vp; 193 struct mount *mp; 194 int error; 195 struct nameidata nd; 196 197 /* 198 * Must be super user 199 */ 200 if (error = suser(p->p_ucred, &p->p_acflag)) 201 return (error); 202 203 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->pathp, p); 204 if (error = namei(&nd)) 205 return (error); 206 vp = nd.ni_vp; 207 /* 208 * Must be the root of the filesystem 209 */ 210 if ((vp->v_flag & VROOT) == 0) { 211 vput(vp); 212 return (EINVAL); 213 } 214 mp = vp->v_mount; 215 vput(vp); 216 return (dounmount(mp, uap->flags, p)); 217 } 218 219 /* 220 * Do an unmount. 221 */ 222 dounmount(mp, flags, p) 223 register struct mount *mp; 224 int flags; 225 struct proc *p; 226 { 227 struct vnode *coveredvp; 228 int error; 229 230 coveredvp = mp->mnt_vnodecovered; 231 if (vfs_busy(mp)) 232 return (EBUSY); 233 mp->mnt_flag |= MNT_UNMOUNT; 234 if (error = vfs_lock(mp)) 235 return (error); 236 237 vnode_pager_umount(mp); /* release cached vnodes */ 238 cache_purgevfs(mp); /* remove cache entries for this file sys */ 239 if ((error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p)) == 0 || 240 (flags & MNT_FORCE)) 241 error = VFS_UNMOUNT(mp, flags, p); 242 mp->mnt_flag &= ~MNT_UNMOUNT; 243 vfs_unbusy(mp); 244 if (error) { 245 vfs_unlock(mp); 246 } else { 247 vrele(coveredvp); 248 vfs_remove(mp); 249 if (mp->mnt_mounth != NULL) 250 panic("unmount: dangling vnode"); 251 free((caddr_t)mp, M_MOUNT); 252 } 253 return (error); 254 } 255 256 /* 257 * Sync system call. 258 * Sync each mounted filesystem. 259 */ 260 struct sync_args { 261 int dummy; 262 }; 263 /* ARGSUSED */ 264 sync(p, uap, retval) 265 struct proc *p; 266 struct sync_args *uap; 267 int *retval; 268 { 269 register struct mount *mp; 270 struct mount *omp; 271 272 mp = rootfs; 273 do { 274 /* 275 * The lock check below is to avoid races with mount 276 * and unmount. 277 */ 278 if ((mp->mnt_flag & (MNT_MLOCK|MNT_RDONLY|MNT_MPBUSY)) == 0 && 279 !vfs_busy(mp)) { 280 VFS_SYNC(mp, MNT_NOWAIT, p->p_ucred, p); 281 omp = mp; 282 mp = mp->mnt_next; 283 vfs_unbusy(omp); 284 } else 285 mp = mp->mnt_next; 286 } while (mp != rootfs); 287 return (0); 288 } 289 290 /* 291 * Operate on filesystem quotas. 292 */ 293 struct quotactl_args { 294 char *path; 295 int cmd; 296 int uid; 297 caddr_t arg; 298 }; 299 /* ARGSUSED */ 300 quotactl(p, uap, retval) 301 struct proc *p; 302 register struct quotactl_args *uap; 303 int *retval; 304 { 305 register struct mount *mp; 306 int error; 307 struct nameidata nd; 308 309 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p); 310 if (error = namei(&nd)) 311 return (error); 312 mp = nd.ni_vp->v_mount; 313 vrele(nd.ni_vp); 314 return (VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg, p)); 315 } 316 317 /* 318 * Get filesystem statistics. 319 */ 320 struct statfs_args { 321 char *path; 322 struct statfs *buf; 323 }; 324 /* ARGSUSED */ 325 statfs(p, uap, retval) 326 struct proc *p; 327 register struct statfs_args *uap; 328 int *retval; 329 { 330 register struct mount *mp; 331 register struct statfs *sp; 332 int error; 333 struct nameidata nd; 334 335 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p); 336 if (error = namei(&nd)) 337 return (error); 338 mp = nd.ni_vp->v_mount; 339 sp = &mp->mnt_stat; 340 vrele(nd.ni_vp); 341 if (error = VFS_STATFS(mp, sp, p)) 342 return (error); 343 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 344 return (copyout((caddr_t)sp, (caddr_t)uap->buf, sizeof(*sp))); 345 } 346 347 /* 348 * Get filesystem statistics. 349 */ 350 struct fstatfs_args { 351 int fd; 352 struct statfs *buf; 353 }; 354 /* ARGSUSED */ 355 fstatfs(p, uap, retval) 356 struct proc *p; 357 register struct fstatfs_args *uap; 358 int *retval; 359 { 360 struct file *fp; 361 struct mount *mp; 362 register struct statfs *sp; 363 int error; 364 365 if (error = getvnode(p->p_fd, uap->fd, &fp)) 366 return (error); 367 mp = ((struct vnode *)fp->f_data)->v_mount; 368 sp = &mp->mnt_stat; 369 if (error = VFS_STATFS(mp, sp, p)) 370 return (error); 371 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 372 return (copyout((caddr_t)sp, (caddr_t)uap->buf, sizeof(*sp))); 373 } 374 375 /* 376 * Get statistics on all filesystems. 377 */ 378 struct getfsstat_args { 379 struct statfs *buf; 380 long bufsize; 381 int flags; 382 }; 383 getfsstat(p, uap, retval) 384 struct proc *p; 385 register struct getfsstat_args *uap; 386 int *retval; 387 { 388 register struct mount *mp; 389 register struct statfs *sp; 390 caddr_t sfsp; 391 long count, maxcount, error; 392 393 maxcount = uap->bufsize / sizeof(struct statfs); 394 sfsp = (caddr_t)uap->buf; 395 mp = rootfs; 396 count = 0; 397 do { 398 if (sfsp && count < maxcount && 399 ((mp->mnt_flag & MNT_MLOCK) == 0)) { 400 sp = &mp->mnt_stat; 401 /* 402 * If MNT_NOWAIT is specified, do not refresh the 403 * fsstat cache. MNT_WAIT overrides MNT_NOWAIT. 404 */ 405 if (((uap->flags & MNT_NOWAIT) == 0 || 406 (uap->flags & MNT_WAIT)) && 407 (error = VFS_STATFS(mp, sp, p))) { 408 mp = mp->mnt_prev; 409 continue; 410 } 411 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 412 if (error = copyout((caddr_t)sp, sfsp, sizeof(*sp))) 413 return (error); 414 sfsp += sizeof(*sp); 415 } 416 count++; 417 mp = mp->mnt_prev; 418 } while (mp != rootfs); 419 if (sfsp && count > maxcount) 420 *retval = maxcount; 421 else 422 *retval = count; 423 return (0); 424 } 425 426 /* 427 * Change current working directory to a given file descriptor. 428 */ 429 struct fchdir_args { 430 int fd; 431 }; 432 /* ARGSUSED */ 433 fchdir(p, uap, retval) 434 struct proc *p; 435 struct fchdir_args *uap; 436 int *retval; 437 { 438 register struct filedesc *fdp = p->p_fd; 439 register struct vnode *vp; 440 struct file *fp; 441 int error; 442 443 if (error = getvnode(fdp, uap->fd, &fp)) 444 return (error); 445 vp = (struct vnode *)fp->f_data; 446 VOP_LOCK(vp); 447 if (vp->v_type != VDIR) 448 error = ENOTDIR; 449 else 450 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 451 VOP_UNLOCK(vp); 452 if (error) 453 return (error); 454 VREF(vp); 455 vrele(fdp->fd_cdir); 456 fdp->fd_cdir = vp; 457 return (0); 458 } 459 460 /* 461 * Change current working directory (``.''). 462 */ 463 struct chdir_args { 464 char *fname; 465 }; 466 /* ARGSUSED */ 467 chdir(p, uap, retval) 468 struct proc *p; 469 struct chdir_args *uap; 470 int *retval; 471 { 472 register struct filedesc *fdp = p->p_fd; 473 int error; 474 struct nameidata nd; 475 476 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 477 if (error = chdirec(&nd, p)) 478 return (error); 479 vrele(fdp->fd_cdir); 480 fdp->fd_cdir = nd.ni_vp; 481 return (0); 482 } 483 484 /* 485 * Change notion of root (``/'') directory. 486 */ 487 struct chroot_args { 488 char *fname; 489 }; 490 /* ARGSUSED */ 491 chroot(p, uap, retval) 492 struct proc *p; 493 struct chroot_args *uap; 494 int *retval; 495 { 496 register struct filedesc *fdp = p->p_fd; 497 int error; 498 struct nameidata nd; 499 500 if (error = suser(p->p_ucred, &p->p_acflag)) 501 return (error); 502 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 503 if (error = chdirec(&nd, p)) 504 return (error); 505 if (fdp->fd_rdir != NULL) 506 vrele(fdp->fd_rdir); 507 fdp->fd_rdir = nd.ni_vp; 508 return (0); 509 } 510 511 /* 512 * Common routine for chroot and chdir. 513 */ 514 chdirec(ndp, p) 515 register struct nameidata *ndp; 516 struct proc *p; 517 { 518 struct vnode *vp; 519 int error; 520 521 if (error = namei(ndp)) 522 return (error); 523 vp = ndp->ni_vp; 524 if (vp->v_type != VDIR) 525 error = ENOTDIR; 526 else 527 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 528 VOP_UNLOCK(vp); 529 if (error) 530 vrele(vp); 531 return (error); 532 } 533 534 /* 535 * Open system call. 536 * Check permissions, allocate an open file structure, 537 * and call the device open routine if any. 538 */ 539 struct open_args { 540 char *fname; 541 int mode; 542 int crtmode; 543 }; 544 open(p, uap, retval) 545 struct proc *p; 546 register struct open_args *uap; 547 int *retval; 548 { 549 register struct filedesc *fdp = p->p_fd; 550 register struct file *fp; 551 register struct vnode *vp; 552 int fmode, cmode; 553 struct file *nfp; 554 int type, indx, error; 555 struct flock lf; 556 struct nameidata nd; 557 extern struct fileops vnops; 558 559 if (error = falloc(p, &nfp, &indx)) 560 return (error); 561 fp = nfp; 562 fmode = FFLAGS(uap->mode); 563 cmode = ((uap->crtmode &~ fdp->fd_cmask) & 07777) &~ S_ISVTX; 564 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p); 565 p->p_dupfd = -indx - 1; /* XXX check for fdopen */ 566 if (error = vn_open(&nd, fmode, cmode)) { 567 ffree(fp); 568 if ((error == ENODEV || error == ENXIO) && 569 p->p_dupfd >= 0 && /* XXX from fdopen */ 570 (error = dupfdopen(fdp, indx, p->p_dupfd, 571 fmode, error)) == 0) { 572 *retval = indx; 573 return (0); 574 } 575 if (error == ERESTART) 576 error = EINTR; 577 fdp->fd_ofiles[indx] = NULL; 578 return (error); 579 } 580 p->p_dupfd = 0; 581 vp = nd.ni_vp; 582 fp->f_flag = fmode & FMASK; 583 fp->f_type = DTYPE_VNODE; 584 fp->f_ops = &vnops; 585 fp->f_data = (caddr_t)vp; 586 if (fmode & (O_EXLOCK | O_SHLOCK)) { 587 lf.l_whence = SEEK_SET; 588 lf.l_start = 0; 589 lf.l_len = 0; 590 if (fmode & O_EXLOCK) 591 lf.l_type = F_WRLCK; 592 else 593 lf.l_type = F_RDLCK; 594 type = F_FLOCK; 595 if ((fmode & FNONBLOCK) == 0) 596 type |= F_WAIT; 597 if (error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) { 598 VOP_UNLOCK(vp); 599 (void) vn_close(vp, fp->f_flag, fp->f_cred, p); 600 ffree(fp); 601 fdp->fd_ofiles[indx] = NULL; 602 return (error); 603 } 604 fp->f_flag |= FHASLOCK; 605 } 606 VOP_UNLOCK(vp); 607 *retval = indx; 608 return (0); 609 } 610 611 #ifdef COMPAT_43 612 /* 613 * Creat system call. 614 */ 615 struct ocreat_args { 616 char *fname; 617 int fmode; 618 }; 619 ocreat(p, uap, retval) 620 struct proc *p; 621 register struct ocreat_args *uap; 622 int *retval; 623 { 624 struct open_args openuap; 625 626 openuap.fname = uap->fname; 627 openuap.crtmode = uap->fmode; 628 openuap.mode = O_WRONLY | O_CREAT | O_TRUNC; 629 return (open(p, &openuap, retval)); 630 } 631 #endif /* COMPAT_43 */ 632 633 /* 634 * Mknod system call. 635 */ 636 struct mknod_args { 637 char *fname; 638 int fmode; 639 int dev; 640 }; 641 /* ARGSUSED */ 642 mknod(p, uap, retval) 643 struct proc *p; 644 register struct mknod_args *uap; 645 int *retval; 646 { 647 register struct vnode *vp; 648 struct vattr vattr; 649 int error; 650 struct nameidata nd; 651 652 if (error = suser(p->p_ucred, &p->p_acflag)) 653 return (error); 654 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->fname, p); 655 if (error = namei(&nd)) 656 return (error); 657 vp = nd.ni_vp; 658 if (vp != NULL) { 659 error = EEXIST; 660 goto out; 661 } 662 VATTR_NULL(&vattr); 663 switch (uap->fmode & S_IFMT) { 664 665 case S_IFMT: /* used by badsect to flag bad sectors */ 666 vattr.va_type = VBAD; 667 break; 668 case S_IFCHR: 669 vattr.va_type = VCHR; 670 break; 671 case S_IFBLK: 672 vattr.va_type = VBLK; 673 break; 674 default: 675 error = EINVAL; 676 goto out; 677 } 678 vattr.va_mode = (uap->fmode & 07777) &~ p->p_fd->fd_cmask; 679 vattr.va_rdev = uap->dev; 680 out: 681 if (!error) { 682 LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 683 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 684 } else { 685 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 686 if (nd.ni_dvp == vp) 687 vrele(nd.ni_dvp); 688 else 689 vput(nd.ni_dvp); 690 if (vp) 691 vrele(vp); 692 } 693 return (error); 694 } 695 696 /* 697 * Mkfifo system call. 698 */ 699 struct mkfifo_args { 700 char *fname; 701 int fmode; 702 }; 703 /* ARGSUSED */ 704 mkfifo(p, uap, retval) 705 struct proc *p; 706 register struct mkfifo_args *uap; 707 int *retval; 708 { 709 struct vattr vattr; 710 int error; 711 struct nameidata nd; 712 713 #ifndef FIFO 714 return (EOPNOTSUPP); 715 #else 716 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->fname, p); 717 if (error = namei(&nd)) 718 return (error); 719 if (nd.ni_vp != NULL) { 720 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 721 if (nd.ni_dvp == nd.ni_vp) 722 vrele(nd.ni_dvp); 723 else 724 vput(nd.ni_dvp); 725 vrele(nd.ni_vp); 726 return (EEXIST); 727 } 728 VATTR_NULL(&vattr); 729 vattr.va_type = VFIFO; 730 vattr.va_mode = (uap->fmode & 07777) &~ p->p_fd->fd_cmask; 731 LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 732 return (VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr)); 733 #endif /* FIFO */ 734 } 735 736 /* 737 * Link system call. 738 */ 739 struct link_args { 740 char *target; 741 char *linkname; 742 }; 743 /* ARGSUSED */ 744 link(p, uap, retval) 745 struct proc *p; 746 register struct link_args *uap; 747 int *retval; 748 { 749 register struct vnode *vp, *xp; 750 int error; 751 struct nameidata nd; 752 753 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->target, p); 754 if (error = namei(&nd)) 755 return (error); 756 vp = nd.ni_vp; 757 if (vp->v_type == VDIR && 758 (error = suser(p->p_ucred, &p->p_acflag))) 759 goto out1; 760 nd.ni_cnd.cn_nameiop = CREATE; 761 nd.ni_cnd.cn_flags = LOCKPARENT; 762 nd.ni_dirp = (caddr_t)uap->linkname; 763 if (error = namei(&nd)) 764 goto out1; 765 xp = nd.ni_vp; 766 if (xp != NULL) { 767 error = EEXIST; 768 goto out; 769 } 770 xp = nd.ni_dvp; 771 out: 772 if (!error) { 773 LEASE_CHECK(xp, p, p->p_ucred, LEASE_WRITE); 774 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 775 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); 776 } else { 777 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 778 if (nd.ni_dvp == nd.ni_vp) 779 vrele(nd.ni_dvp); 780 else 781 vput(nd.ni_dvp); 782 if (nd.ni_vp) 783 vrele(nd.ni_vp); 784 } 785 out1: 786 vrele(vp); 787 return (error); 788 } 789 790 /* 791 * Make a symbolic link. 792 */ 793 struct symlink_args { 794 char *target; 795 char *linkname; 796 }; 797 /* ARGSUSED */ 798 symlink(p, uap, retval) 799 struct proc *p; 800 register struct symlink_args *uap; 801 int *retval; 802 { 803 struct vattr vattr; 804 char *target; 805 int error; 806 struct nameidata nd; 807 808 MALLOC(target, char *, MAXPATHLEN, M_NAMEI, M_WAITOK); 809 if (error = copyinstr(uap->target, target, MAXPATHLEN, (u_int *)0)) 810 goto out; 811 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->linkname, p); 812 if (error = namei(&nd)) 813 goto out; 814 if (nd.ni_vp) { 815 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 816 if (nd.ni_dvp == nd.ni_vp) 817 vrele(nd.ni_dvp); 818 else 819 vput(nd.ni_dvp); 820 vrele(nd.ni_vp); 821 error = EEXIST; 822 goto out; 823 } 824 VATTR_NULL(&vattr); 825 vattr.va_mode = 0777 &~ p->p_fd->fd_cmask; 826 LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 827 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, target); 828 out: 829 FREE(target, M_NAMEI); 830 return (error); 831 } 832 833 /* 834 * Delete a name from the filesystem. 835 */ 836 struct unlink_args { 837 char *name; 838 }; 839 /* ARGSUSED */ 840 unlink(p, uap, retval) 841 struct proc *p; 842 struct unlink_args *uap; 843 int *retval; 844 { 845 register struct vnode *vp; 846 int error; 847 struct nameidata nd; 848 849 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE, uap->name, p); 850 if (error = namei(&nd)) 851 return (error); 852 vp = nd.ni_vp; 853 if (vp->v_type == VDIR && 854 (error = suser(p->p_ucred, &p->p_acflag))) 855 goto out; 856 /* 857 * The root of a mounted filesystem cannot be deleted. 858 */ 859 if (vp->v_flag & VROOT) { 860 error = EBUSY; 861 goto out; 862 } 863 (void) vnode_pager_uncache(vp); 864 out: 865 if (!error) { 866 LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 867 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 868 error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 869 } else { 870 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 871 if (nd.ni_dvp == vp) 872 vrele(nd.ni_dvp); 873 else 874 vput(nd.ni_dvp); 875 vput(vp); 876 } 877 return (error); 878 } 879 880 struct __lseek_args { 881 int fdes; 882 int pad; 883 off_t off; 884 int sbase; 885 }; 886 887 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 888 /* 889 * Seek system call. 890 */ 891 struct lseek_args { 892 int fdes; 893 long off; 894 int sbase; 895 }; 896 lseek(p, uap, retval) 897 struct proc *p; 898 register struct lseek_args *uap; 899 int *retval; 900 { 901 struct __lseek_args nuap; 902 off_t qret; 903 int error; 904 905 nuap.fdes = uap->fdes; 906 nuap.off = uap->off; 907 nuap.sbase = uap->sbase; 908 error = __lseek(p, &nuap, &qret); 909 *(long *)retval = qret; 910 return (error); 911 } 912 #endif /* COMPAT_43 || COMPAT_SUNOS */ 913 914 /* 915 * Seek system call. 916 */ 917 __lseek(p, uap, retval) 918 struct proc *p; 919 register struct __lseek_args *uap; 920 int *retval; 921 { 922 struct ucred *cred = p->p_ucred; 923 register struct filedesc *fdp = p->p_fd; 924 register struct file *fp; 925 struct vattr vattr; 926 int error; 927 928 if ((unsigned)uap->fdes >= fdp->fd_nfiles || 929 (fp = fdp->fd_ofiles[uap->fdes]) == NULL) 930 return (EBADF); 931 if (fp->f_type != DTYPE_VNODE) 932 return (ESPIPE); 933 switch (uap->sbase) { 934 935 case L_INCR: 936 fp->f_offset += uap->off; 937 break; 938 939 case L_XTND: 940 if (error = VOP_GETATTR((struct vnode *)fp->f_data, 941 &vattr, cred, p)) 942 return (error); 943 fp->f_offset = uap->off + vattr.va_size; 944 break; 945 946 case L_SET: 947 fp->f_offset = uap->off; 948 break; 949 950 default: 951 return (EINVAL); 952 } 953 *(off_t *)retval = fp->f_offset; 954 return (0); 955 } 956 957 /* 958 * Check access permissions. 959 */ 960 struct saccess_args { 961 char *fname; 962 int fmode; 963 }; 964 /* ARGSUSED */ 965 saccess(p, uap, retval) 966 struct proc *p; 967 register struct saccess_args *uap; 968 int *retval; 969 { 970 register struct ucred *cred = p->p_ucred; 971 register struct vnode *vp; 972 int error, mode, svuid, svgid; 973 struct nameidata nd; 974 975 svuid = cred->cr_uid; 976 svgid = cred->cr_groups[0]; 977 cred->cr_uid = p->p_cred->p_ruid; 978 cred->cr_groups[0] = p->p_cred->p_rgid; 979 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 980 if (error = namei(&nd)) 981 goto out1; 982 vp = nd.ni_vp; 983 /* 984 * fmode == 0 means only check for exist 985 */ 986 if (uap->fmode) { 987 mode = 0; 988 if (uap->fmode & R_OK) 989 mode |= VREAD; 990 if (uap->fmode & W_OK) 991 mode |= VWRITE; 992 if (uap->fmode & X_OK) 993 mode |= VEXEC; 994 if ((mode & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) 995 error = VOP_ACCESS(vp, mode, cred, p); 996 } 997 vput(vp); 998 out1: 999 cred->cr_uid = svuid; 1000 cred->cr_groups[0] = svgid; 1001 return (error); 1002 } 1003 1004 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1005 /* 1006 * Stat system call. 1007 * This version follows links. 1008 */ 1009 struct ostat_args { 1010 char *fname; 1011 struct ostat *ub; 1012 }; 1013 /* ARGSUSED */ 1014 ostat(p, uap, retval) 1015 struct proc *p; 1016 register struct ostat_args *uap; 1017 int *retval; 1018 { 1019 struct stat sb; 1020 struct ostat osb; 1021 int error; 1022 struct nameidata nd; 1023 1024 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1025 if (error = namei(&nd)) 1026 return (error); 1027 error = vn_stat(nd.ni_vp, &sb, p); 1028 vput(nd.ni_vp); 1029 if (error) 1030 return (error); 1031 cvtstat(&sb, &osb); 1032 error = copyout((caddr_t)&osb, (caddr_t)uap->ub, sizeof (osb)); 1033 return (error); 1034 } 1035 1036 /* 1037 * Lstat system call. 1038 * This version does not follow links. 1039 */ 1040 struct olstat_args { 1041 char *fname; 1042 struct ostat *ub; 1043 }; 1044 /* ARGSUSED */ 1045 olstat(p, uap, retval) 1046 struct proc *p; 1047 register struct olstat_args *uap; 1048 int *retval; 1049 { 1050 struct stat sb; 1051 struct ostat osb; 1052 int error; 1053 struct nameidata nd; 1054 1055 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1056 if (error = namei(&nd)) 1057 return (error); 1058 error = vn_stat(nd.ni_vp, &sb, p); 1059 vput(nd.ni_vp); 1060 if (error) 1061 return (error); 1062 cvtstat(&sb, &osb); 1063 error = copyout((caddr_t)&osb, (caddr_t)uap->ub, sizeof (osb)); 1064 return (error); 1065 } 1066 1067 /* 1068 * convert from an old to a new stat structure. 1069 */ 1070 cvtstat(st, ost) 1071 struct stat *st; 1072 struct ostat *ost; 1073 { 1074 1075 ost->st_dev = st->st_dev; 1076 ost->st_ino = st->st_ino; 1077 ost->st_mode = st->st_mode; 1078 ost->st_nlink = st->st_nlink; 1079 ost->st_uid = st->st_uid; 1080 ost->st_gid = st->st_gid; 1081 ost->st_rdev = st->st_rdev; 1082 if (st->st_size < (quad_t)1 << 32) 1083 ost->st_size = st->st_size; 1084 else 1085 ost->st_size = -2; 1086 ost->st_atime = st->st_atime; 1087 ost->st_mtime = st->st_mtime; 1088 ost->st_ctime = st->st_ctime; 1089 ost->st_blksize = st->st_blksize; 1090 ost->st_blocks = st->st_blocks; 1091 ost->st_flags = st->st_flags; 1092 ost->st_gen = st->st_gen; 1093 } 1094 #endif /* COMPAT_43 || COMPAT_SUNOS */ 1095 1096 /* 1097 * Stat system call. 1098 * This version follows links. 1099 */ 1100 struct stat_args { 1101 char *fname; 1102 struct stat *ub; 1103 }; 1104 /* ARGSUSED */ 1105 stat(p, uap, retval) 1106 struct proc *p; 1107 register struct stat_args *uap; 1108 int *retval; 1109 { 1110 struct stat sb; 1111 int error; 1112 struct nameidata nd; 1113 1114 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1115 if (error = namei(&nd)) 1116 return (error); 1117 error = vn_stat(nd.ni_vp, &sb, p); 1118 vput(nd.ni_vp); 1119 if (error) 1120 return (error); 1121 error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb)); 1122 return (error); 1123 } 1124 1125 /* 1126 * Lstat system call. 1127 * This version does not follow links. 1128 */ 1129 struct lstat_args { 1130 char *fname; 1131 struct stat *ub; 1132 }; 1133 /* ARGSUSED */ 1134 lstat(p, uap, retval) 1135 struct proc *p; 1136 register struct lstat_args *uap; 1137 int *retval; 1138 { 1139 struct stat sb; 1140 int error; 1141 struct nameidata nd; 1142 1143 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1144 if (error = namei(&nd)) 1145 return (error); 1146 error = vn_stat(nd.ni_vp, &sb, p); 1147 vput(nd.ni_vp); 1148 if (error) 1149 return (error); 1150 error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb)); 1151 return (error); 1152 } 1153 1154 /* 1155 * Return target name of a symbolic link. 1156 */ 1157 struct readlink_args { 1158 char *name; 1159 char *buf; 1160 int count; 1161 }; 1162 /* ARGSUSED */ 1163 readlink(p, uap, retval) 1164 struct proc *p; 1165 register struct readlink_args *uap; 1166 int *retval; 1167 { 1168 register struct vnode *vp; 1169 struct iovec aiov; 1170 struct uio auio; 1171 int error; 1172 struct nameidata nd; 1173 1174 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, uap->name, p); 1175 if (error = namei(&nd)) 1176 return (error); 1177 vp = nd.ni_vp; 1178 if (vp->v_type != VLNK) { 1179 error = EINVAL; 1180 goto out; 1181 } 1182 aiov.iov_base = uap->buf; 1183 aiov.iov_len = uap->count; 1184 auio.uio_iov = &aiov; 1185 auio.uio_iovcnt = 1; 1186 auio.uio_offset = 0; 1187 auio.uio_rw = UIO_READ; 1188 auio.uio_segflg = UIO_USERSPACE; 1189 auio.uio_procp = p; 1190 auio.uio_resid = uap->count; 1191 error = VOP_READLINK(vp, &auio, p->p_ucred); 1192 out: 1193 vput(vp); 1194 *retval = uap->count - auio.uio_resid; 1195 return (error); 1196 } 1197 1198 /* 1199 * Change flags of a file given path name. 1200 */ 1201 struct chflags_args { 1202 char *fname; 1203 int flags; 1204 }; 1205 /* ARGSUSED */ 1206 chflags(p, uap, retval) 1207 struct proc *p; 1208 register struct chflags_args *uap; 1209 int *retval; 1210 { 1211 register struct vnode *vp; 1212 struct vattr vattr; 1213 int error; 1214 struct nameidata nd; 1215 1216 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1217 if (error = namei(&nd)) 1218 return (error); 1219 vp = nd.ni_vp; 1220 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1221 error = EROFS; 1222 goto out; 1223 } 1224 VATTR_NULL(&vattr); 1225 vattr.va_flags = uap->flags; 1226 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1227 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1228 out: 1229 vput(vp); 1230 return (error); 1231 } 1232 1233 /* 1234 * Change flags of a file given a file descriptor. 1235 */ 1236 struct fchflags_args { 1237 int fd; 1238 int flags; 1239 }; 1240 /* ARGSUSED */ 1241 fchflags(p, uap, retval) 1242 struct proc *p; 1243 register struct fchflags_args *uap; 1244 int *retval; 1245 { 1246 struct vattr vattr; 1247 struct vnode *vp; 1248 struct file *fp; 1249 int error; 1250 1251 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1252 return (error); 1253 vp = (struct vnode *)fp->f_data; 1254 VOP_LOCK(vp); 1255 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1256 error = EROFS; 1257 goto out; 1258 } 1259 VATTR_NULL(&vattr); 1260 vattr.va_flags = uap->flags; 1261 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1262 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1263 out: 1264 VOP_UNLOCK(vp); 1265 return (error); 1266 } 1267 1268 /* 1269 * Change mode of a file given path name. 1270 */ 1271 struct chmod_args { 1272 char *fname; 1273 int fmode; 1274 }; 1275 /* ARGSUSED */ 1276 chmod(p, uap, retval) 1277 struct proc *p; 1278 register struct chmod_args *uap; 1279 int *retval; 1280 { 1281 register struct vnode *vp; 1282 struct vattr vattr; 1283 int error; 1284 struct nameidata nd; 1285 1286 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1287 if (error = namei(&nd)) 1288 return (error); 1289 vp = nd.ni_vp; 1290 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1291 error = EROFS; 1292 goto out; 1293 } 1294 VATTR_NULL(&vattr); 1295 vattr.va_mode = uap->fmode & 07777; 1296 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1297 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1298 out: 1299 vput(vp); 1300 return (error); 1301 } 1302 1303 /* 1304 * Change mode of a file given a file descriptor. 1305 */ 1306 struct fchmod_args { 1307 int fd; 1308 int fmode; 1309 }; 1310 /* ARGSUSED */ 1311 fchmod(p, uap, retval) 1312 struct proc *p; 1313 register struct fchmod_args *uap; 1314 int *retval; 1315 { 1316 struct vattr vattr; 1317 struct vnode *vp; 1318 struct file *fp; 1319 int error; 1320 1321 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1322 return (error); 1323 vp = (struct vnode *)fp->f_data; 1324 VOP_LOCK(vp); 1325 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1326 error = EROFS; 1327 goto out; 1328 } 1329 VATTR_NULL(&vattr); 1330 vattr.va_mode = uap->fmode & 07777; 1331 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1332 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1333 out: 1334 VOP_UNLOCK(vp); 1335 return (error); 1336 } 1337 1338 /* 1339 * Set ownership given a path name. 1340 */ 1341 struct chown_args { 1342 char *fname; 1343 int uid; 1344 int gid; 1345 }; 1346 /* ARGSUSED */ 1347 chown(p, uap, retval) 1348 struct proc *p; 1349 register struct chown_args *uap; 1350 int *retval; 1351 { 1352 register struct vnode *vp; 1353 struct vattr vattr; 1354 int error; 1355 struct nameidata nd; 1356 1357 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1358 if (error = namei(&nd)) 1359 return (error); 1360 vp = nd.ni_vp; 1361 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1362 error = EROFS; 1363 goto out; 1364 } 1365 VATTR_NULL(&vattr); 1366 vattr.va_uid = uap->uid; 1367 vattr.va_gid = uap->gid; 1368 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1369 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1370 out: 1371 vput(vp); 1372 return (error); 1373 } 1374 1375 /* 1376 * Set ownership given a file descriptor. 1377 */ 1378 struct fchown_args { 1379 int fd; 1380 int uid; 1381 int gid; 1382 }; 1383 /* ARGSUSED */ 1384 fchown(p, uap, retval) 1385 struct proc *p; 1386 register struct fchown_args *uap; 1387 int *retval; 1388 { 1389 struct vattr vattr; 1390 struct vnode *vp; 1391 struct file *fp; 1392 int error; 1393 1394 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1395 return (error); 1396 vp = (struct vnode *)fp->f_data; 1397 VOP_LOCK(vp); 1398 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1399 error = EROFS; 1400 goto out; 1401 } 1402 VATTR_NULL(&vattr); 1403 vattr.va_uid = uap->uid; 1404 vattr.va_gid = uap->gid; 1405 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1406 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1407 out: 1408 VOP_UNLOCK(vp); 1409 return (error); 1410 } 1411 1412 /* 1413 * Set the access and modification times of a file. 1414 */ 1415 struct utimes_args { 1416 char *fname; 1417 struct timeval *tptr; 1418 }; 1419 /* ARGSUSED */ 1420 utimes(p, uap, retval) 1421 struct proc *p; 1422 register struct utimes_args *uap; 1423 int *retval; 1424 { 1425 register struct vnode *vp; 1426 struct timeval tv[2]; 1427 struct vattr vattr; 1428 int error; 1429 struct nameidata nd; 1430 1431 if (error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv))) 1432 return (error); 1433 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1434 if (error = namei(&nd)) 1435 return (error); 1436 vp = nd.ni_vp; 1437 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1438 error = EROFS; 1439 goto out; 1440 } 1441 VATTR_NULL(&vattr); 1442 vattr.va_atime.ts_sec = tv[0].tv_sec; 1443 vattr.va_atime.ts_nsec = tv[0].tv_usec * 1000; 1444 vattr.va_mtime.ts_sec = tv[1].tv_sec; 1445 vattr.va_mtime.ts_nsec = tv[1].tv_usec * 1000; 1446 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1447 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1448 out: 1449 vput(vp); 1450 return (error); 1451 } 1452 1453 struct __truncate_args { 1454 char *fname; 1455 int pad; 1456 off_t length; 1457 }; 1458 1459 /* 1460 * Truncate a file given its path name. 1461 */ 1462 /* ARGSUSED */ 1463 __truncate(p, uap, retval) 1464 struct proc *p; 1465 register struct __truncate_args *uap; 1466 int *retval; 1467 { 1468 register struct vnode *vp; 1469 struct vattr vattr; 1470 int error; 1471 struct nameidata nd; 1472 1473 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1474 if (error = namei(&nd)) 1475 return (error); 1476 vp = nd.ni_vp; 1477 if (vp->v_type == VDIR) { 1478 error = EISDIR; 1479 goto out; 1480 } 1481 if ((error = vn_writechk(vp)) || 1482 (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p))) 1483 goto out; 1484 VATTR_NULL(&vattr); 1485 vattr.va_size = uap->length; 1486 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1487 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1488 out: 1489 vput(vp); 1490 return (error); 1491 } 1492 1493 struct __ftruncate_args { 1494 int fd; 1495 int pad; 1496 off_t length; 1497 }; 1498 1499 /* 1500 * Truncate a file given a file descriptor. 1501 */ 1502 /* ARGSUSED */ 1503 __ftruncate(p, uap, retval) 1504 struct proc *p; 1505 register struct __ftruncate_args *uap; 1506 int *retval; 1507 { 1508 struct vattr vattr; 1509 struct vnode *vp; 1510 struct file *fp; 1511 int error; 1512 1513 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1514 return (error); 1515 if ((fp->f_flag & FWRITE) == 0) 1516 return (EINVAL); 1517 vp = (struct vnode *)fp->f_data; 1518 VOP_LOCK(vp); 1519 if (vp->v_type == VDIR) { 1520 error = EISDIR; 1521 goto out; 1522 } 1523 if (error = vn_writechk(vp)) 1524 goto out; 1525 VATTR_NULL(&vattr); 1526 vattr.va_size = uap->length; 1527 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1528 error = VOP_SETATTR(vp, &vattr, fp->f_cred, p); 1529 out: 1530 VOP_UNLOCK(vp); 1531 return (error); 1532 } 1533 1534 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1535 /* 1536 * Truncate a file given its path name. 1537 */ 1538 struct truncate_args { 1539 char *fname; 1540 long length; 1541 }; 1542 /* ARGSUSED */ 1543 truncate(p, uap, retval) 1544 struct proc *p; 1545 register struct truncate_args *uap; 1546 int *retval; 1547 { 1548 struct __truncate_args nuap; 1549 1550 nuap.fname = uap->fname; 1551 nuap.length = uap->length; 1552 return (__truncate(p, &nuap, retval)); 1553 } 1554 1555 /* 1556 * Truncate a file given a file descriptor. 1557 */ 1558 struct ftruncate_args { 1559 int fd; 1560 long length; 1561 }; 1562 /* ARGSUSED */ 1563 ftruncate(p, uap, retval) 1564 struct proc *p; 1565 register struct ftruncate_args *uap; 1566 int *retval; 1567 { 1568 struct __ftruncate_args nuap; 1569 1570 nuap.fd = uap->fd; 1571 nuap.length = uap->length; 1572 return (__ftruncate(p, &nuap, retval)); 1573 } 1574 #endif /* COMPAT_43 || COMPAT_SUNOS */ 1575 1576 /* 1577 * Synch an open file. 1578 */ 1579 struct fsync_args { 1580 int fd; 1581 }; 1582 /* ARGSUSED */ 1583 fsync(p, uap, retval) 1584 struct proc *p; 1585 struct fsync_args *uap; 1586 int *retval; 1587 { 1588 register struct vnode *vp; 1589 struct file *fp; 1590 int error; 1591 1592 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1593 return (error); 1594 vp = (struct vnode *)fp->f_data; 1595 VOP_LOCK(vp); 1596 error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p); 1597 VOP_UNLOCK(vp); 1598 return (error); 1599 } 1600 1601 /* 1602 * Rename system call. 1603 * 1604 * Source and destination must either both be directories, or both 1605 * not be directories. If target is a directory, it must be empty. 1606 */ 1607 struct rename_args { 1608 char *from; 1609 char *to; 1610 }; 1611 /* ARGSUSED */ 1612 rename(p, uap, retval) 1613 struct proc *p; 1614 register struct rename_args *uap; 1615 int *retval; 1616 { 1617 register struct vnode *tvp, *fvp, *tdvp; 1618 struct nameidata fromnd, tond; 1619 int error; 1620 1621 NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE, 1622 uap->from, p); 1623 if (error = namei(&fromnd)) 1624 return (error); 1625 fvp = fromnd.ni_vp; 1626 NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART, 1627 UIO_USERSPACE, uap->to, p); 1628 if (error = namei(&tond)) { 1629 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd); 1630 vrele(fromnd.ni_dvp); 1631 vrele(fvp); 1632 goto out1; 1633 } 1634 tdvp = tond.ni_dvp; 1635 tvp = tond.ni_vp; 1636 if (tvp != NULL) { 1637 if (fvp->v_type == VDIR && tvp->v_type != VDIR) { 1638 error = ENOTDIR; 1639 goto out; 1640 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { 1641 error = EISDIR; 1642 goto out; 1643 } 1644 } 1645 if (fvp == tdvp) 1646 error = EINVAL; 1647 /* 1648 * If source is the same as the destination (that is the 1649 * same inode number with the same name in the same directory), 1650 * then there is nothing to do. 1651 */ 1652 if (fvp == tvp && fromnd.ni_dvp == tdvp && 1653 fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen && 1654 !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr, 1655 fromnd.ni_cnd.cn_namelen)) 1656 error = -1; 1657 out: 1658 if (!error) { 1659 LEASE_CHECK(tdvp, p, p->p_ucred, LEASE_WRITE); 1660 if (fromnd.ni_dvp != tdvp) 1661 LEASE_CHECK(fromnd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1662 if (tvp) 1663 LEASE_CHECK(tvp, p, p->p_ucred, LEASE_WRITE); 1664 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, 1665 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); 1666 } else { 1667 VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd); 1668 if (tdvp == tvp) 1669 vrele(tdvp); 1670 else 1671 vput(tdvp); 1672 if (tvp) 1673 vput(tvp); 1674 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd); 1675 vrele(fromnd.ni_dvp); 1676 vrele(fvp); 1677 } 1678 vrele(tond.ni_startdir); 1679 FREE(tond.ni_cnd.cn_pnbuf, M_NAMEI); 1680 out1: 1681 vrele(fromnd.ni_startdir); 1682 FREE(fromnd.ni_cnd.cn_pnbuf, M_NAMEI); 1683 if (error == -1) 1684 return (0); 1685 return (error); 1686 } 1687 1688 /* 1689 * Mkdir system call. 1690 */ 1691 struct mkdir_args { 1692 char *name; 1693 int dmode; 1694 }; 1695 /* ARGSUSED */ 1696 mkdir(p, uap, retval) 1697 struct proc *p; 1698 register struct mkdir_args *uap; 1699 int *retval; 1700 { 1701 register struct vnode *vp; 1702 struct vattr vattr; 1703 int error; 1704 struct nameidata nd; 1705 1706 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->name, p); 1707 if (error = namei(&nd)) 1708 return (error); 1709 vp = nd.ni_vp; 1710 if (vp != NULL) { 1711 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1712 if (nd.ni_dvp == vp) 1713 vrele(nd.ni_dvp); 1714 else 1715 vput(nd.ni_dvp); 1716 vrele(vp); 1717 return (EEXIST); 1718 } 1719 VATTR_NULL(&vattr); 1720 vattr.va_type = VDIR; 1721 vattr.va_mode = (uap->dmode & 0777) &~ p->p_fd->fd_cmask; 1722 LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1723 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 1724 if (!error) 1725 vput(nd.ni_vp); 1726 return (error); 1727 } 1728 1729 /* 1730 * Rmdir system call. 1731 */ 1732 struct rmdir_args { 1733 char *name; 1734 }; 1735 /* ARGSUSED */ 1736 rmdir(p, uap, retval) 1737 struct proc *p; 1738 struct rmdir_args *uap; 1739 int *retval; 1740 { 1741 register struct vnode *vp; 1742 int error; 1743 struct nameidata nd; 1744 1745 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE, uap->name, p); 1746 if (error = namei(&nd)) 1747 return (error); 1748 vp = nd.ni_vp; 1749 if (vp->v_type != VDIR) { 1750 error = ENOTDIR; 1751 goto out; 1752 } 1753 /* 1754 * No rmdir "." please. 1755 */ 1756 if (nd.ni_dvp == vp) { 1757 error = EINVAL; 1758 goto out; 1759 } 1760 /* 1761 * The root of a mounted filesystem cannot be deleted. 1762 */ 1763 if (vp->v_flag & VROOT) 1764 error = EBUSY; 1765 out: 1766 if (!error) { 1767 LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1768 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1769 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 1770 } else { 1771 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1772 if (nd.ni_dvp == vp) 1773 vrele(nd.ni_dvp); 1774 else 1775 vput(nd.ni_dvp); 1776 vput(vp); 1777 } 1778 return (error); 1779 } 1780 1781 #ifdef COMPAT_43 1782 /* 1783 * Read a block of directory entries in a file system independent format. 1784 */ 1785 struct ogetdirentries_args { 1786 int fd; 1787 char *buf; 1788 unsigned count; 1789 long *basep; 1790 }; 1791 ogetdirentries(p, uap, retval) 1792 struct proc *p; 1793 register struct ogetdirentries_args *uap; 1794 int *retval; 1795 { 1796 register struct vnode *vp; 1797 struct file *fp; 1798 struct uio auio, kuio; 1799 struct iovec aiov, kiov; 1800 struct dirent *dp, *edp; 1801 caddr_t dirbuf; 1802 int error, readcnt; 1803 long loff; 1804 1805 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1806 return (error); 1807 if ((fp->f_flag & FREAD) == 0) 1808 return (EBADF); 1809 vp = (struct vnode *)fp->f_data; 1810 if (vp->v_type != VDIR) 1811 return (EINVAL); 1812 aiov.iov_base = uap->buf; 1813 aiov.iov_len = uap->count; 1814 auio.uio_iov = &aiov; 1815 auio.uio_iovcnt = 1; 1816 auio.uio_rw = UIO_READ; 1817 auio.uio_segflg = UIO_USERSPACE; 1818 auio.uio_procp = p; 1819 auio.uio_resid = uap->count; 1820 VOP_LOCK(vp); 1821 loff = auio.uio_offset = fp->f_offset; 1822 # if (BYTE_ORDER != LITTLE_ENDIAN) 1823 if (vp->v_mount->mnt_maxsymlinklen <= 0) 1824 error = VOP_READDIR(vp, &auio, fp->f_cred); 1825 else 1826 # endif 1827 { 1828 kuio = auio; 1829 kuio.uio_iov = &kiov; 1830 kuio.uio_segflg = UIO_SYSSPACE; 1831 kiov.iov_len = uap->count; 1832 MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK); 1833 kiov.iov_base = dirbuf; 1834 error = VOP_READDIR(vp, &kuio, fp->f_cred); 1835 if (error == 0) { 1836 readcnt = uap->count - kuio.uio_resid; 1837 edp = (struct dirent *)&dirbuf[readcnt]; 1838 for (dp = (struct dirent *)dirbuf; dp < edp; ) { 1839 # if (BYTE_ORDER == LITTLE_ENDIAN) 1840 /* 1841 * The expected low byte of 1842 * dp->d_namlen is our dp->d_type. 1843 * The high MBZ byte of dp->d_namlen 1844 * is our dp->d_namlen. 1845 */ 1846 dp->d_type = dp->d_namlen; 1847 dp->d_namlen = 0; 1848 # else 1849 /* 1850 * The dp->d_type is the high byte 1851 * of the expected dp->d_namlen, 1852 * so must be zero'ed. 1853 */ 1854 dp->d_type = 0; 1855 # endif 1856 if (dp->d_reclen > 0) { 1857 dp = (struct dirent *) 1858 ((char *)dp + dp->d_reclen); 1859 } else { 1860 error = EIO; 1861 break; 1862 } 1863 } 1864 if (dp >= edp) 1865 error = uiomove(dirbuf, readcnt, &auio); 1866 } 1867 FREE(dirbuf, M_TEMP); 1868 } 1869 fp->f_offset = auio.uio_offset; 1870 VOP_UNLOCK(vp); 1871 if (error) 1872 return (error); 1873 error = copyout((caddr_t)&loff, (caddr_t)uap->basep, sizeof(long)); 1874 *retval = uap->count - auio.uio_resid; 1875 return (error); 1876 } 1877 #endif 1878 1879 /* 1880 * Read a block of directory entries in a file system independent format. 1881 */ 1882 struct getdirentries_args { 1883 int fd; 1884 char *buf; 1885 unsigned count; 1886 long *basep; 1887 }; 1888 getdirentries(p, uap, retval) 1889 struct proc *p; 1890 register struct getdirentries_args *uap; 1891 int *retval; 1892 { 1893 register struct vnode *vp; 1894 struct file *fp; 1895 struct uio auio; 1896 struct iovec aiov; 1897 long loff; 1898 int error; 1899 1900 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1901 return (error); 1902 if ((fp->f_flag & FREAD) == 0) 1903 return (EBADF); 1904 vp = (struct vnode *)fp->f_data; 1905 unionread: 1906 if (vp->v_type != VDIR) 1907 return (EINVAL); 1908 aiov.iov_base = uap->buf; 1909 aiov.iov_len = uap->count; 1910 auio.uio_iov = &aiov; 1911 auio.uio_iovcnt = 1; 1912 auio.uio_rw = UIO_READ; 1913 auio.uio_segflg = UIO_USERSPACE; 1914 auio.uio_procp = p; 1915 auio.uio_resid = uap->count; 1916 VOP_LOCK(vp); 1917 loff = auio.uio_offset = fp->f_offset; 1918 error = VOP_READDIR(vp, &auio, fp->f_cred); 1919 fp->f_offset = auio.uio_offset; 1920 VOP_UNLOCK(vp); 1921 if (error) 1922 return (error); 1923 if ((uap->count == auio.uio_resid) && 1924 (vp->v_flag & VROOT) && 1925 (vp->v_mount->mnt_flag & MNT_UNION)) { 1926 struct vnode *tvp = vp; 1927 vp = vp->v_mount->mnt_vnodecovered; 1928 VREF(vp); 1929 fp->f_data = (caddr_t) vp; 1930 fp->f_offset = 0; 1931 vrele(tvp); 1932 goto unionread; 1933 } 1934 error = copyout((caddr_t)&loff, (caddr_t)uap->basep, sizeof(long)); 1935 *retval = uap->count - auio.uio_resid; 1936 return (error); 1937 } 1938 1939 /* 1940 * Set the mode mask for creation of filesystem nodes. 1941 */ 1942 struct umask_args { 1943 int mask; 1944 }; 1945 mode_t /* XXX */ 1946 umask(p, uap, retval) 1947 struct proc *p; 1948 struct umask_args *uap; 1949 int *retval; 1950 { 1951 register struct filedesc *fdp = p->p_fd; 1952 1953 *retval = fdp->fd_cmask; 1954 fdp->fd_cmask = uap->mask & 07777; 1955 return (0); 1956 } 1957 1958 /* 1959 * Void all references to file by ripping underlying filesystem 1960 * away from vnode. 1961 */ 1962 struct revoke_args { 1963 char *fname; 1964 }; 1965 /* ARGSUSED */ 1966 revoke(p, uap, retval) 1967 struct proc *p; 1968 register struct revoke_args *uap; 1969 int *retval; 1970 { 1971 register struct vnode *vp; 1972 struct vattr vattr; 1973 int error; 1974 struct nameidata nd; 1975 1976 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p); 1977 if (error = namei(&nd)) 1978 return (error); 1979 vp = nd.ni_vp; 1980 if (vp->v_type != VCHR && vp->v_type != VBLK) { 1981 error = EINVAL; 1982 goto out; 1983 } 1984 if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) 1985 goto out; 1986 if (p->p_ucred->cr_uid != vattr.va_uid && 1987 (error = suser(p->p_ucred, &p->p_acflag))) 1988 goto out; 1989 if (vp->v_usecount > 1 || (vp->v_flag & VALIASED)) 1990 vgoneall(vp); 1991 out: 1992 vrele(vp); 1993 return (error); 1994 } 1995 1996 /* 1997 * Convert a user file descriptor to a kernel file entry. 1998 */ 1999 getvnode(fdp, fdes, fpp) 2000 struct filedesc *fdp; 2001 struct file **fpp; 2002 int fdes; 2003 { 2004 struct file *fp; 2005 2006 if ((unsigned)fdes >= fdp->fd_nfiles || 2007 (fp = fdp->fd_ofiles[fdes]) == NULL) 2008 return (EBADF); 2009 if (fp->f_type != DTYPE_VNODE) 2010 return (EINVAL); 2011 *fpp = fp; 2012 return (0); 2013 } 2014