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.85 (Berkeley) 06/19/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.ts_sec = tv[0].tv_sec; 1445 vattr.va_atime.ts_nsec = tv[0].tv_usec * 1000; 1446 vattr.va_mtime.ts_sec = tv[1].tv_sec; 1447 vattr.va_mtime.ts_nsec = tv[1].tv_usec * 1000; 1448 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1449 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1450 out: 1451 vput(vp); 1452 return (error); 1453 } 1454 1455 #ifdef COMPAT_43 1456 /* 1457 * Truncate a file given its path name. 1458 */ 1459 /* ARGSUSED */ 1460 truncate(p, uap, retval) 1461 struct proc *p; 1462 register struct args { 1463 char *fname; 1464 long length; 1465 } *uap; 1466 int *retval; 1467 { 1468 struct nargs { 1469 char *fname; 1470 off_t length; 1471 } nuap; 1472 1473 nuap.fname = uap->fname; 1474 nuap.length = uap->length; 1475 return (__truncate(p, &nuap, retval)); 1476 } 1477 1478 /* 1479 * Truncate a file given a file descriptor. 1480 */ 1481 /* ARGSUSED */ 1482 ftruncate(p, uap, retval) 1483 struct proc *p; 1484 register struct args { 1485 int fd; 1486 long length; 1487 } *uap; 1488 int *retval; 1489 { 1490 struct nargs { 1491 int fd; 1492 off_t length; 1493 } nuap; 1494 1495 nuap.fd = uap->fd; 1496 nuap.length = uap->length; 1497 return (__ftruncate(p, &nuap, retval)); 1498 } 1499 #endif /* COMPAT_43 */ 1500 1501 /* 1502 * Truncate a file given its path name. 1503 */ 1504 /* ARGSUSED */ 1505 __truncate(p, uap, retval) 1506 struct proc *p; 1507 register struct args { 1508 char *fname; 1509 off_t length; 1510 } *uap; 1511 int *retval; 1512 { 1513 USES_VOP_ACCESS; 1514 USES_VOP_SETATTR; 1515 register struct vnode *vp; 1516 struct vattr vattr; 1517 int error; 1518 struct nameidata nd; 1519 1520 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 1521 if (error = namei(&nd)) 1522 return (error); 1523 vp = nd.ni_vp; 1524 if (vp->v_type == VDIR) { 1525 error = EISDIR; 1526 goto out; 1527 } 1528 if ((error = vn_writechk(vp)) || 1529 (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p))) 1530 goto out; 1531 VATTR_NULL(&vattr); 1532 vattr.va_size = uap->length; 1533 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1534 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1535 out: 1536 vput(vp); 1537 return (error); 1538 } 1539 1540 /* 1541 * Truncate a file given a file descriptor. 1542 */ 1543 /* ARGSUSED */ 1544 __ftruncate(p, uap, retval) 1545 struct proc *p; 1546 register struct args { 1547 int fd; 1548 off_t length; 1549 } *uap; 1550 int *retval; 1551 { 1552 USES_VOP_LOCK; 1553 USES_VOP_SETATTR; 1554 USES_VOP_UNLOCK; 1555 struct vattr vattr; 1556 struct vnode *vp; 1557 struct file *fp; 1558 int error; 1559 1560 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1561 return (error); 1562 if ((fp->f_flag & FWRITE) == 0) 1563 return (EINVAL); 1564 vp = (struct vnode *)fp->f_data; 1565 VOP_LOCK(vp); 1566 if (vp->v_type == VDIR) { 1567 error = EISDIR; 1568 goto out; 1569 } 1570 if (error = vn_writechk(vp)) 1571 goto out; 1572 VATTR_NULL(&vattr); 1573 vattr.va_size = uap->length; 1574 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1575 error = VOP_SETATTR(vp, &vattr, fp->f_cred, p); 1576 out: 1577 VOP_UNLOCK(vp); 1578 return (error); 1579 } 1580 1581 /* 1582 * Synch an open file. 1583 */ 1584 /* ARGSUSED */ 1585 fsync(p, uap, retval) 1586 struct proc *p; 1587 struct args { 1588 int fd; 1589 } *uap; 1590 int *retval; 1591 { 1592 USES_VOP_FSYNC; 1593 USES_VOP_LOCK; 1594 USES_VOP_UNLOCK; 1595 register struct vnode *vp; 1596 struct file *fp; 1597 int error; 1598 1599 if (error = getvnode(p->p_fd, uap->fd, &fp)) 1600 return (error); 1601 vp = (struct vnode *)fp->f_data; 1602 VOP_LOCK(vp); 1603 error = VOP_FSYNC(vp, fp->f_flag, fp->f_cred, MNT_WAIT, p); 1604 VOP_UNLOCK(vp); 1605 return (error); 1606 } 1607 1608 /* 1609 * Rename system call. 1610 * 1611 * Source and destination must either both be directories, or both 1612 * not be directories. If target is a directory, it must be empty. 1613 */ 1614 /* ARGSUSED */ 1615 rename(p, uap, retval) 1616 struct proc *p; 1617 register struct args { 1618 char *from; 1619 char *to; 1620 } *uap; 1621 int *retval; 1622 { 1623 USES_VOP_ABORTOP; 1624 USES_VOP_RENAME; 1625 register struct vnode *tvp, *fvp, *tdvp; 1626 struct nameidata fromnd, tond; 1627 int error; 1628 1629 NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE, 1630 uap->from, p); 1631 if (error = namei(&fromnd)) 1632 return (error); 1633 fvp = fromnd.ni_vp; 1634 NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART, 1635 UIO_USERSPACE, uap->to, p); 1636 if (error = namei(&tond)) { 1637 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd); 1638 vrele(fromnd.ni_dvp); 1639 vrele(fvp); 1640 goto out1; 1641 } 1642 tdvp = tond.ni_dvp; 1643 tvp = tond.ni_vp; 1644 if (tvp != NULL) { 1645 if (fvp->v_type == VDIR && tvp->v_type != VDIR) { 1646 error = ENOTDIR; 1647 goto out; 1648 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { 1649 error = EISDIR; 1650 goto out; 1651 } 1652 } 1653 if (fvp == tdvp) 1654 error = EINVAL; 1655 /* 1656 * If source is the same as the destination (that is the 1657 * same inode number with the same name in the same directory), 1658 * then there is nothing to do. 1659 */ 1660 if (fvp == tvp && fromnd.ni_dvp == tdvp && 1661 fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen && 1662 !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr, 1663 fromnd.ni_cnd.cn_namelen)) 1664 error = -1; 1665 out: 1666 if (!error) { 1667 LEASE_CHECK(tdvp, p, p->p_ucred, LEASE_WRITE); 1668 if (fromnd.ni_dvp != tdvp) 1669 LEASE_CHECK(fromnd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1670 if (tvp) 1671 LEASE_CHECK(tvp, p, p->p_ucred, LEASE_WRITE); 1672 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, 1673 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); 1674 } else { 1675 VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd); 1676 if (tdvp == tvp) 1677 vrele(tdvp); 1678 else 1679 vput(tdvp); 1680 if (tvp) 1681 vput(tvp); 1682 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd); 1683 vrele(fromnd.ni_dvp); 1684 vrele(fvp); 1685 } 1686 vrele(tond.ni_startdir); 1687 FREE(tond.ni_cnd.cn_pnbuf, M_NAMEI); 1688 out1: 1689 vrele(fromnd.ni_startdir); 1690 FREE(fromnd.ni_cnd.cn_pnbuf, M_NAMEI); 1691 if (error == -1) 1692 return (0); 1693 return (error); 1694 } 1695 1696 /* 1697 * Mkdir system call. 1698 */ 1699 /* ARGSUSED */ 1700 mkdir(p, uap, retval) 1701 struct proc *p; 1702 register struct args { 1703 char *name; 1704 int dmode; 1705 } *uap; 1706 int *retval; 1707 { 1708 USES_VOP_ABORTOP; 1709 USES_VOP_MKDIR; 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 /* ARGSUSED */ 1742 rmdir(p, uap, retval) 1743 struct proc *p; 1744 struct args { 1745 char *name; 1746 } *uap; 1747 int *retval; 1748 { 1749 USES_VOP_ABORTOP; 1750 USES_VOP_RMDIR; 1751 register struct vnode *vp; 1752 int error; 1753 struct nameidata nd; 1754 1755 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE, uap->name, p); 1756 if (error = namei(&nd)) 1757 return (error); 1758 vp = nd.ni_vp; 1759 if (vp->v_type != VDIR) { 1760 error = ENOTDIR; 1761 goto out; 1762 } 1763 /* 1764 * No rmdir "." please. 1765 */ 1766 if (nd.ni_dvp == vp) { 1767 error = EINVAL; 1768 goto out; 1769 } 1770 /* 1771 * The root of a mounted filesystem cannot be deleted. 1772 */ 1773 if (vp->v_flag & VROOT) 1774 error = EBUSY; 1775 out: 1776 if (!error) { 1777 LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1778 LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE); 1779 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 1780 } else { 1781 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1782 if (nd.ni_dvp == vp) 1783 vrele(nd.ni_dvp); 1784 else 1785 vput(nd.ni_dvp); 1786 vput(vp); 1787 } 1788 return (error); 1789 } 1790 1791 /* 1792 * Read a block of directory entries in a file system independent format. 1793 */ 1794 getdirentries(p, uap, retval) 1795 struct proc *p; 1796 register struct args { 1797 int fd; 1798 char *buf; 1799 unsigned count; 1800 long *basep; 1801 } *uap; 1802 int *retval; 1803 { 1804 USES_VOP_LOCK; 1805 USES_VOP_READDIR; 1806 USES_VOP_UNLOCK; 1807 register struct vnode *vp; 1808 struct file *fp; 1809 struct uio auio; 1810 struct iovec aiov; 1811 off_t off; 1812 int error, eofflag; 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 auio.uio_offset = off = fp->f_offset; 1831 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag); 1832 fp->f_offset = auio.uio_offset; 1833 VOP_UNLOCK(vp); 1834 if (error) 1835 return (error); 1836 error = copyout((caddr_t)&off, (caddr_t)uap->basep, sizeof(long)); 1837 *retval = uap->count - auio.uio_resid; 1838 return (error); 1839 } 1840 1841 /* 1842 * Set the mode mask for creation of filesystem nodes. 1843 */ 1844 mode_t 1845 umask(p, uap, retval) 1846 struct proc *p; 1847 struct args { 1848 int mask; 1849 } *uap; 1850 int *retval; 1851 { 1852 register struct filedesc *fdp = p->p_fd; 1853 1854 *retval = fdp->fd_cmask; 1855 fdp->fd_cmask = uap->mask & 07777; 1856 return (0); 1857 } 1858 1859 /* 1860 * Void all references to file by ripping underlying filesystem 1861 * away from vnode. 1862 */ 1863 /* ARGSUSED */ 1864 revoke(p, uap, retval) 1865 struct proc *p; 1866 register struct args { 1867 char *fname; 1868 } *uap; 1869 int *retval; 1870 { 1871 USES_VOP_GETATTR; 1872 register struct vnode *vp; 1873 struct vattr vattr; 1874 int error; 1875 struct nameidata nd; 1876 1877 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p); 1878 if (error = namei(&nd)) 1879 return (error); 1880 vp = nd.ni_vp; 1881 if (vp->v_type != VCHR && vp->v_type != VBLK) { 1882 error = EINVAL; 1883 goto out; 1884 } 1885 if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) 1886 goto out; 1887 if (p->p_ucred->cr_uid != vattr.va_uid && 1888 (error = suser(p->p_ucred, &p->p_acflag))) 1889 goto out; 1890 if (vp->v_usecount > 1 || (vp->v_flag & VALIASED)) 1891 vgoneall(vp); 1892 out: 1893 vrele(vp); 1894 return (error); 1895 } 1896 1897 /* 1898 * Convert a user file descriptor to a kernel file entry. 1899 */ 1900 getvnode(fdp, fdes, fpp) 1901 struct filedesc *fdp; 1902 struct file **fpp; 1903 int fdes; 1904 { 1905 struct file *fp; 1906 1907 if ((unsigned)fdes >= fdp->fd_nfiles || 1908 (fp = fdp->fd_ofiles[fdes]) == NULL) 1909 return (EBADF); 1910 if (fp->f_type != DTYPE_VNODE) 1911 return (EINVAL); 1912 *fpp = fp; 1913 return (0); 1914 } 1915