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