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.112 (Berkeley) 05/26/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 saccess_args { 961 char *fname; 962 int fmode; 963 }; 964 /* ARGSUSED */ 965 saccess(p, uap, retval) 966 struct proc *p; 967 register struct saccess_args *uap; 968 int *retval; 969 { 970 register struct ucred *cred = p->p_ucred; 971 register struct vnode *vp; 972 int error, mode, svuid, svgid; 973 struct nameidata nd; 974 975 svuid = cred->cr_uid; 976 svgid = cred->cr_groups[0]; 977 cred->cr_uid = p->p_cred->p_ruid; 978 cred->cr_groups[0] = p->p_cred->p_rgid; 979 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 980 if (error = namei(&nd)) 981 goto out1; 982 vp = nd.ni_vp; 983 /* 984 * fmode == 0 means only check for exist 985 */ 986 if (uap->fmode) { 987 mode = 0; 988 if (uap->fmode & R_OK) 989 mode |= VREAD; 990 if (uap->fmode & W_OK) 991 mode |= VWRITE; 992 if (uap->fmode & X_OK) 993 mode |= VEXEC; 994 if ((mode & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) 995 error = VOP_ACCESS(vp, mode, cred, p); 996 } 997 vput(vp); 998 out1: 999 cred->cr_uid = svuid; 1000 cred->cr_groups[0] = svgid; 1001 return (error); 1002 } 1003 1004 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1005 /* 1006 * Stat system call. 1007 * This version follows links. 1008 */ 1009 struct ostat_args { 1010 char *fname; 1011 struct ostat *ub; 1012 }; 1013 /* ARGSUSED */ 1014 ostat(p, uap, retval) 1015 struct proc *p; 1016 register struct ostat_args *uap; 1017 int *retval; 1018 { 1019 struct stat sb; 1020 struct ostat osb; 1021 int error; 1022 struct nameidata nd; 1023 1024 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1025 if (error = namei(&nd)) 1026 return (error); 1027 error = vn_stat(nd.ni_vp, &sb, p); 1028 vput(nd.ni_vp); 1029 if (error) 1030 return (error); 1031 cvtstat(&sb, &osb); 1032 error = copyout((caddr_t)&osb, (caddr_t)uap->ub, sizeof (osb)); 1033 return (error); 1034 } 1035 1036 /* 1037 * Lstat system call. 1038 * This version does not follow links. 1039 */ 1040 struct olstat_args { 1041 char *fname; 1042 struct ostat *ub; 1043 }; 1044 /* ARGSUSED */ 1045 olstat(p, uap, retval) 1046 struct proc *p; 1047 register struct olstat_args *uap; 1048 int *retval; 1049 { 1050 struct stat sb; 1051 struct ostat osb; 1052 int error; 1053 struct nameidata nd; 1054 1055 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1056 if (error = namei(&nd)) 1057 return (error); 1058 error = vn_stat(nd.ni_vp, &sb, p); 1059 vput(nd.ni_vp); 1060 if (error) 1061 return (error); 1062 cvtstat(&sb, &osb); 1063 error = copyout((caddr_t)&osb, (caddr_t)uap->ub, sizeof (osb)); 1064 return (error); 1065 } 1066 1067 /* 1068 * convert from an old to a new stat structure. 1069 */ 1070 cvtstat(st, ost) 1071 struct stat *st; 1072 struct ostat *ost; 1073 { 1074 1075 ost->st_dev = st->st_dev; 1076 ost->st_ino = st->st_ino; 1077 ost->st_mode = st->st_mode; 1078 ost->st_nlink = st->st_nlink; 1079 ost->st_uid = st->st_uid; 1080 ost->st_gid = st->st_gid; 1081 ost->st_rdev = st->st_rdev; 1082 if (st->st_size < (quad_t)1 << 32) 1083 ost->st_size = st->st_size; 1084 else 1085 ost->st_size = -2; 1086 ost->st_atime = st->st_atime; 1087 ost->st_mtime = st->st_mtime; 1088 ost->st_ctime = st->st_ctime; 1089 ost->st_blksize = st->st_blksize; 1090 ost->st_blocks = st->st_blocks; 1091 ost->st_flags = st->st_flags; 1092 ost->st_gen = st->st_gen; 1093 } 1094 #endif /* COMPAT_43 || COMPAT_SUNOS */ 1095 1096 /* 1097 * Stat system call. 1098 * This version follows links. 1099 */ 1100 struct stat_args { 1101 char *fname; 1102 struct stat *ub; 1103 }; 1104 /* ARGSUSED */ 1105 stat(p, uap, retval) 1106 struct proc *p; 1107 register struct stat_args *uap; 1108 int *retval; 1109 { 1110 struct stat sb; 1111 int error; 1112 struct nameidata nd; 1113 1114 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1115 if (error = namei(&nd)) 1116 return (error); 1117 error = vn_stat(nd.ni_vp, &sb, p); 1118 vput(nd.ni_vp); 1119 if (error) 1120 return (error); 1121 error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb)); 1122 return (error); 1123 } 1124 1125 /* 1126 * Lstat system call. 1127 * This version does not follow links. 1128 */ 1129 struct lstat_args { 1130 char *fname; 1131 struct stat *ub; 1132 }; 1133 /* ARGSUSED */ 1134 lstat(p, uap, retval) 1135 struct proc *p; 1136 register struct lstat_args *uap; 1137 int *retval; 1138 { 1139 int error; 1140 struct vnode *vp, *dvp; 1141 struct stat sb, sb1; 1142 struct nameidata nd; 1143 1144 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKPARENT, UIO_USERSPACE, 1145 uap->fname, p); 1146 if (error = namei(&nd)) 1147 return (error); 1148 /* 1149 * For symbolic links, always return the attributes of its 1150 * containing directory, except for mode, size, and links. 1151 */ 1152 vp = nd.ni_vp; 1153 dvp = nd.ni_dvp; 1154 if (vp->v_type != VLNK) { 1155 if (dvp == vp) 1156 vrele(dvp); 1157 else 1158 vput(dvp); 1159 error = vn_stat(vp, &sb, p); 1160 vput(vp); 1161 if (error) 1162 return (error); 1163 } else { 1164 error = vn_stat(dvp, &sb, p); 1165 vput(dvp); 1166 if (error) { 1167 vput(vp); 1168 return (error); 1169 } 1170 error = vn_stat(vp, &sb1, p); 1171 vput(vp); 1172 if (error) 1173 return (error); 1174 sb.st_mode &= ~S_IFDIR; 1175 sb.st_mode |= S_IFLNK; 1176 sb.st_nlink = sb1.st_nlink; 1177 sb.st_size = sb1.st_size; 1178 sb.st_blocks = sb1.st_blocks; 1179 } 1180 error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb)); 1181 return (error); 1182 } 1183 1184 /* 1185 * Pathconf system call. 1186 */ 1187 struct pathconf_args { 1188 char *fname; 1189 int name; 1190 }; 1191 /* ARGSUSED */ 1192 pathconf(p, uap, retval) 1193 struct proc *p; 1194 register struct pathconf_args *uap; 1195 int *retval; 1196 { 1197 int error; 1198 struct nameidata nd; 1199 1200 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1201 if (error = namei(&nd)) 1202 return (error); 1203 error = VOP_PATHCONF(nd.ni_vp, uap->name, retval); 1204 vput(nd.ni_vp); 1205 return (error); 1206 } 1207 1208 /* 1209 * Return target name of a symbolic link. 1210 */ 1211 struct readlink_args { 1212 char *name; 1213 char *buf; 1214 int count; 1215 }; 1216 /* ARGSUSED */ 1217 readlink(p, uap, retval) 1218 struct proc *p; 1219 register struct readlink_args *uap; 1220 int *retval; 1221 { 1222 register struct vnode *vp; 1223 struct iovec aiov; 1224 struct uio auio; 1225 int error; 1226 struct nameidata nd; 1227 1228 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, uap->name, p); 1229 if (error = namei(&nd)) 1230 return (error); 1231 vp = nd.ni_vp; 1232 if (vp->v_type != VLNK) { 1233 error = EINVAL; 1234 goto out; 1235 } 1236 aiov.iov_base = uap->buf; 1237 aiov.iov_len = uap->count; 1238 auio.uio_iov = &aiov; 1239 auio.uio_iovcnt = 1; 1240 auio.uio_offset = 0; 1241 auio.uio_rw = UIO_READ; 1242 auio.uio_segflg = UIO_USERSPACE; 1243 auio.uio_procp = p; 1244 auio.uio_resid = uap->count; 1245 error = VOP_READLINK(vp, &auio, p->p_ucred); 1246 out: 1247 vput(vp); 1248 *retval = uap->count - auio.uio_resid; 1249 return (error); 1250 } 1251 1252 /* 1253 * Change flags of a file given path name. 1254 */ 1255 struct chflags_args { 1256 char *fname; 1257 int flags; 1258 }; 1259 /* ARGSUSED */ 1260 chflags(p, uap, retval) 1261 struct proc *p; 1262 register struct chflags_args *uap; 1263 int *retval; 1264 { 1265 register struct vnode *vp; 1266 struct vattr vattr; 1267 int error; 1268 struct nameidata nd; 1269 1270 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p); 1271 if (error = namei(&nd)) 1272 return (error); 1273 vp = nd.ni_vp; 1274 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1275 VOP_LOCK(vp); 1276 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1277 error = EROFS; 1278 goto out; 1279 } 1280 VATTR_NULL(&vattr); 1281 vattr.va_flags = uap->flags; 1282 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1283 out: 1284 vput(vp); 1285 return (error); 1286 } 1287 1288 /* 1289 * Change flags of a file given a file descriptor. 1290 */ 1291 struct fchflags_args { 1292 int fd; 1293 int flags; 1294 }; 1295 /* ARGSUSED */ 1296 fchflags(p, uap, retval) 1297 struct proc *p; 1298 register struct fchflags_args *uap; 1299 int *retval; 1300 { 1301 struct vattr vattr; 1302 struct vnode *vp; 1303 struct file *fp; 1304 int error; 1305 1306 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1307 return (error); 1308 vp = (struct vnode *)fp->f_data; 1309 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1310 VOP_LOCK(vp); 1311 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1312 error = EROFS; 1313 goto out; 1314 } 1315 VATTR_NULL(&vattr); 1316 vattr.va_flags = uap->flags; 1317 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1318 out: 1319 VOP_UNLOCK(vp); 1320 return (error); 1321 } 1322 1323 /* 1324 * Change mode of a file given path name. 1325 */ 1326 struct chmod_args { 1327 char *fname; 1328 int fmode; 1329 }; 1330 /* ARGSUSED */ 1331 chmod(p, uap, retval) 1332 struct proc *p; 1333 register struct chmod_args *uap; 1334 int *retval; 1335 { 1336 register struct vnode *vp; 1337 struct vattr vattr; 1338 int error; 1339 struct nameidata nd; 1340 1341 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p); 1342 if (error = namei(&nd)) 1343 return (error); 1344 vp = nd.ni_vp; 1345 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1346 VOP_LOCK(vp); 1347 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1348 error = EROFS; 1349 goto out; 1350 } 1351 VATTR_NULL(&vattr); 1352 vattr.va_mode = uap->fmode & 07777; 1353 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1354 out: 1355 vput(vp); 1356 return (error); 1357 } 1358 1359 /* 1360 * Change mode of a file given a file descriptor. 1361 */ 1362 struct fchmod_args { 1363 int fd; 1364 int fmode; 1365 }; 1366 /* ARGSUSED */ 1367 fchmod(p, uap, retval) 1368 struct proc *p; 1369 register struct fchmod_args *uap; 1370 int *retval; 1371 { 1372 struct vattr vattr; 1373 struct vnode *vp; 1374 struct file *fp; 1375 int error; 1376 1377 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1378 return (error); 1379 vp = (struct vnode *)fp->f_data; 1380 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1381 VOP_LOCK(vp); 1382 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1383 error = EROFS; 1384 goto out; 1385 } 1386 VATTR_NULL(&vattr); 1387 vattr.va_mode = uap->fmode & 07777; 1388 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1389 out: 1390 VOP_UNLOCK(vp); 1391 return (error); 1392 } 1393 1394 /* 1395 * Set ownership given a path name. 1396 */ 1397 struct chown_args { 1398 char *fname; 1399 int uid; 1400 int gid; 1401 }; 1402 /* ARGSUSED */ 1403 chown(p, uap, retval) 1404 struct proc *p; 1405 register struct chown_args *uap; 1406 int *retval; 1407 { 1408 register struct vnode *vp; 1409 struct vattr vattr; 1410 int error; 1411 struct nameidata nd; 1412 1413 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->fname, p); 1414 if (error = namei(&nd)) 1415 return (error); 1416 vp = nd.ni_vp; 1417 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1418 VOP_LOCK(vp); 1419 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1420 error = EROFS; 1421 goto out; 1422 } 1423 VATTR_NULL(&vattr); 1424 vattr.va_uid = uap->uid; 1425 vattr.va_gid = uap->gid; 1426 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1427 out: 1428 vput(vp); 1429 return (error); 1430 } 1431 1432 /* 1433 * Set ownership given a file descriptor. 1434 */ 1435 struct fchown_args { 1436 int fd; 1437 int uid; 1438 int gid; 1439 }; 1440 /* ARGSUSED */ 1441 fchown(p, uap, retval) 1442 struct proc *p; 1443 register struct fchown_args *uap; 1444 int *retval; 1445 { 1446 struct vattr vattr; 1447 struct vnode *vp; 1448 struct file *fp; 1449 int error; 1450 1451 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1452 return (error); 1453 vp = (struct vnode *)fp->f_data; 1454 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1455 VOP_LOCK(vp); 1456 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1457 error = EROFS; 1458 goto out; 1459 } 1460 VATTR_NULL(&vattr); 1461 vattr.va_uid = uap->uid; 1462 vattr.va_gid = uap->gid; 1463 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1464 out: 1465 VOP_UNLOCK(vp); 1466 return (error); 1467 } 1468 1469 /* 1470 * Set the access and modification times of a file. 1471 */ 1472 struct utimes_args { 1473 char *fname; 1474 struct timeval *tptr; 1475 }; 1476 /* ARGSUSED */ 1477 utimes(p, uap, retval) 1478 struct proc *p; 1479 register struct utimes_args *uap; 1480 int *retval; 1481 { 1482 register struct vnode *vp; 1483 struct timeval tv[2]; 1484 struct vattr vattr; 1485 int error; 1486 struct nameidata nd; 1487 1488 VATTR_NULL(&vattr); 1489 if (uap->tptr == NULL) { 1490 microtime(&tv[0]); 1491 tv[1] = tv[0]; 1492 vattr.va_vaflags |= VA_UTIMES_NULL; 1493 } else if (error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv))) 1494 return (error); 1495 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p); 1496 if (error = namei(&nd)) 1497 return (error); 1498 vp = nd.ni_vp; 1499 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1500 VOP_LOCK(vp); 1501 if (vp->v_mount->mnt_flag & MNT_RDONLY) { 1502 error = EROFS; 1503 goto out; 1504 } 1505 vattr.va_atime.ts_sec = tv[0].tv_sec; 1506 vattr.va_atime.ts_nsec = tv[0].tv_usec * 1000; 1507 vattr.va_mtime.ts_sec = tv[1].tv_sec; 1508 vattr.va_mtime.ts_nsec = tv[1].tv_usec * 1000; 1509 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1510 out: 1511 vput(vp); 1512 return (error); 1513 } 1514 1515 struct truncate_args { 1516 char *fname; 1517 int pad; 1518 off_t length; 1519 }; 1520 1521 /* 1522 * Truncate a file given its path name. 1523 */ 1524 /* ARGSUSED */ 1525 truncate(p, uap, retval) 1526 struct proc *p; 1527 register struct truncate_args *uap; 1528 int *retval; 1529 { 1530 register struct vnode *vp; 1531 struct vattr vattr; 1532 int error; 1533 struct nameidata nd; 1534 1535 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p); 1536 if (error = namei(&nd)) 1537 return (error); 1538 vp = nd.ni_vp; 1539 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1540 VOP_LOCK(vp); 1541 if (vp->v_type == VDIR) { 1542 error = EISDIR; 1543 goto out; 1544 } 1545 if ((error = vn_writechk(vp)) || 1546 (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p))) 1547 goto out; 1548 VATTR_NULL(&vattr); 1549 vattr.va_size = uap->length; 1550 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1551 out: 1552 vput(vp); 1553 return (error); 1554 } 1555 1556 struct ftruncate_args { 1557 int fd; 1558 int pad; 1559 off_t length; 1560 }; 1561 1562 /* 1563 * Truncate a file given a file descriptor. 1564 */ 1565 /* ARGSUSED */ 1566 ftruncate(p, uap, retval) 1567 struct proc *p; 1568 register struct ftruncate_args *uap; 1569 int *retval; 1570 { 1571 struct vattr vattr; 1572 struct vnode *vp; 1573 struct file *fp; 1574 int error; 1575 1576 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1577 return (error); 1578 if ((fp->f_flag & FWRITE) == 0) 1579 return (EINVAL); 1580 vp = (struct vnode *)fp->f_data; 1581 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1582 VOP_LOCK(vp); 1583 if (vp->v_type == VDIR) { 1584 error = EISDIR; 1585 goto out; 1586 } 1587 if (error = vn_writechk(vp)) 1588 goto out; 1589 VATTR_NULL(&vattr); 1590 vattr.va_size = uap->length; 1591 error = VOP_SETATTR(vp, &vattr, fp->f_cred, p); 1592 out: 1593 VOP_UNLOCK(vp); 1594 return (error); 1595 } 1596 1597 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1598 /* 1599 * Truncate a file given its path name. 1600 */ 1601 struct otruncate_args { 1602 char *fname; 1603 long length; 1604 }; 1605 /* ARGSUSED */ 1606 otruncate(p, uap, retval) 1607 struct proc *p; 1608 register struct otruncate_args *uap; 1609 int *retval; 1610 { 1611 struct truncate_args nuap; 1612 1613 nuap.fname = uap->fname; 1614 nuap.length = uap->length; 1615 return (truncate(p, &nuap, retval)); 1616 } 1617 1618 /* 1619 * Truncate a file given a file descriptor. 1620 */ 1621 struct oftruncate_args { 1622 int fd; 1623 long length; 1624 }; 1625 /* ARGSUSED */ 1626 oftruncate(p, uap, retval) 1627 struct proc *p; 1628 register struct oftruncate_args *uap; 1629 int *retval; 1630 { 1631 struct ftruncate_args nuap; 1632 1633 nuap.fd = uap->fd; 1634 nuap.length = uap->length; 1635 return (ftruncate(p, &nuap, retval)); 1636 } 1637 #endif /* COMPAT_43 || COMPAT_SUNOS */ 1638 1639 /* 1640 * Synch an open file. 1641 */ 1642 struct fsync_args { 1643 int fd; 1644 }; 1645 /* ARGSUSED */ 1646 fsync(p, uap, retval) 1647 struct proc *p; 1648 struct fsync_args *uap; 1649 int *retval; 1650 { 1651 register struct vnode *vp; 1652 struct file *fp; 1653 int error; 1654 1655 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1656 return (error); 1657 vp = (struct vnode *)fp->f_data; 1658 VOP_LOCK(vp); 1659 error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p); 1660 VOP_UNLOCK(vp); 1661 return (error); 1662 } 1663 1664 /* 1665 * Rename system call. 1666 * 1667 * Source and destination must either both be directories, or both 1668 * not be directories. If target is a directory, it must be empty. 1669 */ 1670 struct rename_args { 1671 char *from; 1672 char *to; 1673 }; 1674 /* ARGSUSED */ 1675 rename(p, uap, retval) 1676 struct proc *p; 1677 register struct rename_args *uap; 1678 int *retval; 1679 { 1680 register struct vnode *tvp, *fvp, *tdvp; 1681 struct nameidata fromnd, tond; 1682 int error; 1683 1684 NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE, 1685 uap->from, p); 1686 if (error = namei(&fromnd)) 1687 return (error); 1688 fvp = fromnd.ni_vp; 1689 NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART, 1690 UIO_USERSPACE, uap->to, p); 1691 if (error = namei(&tond)) { 1692 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd); 1693 vrele(fromnd.ni_dvp); 1694 vrele(fvp); 1695 goto out1; 1696 } 1697 tdvp = tond.ni_dvp; 1698 tvp = tond.ni_vp; 1699 if (tvp != NULL) { 1700 if (fvp->v_type == VDIR && tvp->v_type != VDIR) { 1701 error = ENOTDIR; 1702 goto out; 1703 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { 1704 error = EISDIR; 1705 goto out; 1706 } 1707 } 1708 if (fvp == tdvp) 1709 error = EINVAL; 1710 /* 1711 * If source is the same as the destination (that is the 1712 * same inode number with the same name in the same directory), 1713 * then there is nothing to do. 1714 */ 1715 if (fvp == tvp && fromnd.ni_dvp == tdvp && 1716 fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen && 1717 !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr, 1718 fromnd.ni_cnd.cn_namelen)) 1719 error = -1; 1720 out: 1721 if (!error) { 1722 LEASE_CHECK(tdvp, p, p->p_ucred, LEASE_WRITE); 1723 if (fromnd.ni_dvp != tdvp) 1724 LEASE_CHECK(fromnd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1725 if (tvp) 1726 LEASE_CHECK(tvp, p, p->p_ucred, LEASE_WRITE); 1727 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, 1728 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); 1729 } else { 1730 VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd); 1731 if (tdvp == tvp) 1732 vrele(tdvp); 1733 else 1734 vput(tdvp); 1735 if (tvp) 1736 vput(tvp); 1737 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd); 1738 vrele(fromnd.ni_dvp); 1739 vrele(fvp); 1740 } 1741 vrele(tond.ni_startdir); 1742 FREE(tond.ni_cnd.cn_pnbuf, M_NAMEI); 1743 out1: 1744 vrele(fromnd.ni_startdir); 1745 FREE(fromnd.ni_cnd.cn_pnbuf, M_NAMEI); 1746 if (error == -1) 1747 return (0); 1748 return (error); 1749 } 1750 1751 /* 1752 * Mkdir system call. 1753 */ 1754 struct mkdir_args { 1755 char *name; 1756 int dmode; 1757 }; 1758 /* ARGSUSED */ 1759 mkdir(p, uap, retval) 1760 struct proc *p; 1761 register struct mkdir_args *uap; 1762 int *retval; 1763 { 1764 register struct vnode *vp; 1765 struct vattr vattr; 1766 int error; 1767 struct nameidata nd; 1768 1769 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->name, p); 1770 if (error = namei(&nd)) 1771 return (error); 1772 vp = nd.ni_vp; 1773 if (vp != NULL) { 1774 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1775 if (nd.ni_dvp == vp) 1776 vrele(nd.ni_dvp); 1777 else 1778 vput(nd.ni_dvp); 1779 vrele(vp); 1780 return (EEXIST); 1781 } 1782 VATTR_NULL(&vattr); 1783 vattr.va_type = VDIR; 1784 vattr.va_mode = (uap->dmode & 0777) &~ p->p_fd->fd_cmask; 1785 LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1786 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 1787 if (!error) 1788 vput(nd.ni_vp); 1789 return (error); 1790 } 1791 1792 /* 1793 * Rmdir system call. 1794 */ 1795 struct rmdir_args { 1796 char *name; 1797 }; 1798 /* ARGSUSED */ 1799 rmdir(p, uap, retval) 1800 struct proc *p; 1801 struct rmdir_args *uap; 1802 int *retval; 1803 { 1804 register struct vnode *vp; 1805 int error; 1806 struct nameidata nd; 1807 1808 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE, uap->name, p); 1809 if (error = namei(&nd)) 1810 return (error); 1811 vp = nd.ni_vp; 1812 if (vp->v_type != VDIR) { 1813 error = ENOTDIR; 1814 goto out; 1815 } 1816 /* 1817 * No rmdir "." please. 1818 */ 1819 if (nd.ni_dvp == vp) { 1820 error = EINVAL; 1821 goto out; 1822 } 1823 /* 1824 * The root of a mounted filesystem cannot be deleted. 1825 */ 1826 if (vp->v_flag & VROOT) 1827 error = EBUSY; 1828 out: 1829 if (!error) { 1830 LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1831 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1832 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 1833 } else { 1834 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1835 if (nd.ni_dvp == vp) 1836 vrele(nd.ni_dvp); 1837 else 1838 vput(nd.ni_dvp); 1839 vput(vp); 1840 } 1841 return (error); 1842 } 1843 1844 #ifdef COMPAT_43 1845 /* 1846 * Read a block of directory entries in a file system independent format. 1847 */ 1848 struct ogetdirentries_args { 1849 int fd; 1850 char *buf; 1851 unsigned count; 1852 long *basep; 1853 }; 1854 ogetdirentries(p, uap, retval) 1855 struct proc *p; 1856 register struct ogetdirentries_args *uap; 1857 int *retval; 1858 { 1859 register struct vnode *vp; 1860 struct file *fp; 1861 struct uio auio, kuio; 1862 struct iovec aiov, kiov; 1863 struct dirent *dp, *edp; 1864 caddr_t dirbuf; 1865 int error, readcnt; 1866 long loff; 1867 1868 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1869 return (error); 1870 if ((fp->f_flag & FREAD) == 0) 1871 return (EBADF); 1872 vp = (struct vnode *)fp->f_data; 1873 if (vp->v_type != VDIR) 1874 return (EINVAL); 1875 aiov.iov_base = uap->buf; 1876 aiov.iov_len = uap->count; 1877 auio.uio_iov = &aiov; 1878 auio.uio_iovcnt = 1; 1879 auio.uio_rw = UIO_READ; 1880 auio.uio_segflg = UIO_USERSPACE; 1881 auio.uio_procp = p; 1882 auio.uio_resid = uap->count; 1883 VOP_LOCK(vp); 1884 loff = auio.uio_offset = fp->f_offset; 1885 # if (BYTE_ORDER != LITTLE_ENDIAN) 1886 if (vp->v_mount->mnt_maxsymlinklen <= 0) { 1887 error = VOP_READDIR(vp, &auio, fp->f_cred); 1888 fp->f_offset = auio.uio_offset; 1889 } else 1890 # endif 1891 { 1892 kuio = auio; 1893 kuio.uio_iov = &kiov; 1894 kuio.uio_segflg = UIO_SYSSPACE; 1895 kiov.iov_len = uap->count; 1896 MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK); 1897 kiov.iov_base = dirbuf; 1898 error = VOP_READDIR(vp, &kuio, fp->f_cred); 1899 fp->f_offset = kuio.uio_offset; 1900 if (error == 0) { 1901 readcnt = uap->count - kuio.uio_resid; 1902 edp = (struct dirent *)&dirbuf[readcnt]; 1903 for (dp = (struct dirent *)dirbuf; dp < edp; ) { 1904 # if (BYTE_ORDER == LITTLE_ENDIAN) 1905 /* 1906 * The expected low byte of 1907 * dp->d_namlen is our dp->d_type. 1908 * The high MBZ byte of dp->d_namlen 1909 * is our dp->d_namlen. 1910 */ 1911 dp->d_type = dp->d_namlen; 1912 dp->d_namlen = 0; 1913 # else 1914 /* 1915 * The dp->d_type is the high byte 1916 * of the expected dp->d_namlen, 1917 * so must be zero'ed. 1918 */ 1919 dp->d_type = 0; 1920 # endif 1921 if (dp->d_reclen > 0) { 1922 dp = (struct dirent *) 1923 ((char *)dp + dp->d_reclen); 1924 } else { 1925 error = EIO; 1926 break; 1927 } 1928 } 1929 if (dp >= edp) 1930 error = uiomove(dirbuf, readcnt, &auio); 1931 } 1932 FREE(dirbuf, M_TEMP); 1933 } 1934 VOP_UNLOCK(vp); 1935 if (error) 1936 return (error); 1937 error = copyout((caddr_t)&loff, (caddr_t)uap->basep, sizeof(long)); 1938 *retval = uap->count - auio.uio_resid; 1939 return (error); 1940 } 1941 #endif 1942 1943 /* 1944 * Read a block of directory entries in a file system independent format. 1945 */ 1946 struct getdirentries_args { 1947 int fd; 1948 char *buf; 1949 unsigned count; 1950 long *basep; 1951 }; 1952 getdirentries(p, uap, retval) 1953 struct proc *p; 1954 register struct getdirentries_args *uap; 1955 int *retval; 1956 { 1957 register struct vnode *vp; 1958 struct file *fp; 1959 struct uio auio; 1960 struct iovec aiov; 1961 long loff; 1962 int error; 1963 1964 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1965 return (error); 1966 if ((fp->f_flag & FREAD) == 0) 1967 return (EBADF); 1968 vp = (struct vnode *)fp->f_data; 1969 unionread: 1970 if (vp->v_type != VDIR) 1971 return (EINVAL); 1972 aiov.iov_base = uap->buf; 1973 aiov.iov_len = uap->count; 1974 auio.uio_iov = &aiov; 1975 auio.uio_iovcnt = 1; 1976 auio.uio_rw = UIO_READ; 1977 auio.uio_segflg = UIO_USERSPACE; 1978 auio.uio_procp = p; 1979 auio.uio_resid = uap->count; 1980 VOP_LOCK(vp); 1981 loff = auio.uio_offset = fp->f_offset; 1982 error = VOP_READDIR(vp, &auio, fp->f_cred); 1983 fp->f_offset = auio.uio_offset; 1984 VOP_UNLOCK(vp); 1985 if (error) 1986 return (error); 1987 if ((uap->count == auio.uio_resid) && 1988 (vp->v_flag & VROOT) && 1989 (vp->v_mount->mnt_flag & MNT_UNION)) { 1990 struct vnode *tvp = vp; 1991 vp = vp->v_mount->mnt_vnodecovered; 1992 VREF(vp); 1993 fp->f_data = (caddr_t) vp; 1994 fp->f_offset = 0; 1995 vrele(tvp); 1996 goto unionread; 1997 } 1998 error = copyout((caddr_t)&loff, (caddr_t)uap->basep, sizeof(long)); 1999 *retval = uap->count - auio.uio_resid; 2000 return (error); 2001 } 2002 2003 /* 2004 * Set the mode mask for creation of filesystem nodes. 2005 */ 2006 struct umask_args { 2007 int mask; 2008 }; 2009 mode_t /* XXX */ 2010 umask(p, uap, retval) 2011 struct proc *p; 2012 struct umask_args *uap; 2013 int *retval; 2014 { 2015 register struct filedesc *fdp = p->p_fd; 2016 2017 *retval = fdp->fd_cmask; 2018 fdp->fd_cmask = uap->mask & 07777; 2019 return (0); 2020 } 2021 2022 /* 2023 * Void all references to file by ripping underlying filesystem 2024 * away from vnode. 2025 */ 2026 struct revoke_args { 2027 char *fname; 2028 }; 2029 /* ARGSUSED */ 2030 revoke(p, uap, retval) 2031 struct proc *p; 2032 register struct revoke_args *uap; 2033 int *retval; 2034 { 2035 register struct vnode *vp; 2036 struct vattr vattr; 2037 int error; 2038 struct nameidata nd; 2039 2040 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p); 2041 if (error = namei(&nd)) 2042 return (error); 2043 vp = nd.ni_vp; 2044 if (vp->v_type != VCHR && vp->v_type != VBLK) { 2045 error = EINVAL; 2046 goto out; 2047 } 2048 if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) 2049 goto out; 2050 if (p->p_ucred->cr_uid != vattr.va_uid && 2051 (error = suser(p->p_ucred, &p->p_acflag))) 2052 goto out; 2053 if (vp->v_usecount > 1 || (vp->v_flag & VALIASED)) 2054 vgoneall(vp); 2055 out: 2056 vrele(vp); 2057 return (error); 2058 } 2059 2060 /* 2061 * Convert a user file descriptor to a kernel file entry. 2062 */ 2063 getvnode(fdp, fdes, fpp) 2064 struct filedesc *fdp; 2065 struct file **fpp; 2066 int fdes; 2067 { 2068 struct file *fp; 2069 2070 if ((unsigned)fdes >= fdp->fd_nfiles || 2071 (fp = fdp->fd_ofiles[fdes]) == NULL) 2072 return (EBADF); 2073 if (fp->f_type != DTYPE_VNODE) 2074 return (EINVAL); 2075 *fpp = fp; 2076 return (0); 2077 } 2078