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