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