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