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