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