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