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