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