1 /* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 39 * $Id: vfs_syscalls.c,v 1.122 1999/04/27 11:16:25 phk Exp $ 40 */ 41 42 /* For 4.3 integer FS ID compatibility */ 43 #include "opt_compat.h" 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/buf.h> 48 #include <sys/sysent.h> 49 #include <sys/sysproto.h> 50 #include <sys/namei.h> 51 #include <sys/filedesc.h> 52 #include <sys/kernel.h> 53 #include <sys/fcntl.h> 54 #include <sys/file.h> 55 #include <sys/linker.h> 56 #include <sys/stat.h> 57 #include <sys/unistd.h> 58 #include <sys/vnode.h> 59 #include <sys/malloc.h> 60 #include <sys/mount.h> 61 #include <sys/proc.h> 62 #include <sys/dirent.h> 63 64 #include <miscfs/union/union.h> 65 66 #include <vm/vm.h> 67 #include <vm/vm_object.h> 68 #include <vm/vm_extern.h> 69 #include <vm/vm_zone.h> 70 #include <sys/sysctl.h> 71 72 static int change_dir __P((struct nameidata *ndp, struct proc *p)); 73 static void checkdirs __P((struct vnode *olddp)); 74 static int chroot_refuse_vdir_fds __P((struct filedesc *fdp)); 75 static int setfown __P((struct proc *, struct vnode *, uid_t, gid_t)); 76 static int setfmode __P((struct proc *, struct vnode *, int)); 77 static int setfflags __P((struct proc *, struct vnode *, int)); 78 static int setutimes __P((struct proc *, struct vnode *, struct timeval *, int)); 79 static int usermount = 0; /* if 1, non-root can mount fs. */ 80 81 int (*union_dircheckp) __P((struct proc *, struct vnode **, struct file *)); 82 83 SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, ""); 84 85 /* 86 * Virtual File System System Calls 87 */ 88 89 /* 90 * Mount a file system. 91 */ 92 #ifndef _SYS_SYSPROTO_H_ 93 struct mount_args { 94 char *type; 95 char *path; 96 int flags; 97 caddr_t data; 98 }; 99 #endif 100 /* ARGSUSED */ 101 int 102 mount(p, uap) 103 struct proc *p; 104 register struct mount_args /* { 105 syscallarg(char *) type; 106 syscallarg(char *) path; 107 syscallarg(int) flags; 108 syscallarg(caddr_t) data; 109 } */ *uap; 110 { 111 struct vnode *vp; 112 struct mount *mp; 113 struct vfsconf *vfsp; 114 int error, flag = 0, flag2 = 0; 115 struct vattr va; 116 #ifdef COMPAT_43 117 u_long fstypenum; 118 #endif 119 struct nameidata nd; 120 char fstypename[MFSNAMELEN]; 121 122 if (usermount == 0 && (error = suser(p))) 123 return (error); 124 /* 125 * Do not allow NFS export by non-root users. 126 */ 127 if (SCARG(uap, flags) & MNT_EXPORTED) { 128 error = suser(p); 129 if (error) 130 return (error); 131 } 132 /* 133 * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users 134 */ 135 if (suser_xxx(p->p_ucred, 0, 0)) 136 SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV; 137 /* 138 * Get vnode to be covered 139 */ 140 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 141 SCARG(uap, path), p); 142 if ((error = namei(&nd)) != 0) 143 return (error); 144 vp = nd.ni_vp; 145 if (SCARG(uap, flags) & MNT_UPDATE) { 146 if ((vp->v_flag & VROOT) == 0) { 147 vput(vp); 148 return (EINVAL); 149 } 150 mp = vp->v_mount; 151 flag = mp->mnt_flag; 152 flag2 = mp->mnt_kern_flag; 153 /* 154 * We only allow the filesystem to be reloaded if it 155 * is currently mounted read-only. 156 */ 157 if ((SCARG(uap, flags) & MNT_RELOAD) && 158 ((mp->mnt_flag & MNT_RDONLY) == 0)) { 159 vput(vp); 160 return (EOPNOTSUPP); /* Needs translation */ 161 } 162 mp->mnt_flag |= 163 SCARG(uap, flags) & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE); 164 /* 165 * Only root, or the user that did the original mount is 166 * permitted to update it. 167 */ 168 if (mp->mnt_stat.f_owner != p->p_ucred->cr_uid && 169 (error = suser(p))) { 170 vput(vp); 171 return (error); 172 } 173 if (vfs_busy(mp, LK_NOWAIT, 0, p)) { 174 vput(vp); 175 return (EBUSY); 176 } 177 VOP_UNLOCK(vp, 0, p); 178 goto update; 179 } 180 /* 181 * If the user is not root, ensure that they own the directory 182 * onto which we are attempting to mount. 183 */ 184 if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)) || 185 (va.va_uid != p->p_ucred->cr_uid && 186 (error = suser(p)))) { 187 vput(vp); 188 return (error); 189 } 190 if ((error = vinvalbuf(vp, V_SAVE, p->p_ucred, p, 0, 0)) != 0) 191 return (error); 192 if (vp->v_type != VDIR) { 193 vput(vp); 194 return (ENOTDIR); 195 } 196 #ifdef COMPAT_43 197 /* 198 * Historically filesystem types were identified by number. If we 199 * get an integer for the filesystem type instead of a string, we 200 * check to see if it matches one of the historic filesystem types. 201 */ 202 fstypenum = (uintptr_t)SCARG(uap, type); 203 if (fstypenum < maxvfsconf) { 204 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) 205 if (vfsp->vfc_typenum == fstypenum) 206 break; 207 if (vfsp == NULL) { 208 vput(vp); 209 return (ENODEV); 210 } 211 strncpy(fstypename, vfsp->vfc_name, MFSNAMELEN); 212 } else 213 #endif /* COMPAT_43 */ 214 if ((error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL)) != 0) { 215 vput(vp); 216 return (error); 217 } 218 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) 219 if (!strcmp(vfsp->vfc_name, fstypename)) 220 break; 221 if (vfsp == NULL) { 222 linker_file_t lf; 223 224 /* Refuse to load modules if securelevel raised */ 225 if (securelevel > 0) { 226 vput(vp); 227 return EPERM; 228 } 229 /* Only load modules for root (very important!) */ 230 if ((error = suser(p)) != 0) { 231 vput(vp); 232 return error; 233 } 234 error = linker_load_file(fstypename, &lf); 235 if (error || lf == NULL) { 236 vput(vp); 237 if (lf == NULL) 238 error = ENODEV; 239 return error; 240 } 241 lf->userrefs++; 242 /* lookup again, see if the VFS was loaded */ 243 for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) 244 if (!strcmp(vfsp->vfc_name, fstypename)) 245 break; 246 if (vfsp == NULL) { 247 lf->userrefs--; 248 linker_file_unload(lf); 249 vput(vp); 250 return (ENODEV); 251 } 252 } 253 simple_lock(&vp->v_interlock); 254 if ((vp->v_flag & VMOUNT) != 0 || 255 vp->v_mountedhere != NULL) { 256 simple_unlock(&vp->v_interlock); 257 vput(vp); 258 return (EBUSY); 259 } 260 vp->v_flag |= VMOUNT; 261 simple_unlock(&vp->v_interlock); 262 263 /* 264 * Allocate and initialize the filesystem. 265 */ 266 mp = (struct mount *)malloc((u_long)sizeof(struct mount), 267 M_MOUNT, M_WAITOK); 268 bzero((char *)mp, (u_long)sizeof(struct mount)); 269 lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE); 270 (void)vfs_busy(mp, LK_NOWAIT, 0, p); 271 mp->mnt_op = vfsp->vfc_vfsops; 272 mp->mnt_vfc = vfsp; 273 vfsp->vfc_refcount++; 274 mp->mnt_stat.f_type = vfsp->vfc_typenum; 275 mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK; 276 strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN); 277 mp->mnt_vnodecovered = vp; 278 mp->mnt_stat.f_owner = p->p_ucred->cr_uid; 279 VOP_UNLOCK(vp, 0, p); 280 update: 281 /* 282 * Set the mount level flags. 283 */ 284 if (SCARG(uap, flags) & MNT_RDONLY) 285 mp->mnt_flag |= MNT_RDONLY; 286 else if (mp->mnt_flag & MNT_RDONLY) 287 mp->mnt_kern_flag |= MNTK_WANTRDWR; 288 mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV | 289 MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME | 290 MNT_NOSYMFOLLOW | 291 MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR); 292 mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC | 293 MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE | 294 MNT_NOSYMFOLLOW | 295 MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR); 296 /* 297 * Mount the filesystem. 298 */ 299 error = VFS_MOUNT(mp, SCARG(uap, path), SCARG(uap, data), &nd, p); 300 if (mp->mnt_flag & MNT_UPDATE) { 301 vrele(vp); 302 if (mp->mnt_kern_flag & MNTK_WANTRDWR) 303 mp->mnt_flag &= ~MNT_RDONLY; 304 mp->mnt_flag &=~ (MNT_UPDATE | MNT_RELOAD | MNT_FORCE); 305 mp->mnt_kern_flag &=~ MNTK_WANTRDWR; 306 if (error) { 307 mp->mnt_flag = flag; 308 mp->mnt_kern_flag = flag2; 309 } 310 if ((mp->mnt_flag & MNT_RDONLY) == 0) { 311 if (mp->mnt_syncer == NULL) 312 error = vfs_allocate_syncvnode(mp); 313 } else { 314 if (mp->mnt_syncer != NULL) 315 vrele(mp->mnt_syncer); 316 mp->mnt_syncer = NULL; 317 } 318 vfs_unbusy(mp, p); 319 return (error); 320 } 321 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 322 /* 323 * Put the new filesystem on the mount list after root. 324 */ 325 cache_purge(vp); 326 if (!error) { 327 simple_lock(&vp->v_interlock); 328 vp->v_flag &= ~VMOUNT; 329 vp->v_mountedhere = mp; 330 simple_unlock(&vp->v_interlock); 331 simple_lock(&mountlist_slock); 332 CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); 333 simple_unlock(&mountlist_slock); 334 checkdirs(vp); 335 VOP_UNLOCK(vp, 0, p); 336 if ((mp->mnt_flag & MNT_RDONLY) == 0) 337 error = vfs_allocate_syncvnode(mp); 338 vfs_unbusy(mp, p); 339 if ((error = VFS_START(mp, 0, p)) != 0) 340 vrele(vp); 341 } else { 342 simple_lock(&vp->v_interlock); 343 vp->v_flag &= ~VMOUNT; 344 simple_unlock(&vp->v_interlock); 345 mp->mnt_vfc->vfc_refcount--; 346 vfs_unbusy(mp, p); 347 free((caddr_t)mp, M_MOUNT); 348 vput(vp); 349 } 350 return (error); 351 } 352 353 /* 354 * Scan all active processes to see if any of them have a current 355 * or root directory onto which the new filesystem has just been 356 * mounted. If so, replace them with the new mount point. 357 */ 358 static void 359 checkdirs(olddp) 360 struct vnode *olddp; 361 { 362 struct filedesc *fdp; 363 struct vnode *newdp; 364 struct proc *p; 365 366 if (olddp->v_usecount == 1) 367 return; 368 if (VFS_ROOT(olddp->v_mountedhere, &newdp)) 369 panic("mount: lost mount"); 370 for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { 371 fdp = p->p_fd; 372 if (fdp->fd_cdir == olddp) { 373 vrele(fdp->fd_cdir); 374 VREF(newdp); 375 fdp->fd_cdir = newdp; 376 } 377 if (fdp->fd_rdir == olddp) { 378 vrele(fdp->fd_rdir); 379 VREF(newdp); 380 fdp->fd_rdir = newdp; 381 } 382 } 383 if (rootvnode == olddp) { 384 vrele(rootvnode); 385 VREF(newdp); 386 rootvnode = newdp; 387 } 388 vput(newdp); 389 } 390 391 /* 392 * Unmount a file system. 393 * 394 * Note: unmount takes a path to the vnode mounted on as argument, 395 * not special file (as before). 396 */ 397 #ifndef _SYS_SYSPROTO_H_ 398 struct unmount_args { 399 char *path; 400 int flags; 401 }; 402 #endif 403 /* ARGSUSED */ 404 int 405 unmount(p, uap) 406 struct proc *p; 407 register struct unmount_args /* { 408 syscallarg(char *) path; 409 syscallarg(int) flags; 410 } */ *uap; 411 { 412 register struct vnode *vp; 413 struct mount *mp; 414 int error; 415 struct nameidata nd; 416 417 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 418 SCARG(uap, path), p); 419 if ((error = namei(&nd)) != 0) 420 return (error); 421 vp = nd.ni_vp; 422 mp = vp->v_mount; 423 424 /* 425 * Only root, or the user that did the original mount is 426 * permitted to unmount this filesystem. 427 */ 428 if ((mp->mnt_stat.f_owner != p->p_ucred->cr_uid) && 429 (error = suser(p))) { 430 vput(vp); 431 return (error); 432 } 433 434 /* 435 * Don't allow unmounting the root file system. 436 */ 437 if (mp->mnt_flag & MNT_ROOTFS) { 438 vput(vp); 439 return (EINVAL); 440 } 441 442 /* 443 * Must be the root of the filesystem 444 */ 445 if ((vp->v_flag & VROOT) == 0) { 446 vput(vp); 447 return (EINVAL); 448 } 449 vput(vp); 450 return (dounmount(mp, SCARG(uap, flags), p)); 451 } 452 453 /* 454 * Do the actual file system unmount. 455 */ 456 int 457 dounmount(mp, flags, p) 458 register struct mount *mp; 459 int flags; 460 struct proc *p; 461 { 462 struct vnode *coveredvp; 463 int error; 464 int async_flag; 465 466 simple_lock(&mountlist_slock); 467 mp->mnt_kern_flag |= MNTK_UNMOUNT; 468 lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK, &mountlist_slock, p); 469 470 if (mp->mnt_flag & MNT_EXPUBLIC) 471 vfs_setpublicfs(NULL, NULL, NULL); 472 473 vfs_msync(mp, MNT_WAIT); 474 async_flag = mp->mnt_flag & MNT_ASYNC; 475 mp->mnt_flag &=~ MNT_ASYNC; 476 cache_purgevfs(mp); /* remove cache entries for this file sys */ 477 if (mp->mnt_syncer != NULL) 478 vrele(mp->mnt_syncer); 479 if (((mp->mnt_flag & MNT_RDONLY) || 480 (error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p)) == 0) || 481 (flags & MNT_FORCE)) 482 error = VFS_UNMOUNT(mp, flags, p); 483 simple_lock(&mountlist_slock); 484 if (error) { 485 if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL) 486 (void) vfs_allocate_syncvnode(mp); 487 mp->mnt_kern_flag &= ~MNTK_UNMOUNT; 488 mp->mnt_flag |= async_flag; 489 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE, 490 &mountlist_slock, p); 491 if (mp->mnt_kern_flag & MNTK_MWAIT) 492 wakeup((caddr_t)mp); 493 return (error); 494 } 495 CIRCLEQ_REMOVE(&mountlist, mp, mnt_list); 496 if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) { 497 coveredvp->v_mountedhere = (struct mount *)0; 498 vrele(coveredvp); 499 } 500 mp->mnt_vfc->vfc_refcount--; 501 if (mp->mnt_vnodelist.lh_first != NULL) 502 panic("unmount: dangling vnode"); 503 lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_slock, p); 504 if (mp->mnt_kern_flag & MNTK_MWAIT) 505 wakeup((caddr_t)mp); 506 free((caddr_t)mp, M_MOUNT); 507 return (0); 508 } 509 510 /* 511 * Sync each mounted filesystem. 512 */ 513 #ifndef _SYS_SYSPROTO_H_ 514 struct sync_args { 515 int dummy; 516 }; 517 #endif 518 519 #ifdef DEBUG 520 static int syncprt = 0; 521 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, ""); 522 #endif 523 524 /* ARGSUSED */ 525 int 526 sync(p, uap) 527 struct proc *p; 528 struct sync_args *uap; 529 { 530 register struct mount *mp, *nmp; 531 int asyncflag; 532 533 simple_lock(&mountlist_slock); 534 for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) { 535 if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) { 536 nmp = mp->mnt_list.cqe_next; 537 continue; 538 } 539 if ((mp->mnt_flag & MNT_RDONLY) == 0) { 540 asyncflag = mp->mnt_flag & MNT_ASYNC; 541 mp->mnt_flag &= ~MNT_ASYNC; 542 vfs_msync(mp, MNT_NOWAIT); 543 VFS_SYNC(mp, MNT_NOWAIT, 544 ((p != NULL) ? p->p_ucred : NOCRED), p); 545 mp->mnt_flag |= asyncflag; 546 } 547 simple_lock(&mountlist_slock); 548 nmp = mp->mnt_list.cqe_next; 549 vfs_unbusy(mp, p); 550 } 551 simple_unlock(&mountlist_slock); 552 #if 0 553 /* 554 * XXX don't call vfs_bufstats() yet because that routine 555 * was not imported in the Lite2 merge. 556 */ 557 #ifdef DIAGNOSTIC 558 if (syncprt) 559 vfs_bufstats(); 560 #endif /* DIAGNOSTIC */ 561 #endif 562 return (0); 563 } 564 565 /* XXX PRISON: could be per prison flag */ 566 static int prison_quotas; 567 #if 0 568 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, ""); 569 #endif 570 571 /* 572 * Change filesystem quotas. 573 */ 574 #ifndef _SYS_SYSPROTO_H_ 575 struct quotactl_args { 576 char *path; 577 int cmd; 578 int uid; 579 caddr_t arg; 580 }; 581 #endif 582 /* ARGSUSED */ 583 int 584 quotactl(p, uap) 585 struct proc *p; 586 register struct quotactl_args /* { 587 syscallarg(char *) path; 588 syscallarg(int) cmd; 589 syscallarg(int) uid; 590 syscallarg(caddr_t) arg; 591 } */ *uap; 592 { 593 register struct mount *mp; 594 int error; 595 struct nameidata nd; 596 597 if (p->p_prison && !prison_quotas) 598 return (EPERM); 599 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 600 if ((error = namei(&nd)) != 0) 601 return (error); 602 mp = nd.ni_vp->v_mount; 603 vrele(nd.ni_vp); 604 return (VFS_QUOTACTL(mp, SCARG(uap, cmd), SCARG(uap, uid), 605 SCARG(uap, arg), p)); 606 } 607 608 /* 609 * Get filesystem statistics. 610 */ 611 #ifndef _SYS_SYSPROTO_H_ 612 struct statfs_args { 613 char *path; 614 struct statfs *buf; 615 }; 616 #endif 617 /* ARGSUSED */ 618 int 619 statfs(p, uap) 620 struct proc *p; 621 register struct statfs_args /* { 622 syscallarg(char *) path; 623 syscallarg(struct statfs *) buf; 624 } */ *uap; 625 { 626 register struct mount *mp; 627 register struct statfs *sp; 628 int error; 629 struct nameidata nd; 630 struct statfs sb; 631 632 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 633 if ((error = namei(&nd)) != 0) 634 return (error); 635 mp = nd.ni_vp->v_mount; 636 sp = &mp->mnt_stat; 637 vrele(nd.ni_vp); 638 error = VFS_STATFS(mp, sp, p); 639 if (error) 640 return (error); 641 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 642 if (suser_xxx(p->p_ucred, 0, 0)) { 643 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); 644 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 645 sp = &sb; 646 } 647 return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp))); 648 } 649 650 /* 651 * Get filesystem statistics. 652 */ 653 #ifndef _SYS_SYSPROTO_H_ 654 struct fstatfs_args { 655 int fd; 656 struct statfs *buf; 657 }; 658 #endif 659 /* ARGSUSED */ 660 int 661 fstatfs(p, uap) 662 struct proc *p; 663 register struct fstatfs_args /* { 664 syscallarg(int) fd; 665 syscallarg(struct statfs *) buf; 666 } */ *uap; 667 { 668 struct file *fp; 669 struct mount *mp; 670 register struct statfs *sp; 671 int error; 672 struct statfs sb; 673 674 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 675 return (error); 676 mp = ((struct vnode *)fp->f_data)->v_mount; 677 sp = &mp->mnt_stat; 678 error = VFS_STATFS(mp, sp, p); 679 if (error) 680 return (error); 681 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 682 if (suser_xxx(p->p_ucred, 0, 0)) { 683 bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); 684 sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; 685 sp = &sb; 686 } 687 return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp))); 688 } 689 690 /* 691 * Get statistics on all filesystems. 692 */ 693 #ifndef _SYS_SYSPROTO_H_ 694 struct getfsstat_args { 695 struct statfs *buf; 696 long bufsize; 697 int flags; 698 }; 699 #endif 700 int 701 getfsstat(p, uap) 702 struct proc *p; 703 register struct getfsstat_args /* { 704 syscallarg(struct statfs *) buf; 705 syscallarg(long) bufsize; 706 syscallarg(int) flags; 707 } */ *uap; 708 { 709 register struct mount *mp, *nmp; 710 register struct statfs *sp; 711 caddr_t sfsp; 712 long count, maxcount, error; 713 714 maxcount = SCARG(uap, bufsize) / sizeof(struct statfs); 715 sfsp = (caddr_t)SCARG(uap, buf); 716 count = 0; 717 simple_lock(&mountlist_slock); 718 for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) { 719 if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) { 720 nmp = mp->mnt_list.cqe_next; 721 continue; 722 } 723 if (sfsp && count < maxcount) { 724 sp = &mp->mnt_stat; 725 /* 726 * If MNT_NOWAIT or MNT_LAZY is specified, do not 727 * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY 728 * overrides MNT_WAIT. 729 */ 730 if (((SCARG(uap, flags) & (MNT_LAZY|MNT_NOWAIT)) == 0 || 731 (SCARG(uap, flags) & MNT_WAIT)) && 732 (error = VFS_STATFS(mp, sp, p))) { 733 simple_lock(&mountlist_slock); 734 nmp = mp->mnt_list.cqe_next; 735 vfs_unbusy(mp, p); 736 continue; 737 } 738 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; 739 error = copyout((caddr_t)sp, sfsp, sizeof(*sp)); 740 if (error) { 741 vfs_unbusy(mp, p); 742 return (error); 743 } 744 sfsp += sizeof(*sp); 745 } 746 count++; 747 simple_lock(&mountlist_slock); 748 nmp = mp->mnt_list.cqe_next; 749 vfs_unbusy(mp, p); 750 } 751 simple_unlock(&mountlist_slock); 752 if (sfsp && count > maxcount) 753 p->p_retval[0] = maxcount; 754 else 755 p->p_retval[0] = count; 756 return (0); 757 } 758 759 /* 760 * Change current working directory to a given file descriptor. 761 */ 762 #ifndef _SYS_SYSPROTO_H_ 763 struct fchdir_args { 764 int fd; 765 }; 766 #endif 767 /* ARGSUSED */ 768 int 769 fchdir(p, uap) 770 struct proc *p; 771 struct fchdir_args /* { 772 syscallarg(int) fd; 773 } */ *uap; 774 { 775 register struct filedesc *fdp = p->p_fd; 776 struct vnode *vp, *tdp; 777 struct mount *mp; 778 struct file *fp; 779 int error; 780 781 if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0) 782 return (error); 783 vp = (struct vnode *)fp->f_data; 784 VREF(vp); 785 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 786 if (vp->v_type != VDIR) 787 error = ENOTDIR; 788 else 789 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 790 while (!error && (mp = vp->v_mountedhere) != NULL) { 791 if (vfs_busy(mp, 0, 0, p)) 792 continue; 793 error = VFS_ROOT(mp, &tdp); 794 vfs_unbusy(mp, p); 795 if (error) 796 break; 797 vput(vp); 798 vp = tdp; 799 } 800 if (error) { 801 vput(vp); 802 return (error); 803 } 804 VOP_UNLOCK(vp, 0, p); 805 vrele(fdp->fd_cdir); 806 fdp->fd_cdir = vp; 807 return (0); 808 } 809 810 /* 811 * Change current working directory (``.''). 812 */ 813 #ifndef _SYS_SYSPROTO_H_ 814 struct chdir_args { 815 char *path; 816 }; 817 #endif 818 /* ARGSUSED */ 819 int 820 chdir(p, uap) 821 struct proc *p; 822 struct chdir_args /* { 823 syscallarg(char *) path; 824 } */ *uap; 825 { 826 register struct filedesc *fdp = p->p_fd; 827 int error; 828 struct nameidata nd; 829 830 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 831 SCARG(uap, path), p); 832 if ((error = change_dir(&nd, p)) != 0) 833 return (error); 834 vrele(fdp->fd_cdir); 835 fdp->fd_cdir = nd.ni_vp; 836 return (0); 837 } 838 839 /* 840 * Helper function for raised chroot(2) security function: Refuse if 841 * any filedescriptors are open directories. 842 */ 843 static int 844 chroot_refuse_vdir_fds(fdp) 845 struct filedesc *fdp; 846 { 847 struct vnode *vp; 848 struct file *fp; 849 int error; 850 int fd; 851 852 for (fd = 0; fd < fdp->fd_nfiles ; fd++) { 853 error = getvnode(fdp, fd, &fp); 854 if (error) 855 continue; 856 vp = (struct vnode *)fp->f_data; 857 if (vp->v_type != VDIR) 858 continue; 859 return(EPERM); 860 } 861 return (0); 862 } 863 864 /* 865 * This sysctl determines if we will allow a process to chroot(2) if it 866 * has a directory open: 867 * 0: disallowed for all processes. 868 * 1: allowed for processes that were not already chroot(2)'ed. 869 * 2: allowed for all processes. 870 */ 871 872 static int chroot_allow_open_directories = 1; 873 874 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW, 875 &chroot_allow_open_directories, 0, ""); 876 877 /* 878 * Change notion of root (``/'') directory. 879 */ 880 #ifndef _SYS_SYSPROTO_H_ 881 struct chroot_args { 882 char *path; 883 }; 884 #endif 885 /* ARGSUSED */ 886 int 887 chroot(p, uap) 888 struct proc *p; 889 struct chroot_args /* { 890 syscallarg(char *) path; 891 } */ *uap; 892 { 893 register struct filedesc *fdp = p->p_fd; 894 int error; 895 struct nameidata nd; 896 897 error = suser_xxx(0, p, PRISON_ROOT); 898 if (error) 899 return (error); 900 if (chroot_allow_open_directories == 0 || 901 (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode)) 902 error = chroot_refuse_vdir_fds(fdp); 903 if (error) 904 return (error); 905 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 906 SCARG(uap, path), p); 907 if ((error = change_dir(&nd, p)) != 0) 908 return (error); 909 vrele(fdp->fd_rdir); 910 fdp->fd_rdir = nd.ni_vp; 911 return (0); 912 } 913 914 /* 915 * Common routine for chroot and chdir. 916 */ 917 static int 918 change_dir(ndp, p) 919 register struct nameidata *ndp; 920 struct proc *p; 921 { 922 struct vnode *vp; 923 int error; 924 925 error = namei(ndp); 926 if (error) 927 return (error); 928 vp = ndp->ni_vp; 929 if (vp->v_type != VDIR) 930 error = ENOTDIR; 931 else 932 error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); 933 if (error) 934 vput(vp); 935 else 936 VOP_UNLOCK(vp, 0, p); 937 return (error); 938 } 939 940 /* 941 * Check permissions, allocate an open file structure, 942 * and call the device open routine if any. 943 */ 944 #ifndef _SYS_SYSPROTO_H_ 945 struct open_args { 946 char *path; 947 int flags; 948 int mode; 949 }; 950 #endif 951 int 952 open(p, uap) 953 struct proc *p; 954 register struct open_args /* { 955 syscallarg(char *) path; 956 syscallarg(int) flags; 957 syscallarg(int) mode; 958 } */ *uap; 959 { 960 register struct filedesc *fdp = p->p_fd; 961 register struct file *fp; 962 register struct vnode *vp; 963 int cmode, flags, oflags; 964 struct file *nfp; 965 int type, indx, error; 966 struct flock lf; 967 struct nameidata nd; 968 969 oflags = SCARG(uap, flags); 970 if ((oflags & O_ACCMODE) == O_ACCMODE) 971 return (EINVAL); 972 flags = FFLAGS(oflags); 973 error = falloc(p, &nfp, &indx); 974 if (error) 975 return (error); 976 fp = nfp; 977 cmode = ((SCARG(uap, mode) &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; 978 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 979 p->p_dupfd = -indx - 1; /* XXX check for fdopen */ 980 error = vn_open(&nd, flags, cmode); 981 if (error) { 982 ffree(fp); 983 if ((error == ENODEV || error == ENXIO) && 984 p->p_dupfd >= 0 && /* XXX from fdopen */ 985 (error = 986 dupfdopen(fdp, indx, p->p_dupfd, flags, error)) == 0) { 987 p->p_retval[0] = indx; 988 return (0); 989 } 990 if (error == ERESTART) 991 error = EINTR; 992 fdp->fd_ofiles[indx] = NULL; 993 return (error); 994 } 995 p->p_dupfd = 0; 996 vp = nd.ni_vp; 997 998 fp->f_flag = flags & FMASK; 999 fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE); 1000 fp->f_ops = &vnops; 1001 fp->f_data = (caddr_t)vp; 1002 if (flags & (O_EXLOCK | O_SHLOCK)) { 1003 lf.l_whence = SEEK_SET; 1004 lf.l_start = 0; 1005 lf.l_len = 0; 1006 if (flags & O_EXLOCK) 1007 lf.l_type = F_WRLCK; 1008 else 1009 lf.l_type = F_RDLCK; 1010 type = F_FLOCK; 1011 if ((flags & FNONBLOCK) == 0) 1012 type |= F_WAIT; 1013 VOP_UNLOCK(vp, 0, p); 1014 if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) { 1015 (void) vn_close(vp, fp->f_flag, fp->f_cred, p); 1016 ffree(fp); 1017 fdp->fd_ofiles[indx] = NULL; 1018 return (error); 1019 } 1020 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1021 fp->f_flag |= FHASLOCK; 1022 } 1023 if ((vp->v_type == VREG) && (vp->v_object == NULL)) 1024 vfs_object_create(vp, p, p->p_ucred); 1025 VOP_UNLOCK(vp, 0, p); 1026 p->p_retval[0] = indx; 1027 return (0); 1028 } 1029 1030 #ifdef COMPAT_43 1031 /* 1032 * Create a file. 1033 */ 1034 #ifndef _SYS_SYSPROTO_H_ 1035 struct ocreat_args { 1036 char *path; 1037 int mode; 1038 }; 1039 #endif 1040 int 1041 ocreat(p, uap) 1042 struct proc *p; 1043 register struct ocreat_args /* { 1044 syscallarg(char *) path; 1045 syscallarg(int) mode; 1046 } */ *uap; 1047 { 1048 struct open_args /* { 1049 syscallarg(char *) path; 1050 syscallarg(int) flags; 1051 syscallarg(int) mode; 1052 } */ nuap; 1053 1054 SCARG(&nuap, path) = SCARG(uap, path); 1055 SCARG(&nuap, mode) = SCARG(uap, mode); 1056 SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC; 1057 return (open(p, &nuap)); 1058 } 1059 #endif /* COMPAT_43 */ 1060 1061 /* 1062 * Create a special file. 1063 */ 1064 #ifndef _SYS_SYSPROTO_H_ 1065 struct mknod_args { 1066 char *path; 1067 int mode; 1068 int dev; 1069 }; 1070 #endif 1071 /* ARGSUSED */ 1072 int 1073 mknod(p, uap) 1074 struct proc *p; 1075 register struct mknod_args /* { 1076 syscallarg(char *) path; 1077 syscallarg(int) mode; 1078 syscallarg(int) dev; 1079 } */ *uap; 1080 { 1081 register struct vnode *vp; 1082 struct vattr vattr; 1083 int error; 1084 int whiteout = 0; 1085 struct nameidata nd; 1086 1087 switch (SCARG(uap, mode) & S_IFMT) { 1088 case S_IFCHR: 1089 case S_IFBLK: 1090 error = suser(p); 1091 break; 1092 default: 1093 error = suser_xxx(0, p, PRISON_ROOT); 1094 break; 1095 } 1096 if (error) 1097 return (error); 1098 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p); 1099 if ((error = namei(&nd)) != 0) 1100 return (error); 1101 vp = nd.ni_vp; 1102 if (vp != NULL) 1103 error = EEXIST; 1104 else { 1105 VATTR_NULL(&vattr); 1106 vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask; 1107 vattr.va_rdev = SCARG(uap, dev); 1108 whiteout = 0; 1109 1110 switch (SCARG(uap, mode) & S_IFMT) { 1111 case S_IFMT: /* used by badsect to flag bad sectors */ 1112 vattr.va_type = VBAD; 1113 break; 1114 case S_IFCHR: 1115 vattr.va_type = VCHR; 1116 break; 1117 case S_IFBLK: 1118 vattr.va_type = VBLK; 1119 break; 1120 case S_IFWHT: 1121 whiteout = 1; 1122 break; 1123 default: 1124 error = EINVAL; 1125 break; 1126 } 1127 } 1128 if (!error) { 1129 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1130 if (whiteout) { 1131 error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE); 1132 if (error) 1133 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1134 vput(nd.ni_dvp); 1135 } else { 1136 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, 1137 &nd.ni_cnd, &vattr); 1138 vput(nd.ni_dvp); 1139 } 1140 } else { 1141 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1142 if (nd.ni_dvp == vp) 1143 vrele(nd.ni_dvp); 1144 else 1145 vput(nd.ni_dvp); 1146 if (vp) 1147 vrele(vp); 1148 } 1149 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod"); 1150 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod"); 1151 return (error); 1152 } 1153 1154 /* 1155 * Create a named pipe. 1156 */ 1157 #ifndef _SYS_SYSPROTO_H_ 1158 struct mkfifo_args { 1159 char *path; 1160 int mode; 1161 }; 1162 #endif 1163 /* ARGSUSED */ 1164 int 1165 mkfifo(p, uap) 1166 struct proc *p; 1167 register struct mkfifo_args /* { 1168 syscallarg(char *) path; 1169 syscallarg(int) mode; 1170 } */ *uap; 1171 { 1172 struct vattr vattr; 1173 int error; 1174 struct nameidata nd; 1175 1176 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p); 1177 if ((error = namei(&nd)) != 0) 1178 return (error); 1179 if (nd.ni_vp != NULL) { 1180 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1181 if (nd.ni_dvp == nd.ni_vp) 1182 vrele(nd.ni_dvp); 1183 else 1184 vput(nd.ni_dvp); 1185 vrele(nd.ni_vp); 1186 return (EEXIST); 1187 } 1188 VATTR_NULL(&vattr); 1189 vattr.va_type = VFIFO; 1190 vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask; 1191 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1192 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 1193 vput(nd.ni_dvp); 1194 return (error); 1195 } 1196 1197 /* 1198 * Make a hard file link. 1199 */ 1200 #ifndef _SYS_SYSPROTO_H_ 1201 struct link_args { 1202 char *path; 1203 char *link; 1204 }; 1205 #endif 1206 /* ARGSUSED */ 1207 int 1208 link(p, uap) 1209 struct proc *p; 1210 register struct link_args /* { 1211 syscallarg(char *) path; 1212 syscallarg(char *) link; 1213 } */ *uap; 1214 { 1215 register struct vnode *vp; 1216 struct nameidata nd; 1217 int error; 1218 1219 NDINIT(&nd, LOOKUP, FOLLOW|NOOBJ, UIO_USERSPACE, SCARG(uap, path), p); 1220 if ((error = namei(&nd)) != 0) 1221 return (error); 1222 vp = nd.ni_vp; 1223 if (vp->v_type == VDIR) 1224 error = EPERM; /* POSIX */ 1225 else { 1226 NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), p); 1227 error = namei(&nd); 1228 if (!error) { 1229 if (nd.ni_vp != NULL) { 1230 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1231 if (nd.ni_vp) 1232 vrele(nd.ni_vp); 1233 error = EEXIST; 1234 } else { 1235 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, 1236 LEASE_WRITE); 1237 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 1238 error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); 1239 } 1240 if (nd.ni_dvp == nd.ni_vp) 1241 vrele(nd.ni_dvp); 1242 else 1243 vput(nd.ni_dvp); 1244 } 1245 } 1246 vrele(vp); 1247 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link"); 1248 ASSERT_VOP_UNLOCKED(nd.ni_vp, "link"); 1249 return (error); 1250 } 1251 1252 /* 1253 * Make a symbolic link. 1254 */ 1255 #ifndef _SYS_SYSPROTO_H_ 1256 struct symlink_args { 1257 char *path; 1258 char *link; 1259 }; 1260 #endif 1261 /* ARGSUSED */ 1262 int 1263 symlink(p, uap) 1264 struct proc *p; 1265 register struct symlink_args /* { 1266 syscallarg(char *) path; 1267 syscallarg(char *) link; 1268 } */ *uap; 1269 { 1270 struct vattr vattr; 1271 char *path; 1272 int error; 1273 struct nameidata nd; 1274 1275 path = zalloc(namei_zone); 1276 if ((error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL)) != 0) 1277 goto out; 1278 NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), p); 1279 if ((error = namei(&nd)) != 0) 1280 goto out; 1281 if (nd.ni_vp) { 1282 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1283 if (nd.ni_dvp == nd.ni_vp) 1284 vrele(nd.ni_dvp); 1285 else 1286 vput(nd.ni_dvp); 1287 vrele(nd.ni_vp); 1288 error = EEXIST; 1289 goto out; 1290 } 1291 VATTR_NULL(&vattr); 1292 vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask; 1293 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1294 error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path); 1295 vput(nd.ni_dvp); 1296 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink"); 1297 ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink"); 1298 out: 1299 zfree(namei_zone, path); 1300 return (error); 1301 } 1302 1303 /* 1304 * Delete a whiteout from the filesystem. 1305 */ 1306 /* ARGSUSED */ 1307 int 1308 undelete(p, uap) 1309 struct proc *p; 1310 register struct undelete_args /* { 1311 syscallarg(char *) path; 1312 } */ *uap; 1313 { 1314 int error; 1315 struct nameidata nd; 1316 1317 NDINIT(&nd, DELETE, LOCKPARENT|DOWHITEOUT, UIO_USERSPACE, 1318 SCARG(uap, path), p); 1319 error = namei(&nd); 1320 if (error) 1321 return (error); 1322 1323 if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) { 1324 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1325 if (nd.ni_dvp == nd.ni_vp) 1326 vrele(nd.ni_dvp); 1327 else 1328 vput(nd.ni_dvp); 1329 if (nd.ni_vp) 1330 vrele(nd.ni_vp); 1331 return (EEXIST); 1332 } 1333 1334 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1335 if ((error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE)) != 0) 1336 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1337 vput(nd.ni_dvp); 1338 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "undelete"); 1339 ASSERT_VOP_UNLOCKED(nd.ni_vp, "undelete"); 1340 return (error); 1341 } 1342 1343 /* 1344 * Delete a name from the filesystem. 1345 */ 1346 #ifndef _SYS_SYSPROTO_H_ 1347 struct unlink_args { 1348 char *path; 1349 }; 1350 #endif 1351 /* ARGSUSED */ 1352 int 1353 unlink(p, uap) 1354 struct proc *p; 1355 struct unlink_args /* { 1356 syscallarg(char *) path; 1357 } */ *uap; 1358 { 1359 register struct vnode *vp; 1360 int error; 1361 struct nameidata nd; 1362 1363 NDINIT(&nd, DELETE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p); 1364 if ((error = namei(&nd)) != 0) 1365 return (error); 1366 vp = nd.ni_vp; 1367 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 1368 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1369 1370 if (vp->v_type == VDIR) 1371 error = EPERM; /* POSIX */ 1372 else { 1373 /* 1374 * The root of a mounted filesystem cannot be deleted. 1375 * 1376 * XXX: can this only be a VDIR case? 1377 */ 1378 if (vp->v_flag & VROOT) 1379 error = EBUSY; 1380 } 1381 1382 if (!error) { 1383 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 1384 error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); 1385 } else { 1386 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 1387 } 1388 if (nd.ni_dvp == vp) 1389 vrele(nd.ni_dvp); 1390 else 1391 vput(nd.ni_dvp); 1392 if (vp != NULLVP) 1393 vput(vp); 1394 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink"); 1395 ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink"); 1396 return (error); 1397 } 1398 1399 /* 1400 * Reposition read/write file offset. 1401 */ 1402 #ifndef _SYS_SYSPROTO_H_ 1403 struct lseek_args { 1404 int fd; 1405 int pad; 1406 off_t offset; 1407 int whence; 1408 }; 1409 #endif 1410 int 1411 lseek(p, uap) 1412 struct proc *p; 1413 register struct lseek_args /* { 1414 syscallarg(int) fd; 1415 syscallarg(int) pad; 1416 syscallarg(off_t) offset; 1417 syscallarg(int) whence; 1418 } */ *uap; 1419 { 1420 struct ucred *cred = p->p_ucred; 1421 register struct filedesc *fdp = p->p_fd; 1422 register struct file *fp; 1423 struct vattr vattr; 1424 int error; 1425 1426 if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles || 1427 (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL) 1428 return (EBADF); 1429 if (fp->f_type != DTYPE_VNODE) 1430 return (ESPIPE); 1431 switch (SCARG(uap, whence)) { 1432 case L_INCR: 1433 fp->f_offset += SCARG(uap, offset); 1434 break; 1435 case L_XTND: 1436 error=VOP_GETATTR((struct vnode *)fp->f_data, &vattr, cred, p); 1437 if (error) 1438 return (error); 1439 fp->f_offset = SCARG(uap, offset) + vattr.va_size; 1440 break; 1441 case L_SET: 1442 fp->f_offset = SCARG(uap, offset); 1443 break; 1444 default: 1445 return (EINVAL); 1446 } 1447 *(off_t *)(p->p_retval) = fp->f_offset; 1448 return (0); 1449 } 1450 1451 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1452 /* 1453 * Reposition read/write file offset. 1454 */ 1455 #ifndef _SYS_SYSPROTO_H_ 1456 struct olseek_args { 1457 int fd; 1458 long offset; 1459 int whence; 1460 }; 1461 #endif 1462 int 1463 olseek(p, uap) 1464 struct proc *p; 1465 register struct olseek_args /* { 1466 syscallarg(int) fd; 1467 syscallarg(long) offset; 1468 syscallarg(int) whence; 1469 } */ *uap; 1470 { 1471 struct lseek_args /* { 1472 syscallarg(int) fd; 1473 syscallarg(int) pad; 1474 syscallarg(off_t) offset; 1475 syscallarg(int) whence; 1476 } */ nuap; 1477 int error; 1478 1479 SCARG(&nuap, fd) = SCARG(uap, fd); 1480 SCARG(&nuap, offset) = SCARG(uap, offset); 1481 SCARG(&nuap, whence) = SCARG(uap, whence); 1482 error = lseek(p, &nuap); 1483 return (error); 1484 } 1485 #endif /* COMPAT_43 */ 1486 1487 /* 1488 * Check access permissions. 1489 */ 1490 #ifndef _SYS_SYSPROTO_H_ 1491 struct access_args { 1492 char *path; 1493 int flags; 1494 }; 1495 #endif 1496 int 1497 access(p, uap) 1498 struct proc *p; 1499 register struct access_args /* { 1500 syscallarg(char *) path; 1501 syscallarg(int) flags; 1502 } */ *uap; 1503 { 1504 register struct ucred *cred = p->p_ucred; 1505 register struct vnode *vp; 1506 int error, flags, t_gid, t_uid; 1507 struct nameidata nd; 1508 1509 t_uid = cred->cr_uid; 1510 t_gid = cred->cr_groups[0]; 1511 cred->cr_uid = p->p_cred->p_ruid; 1512 cred->cr_groups[0] = p->p_cred->p_rgid; 1513 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1514 SCARG(uap, path), p); 1515 if ((error = namei(&nd)) != 0) 1516 goto out1; 1517 vp = nd.ni_vp; 1518 1519 /* Flags == 0 means only check for existence. */ 1520 if (SCARG(uap, flags)) { 1521 flags = 0; 1522 if (SCARG(uap, flags) & R_OK) 1523 flags |= VREAD; 1524 if (SCARG(uap, flags) & W_OK) 1525 flags |= VWRITE; 1526 if (SCARG(uap, flags) & X_OK) 1527 flags |= VEXEC; 1528 if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) 1529 error = VOP_ACCESS(vp, flags, cred, p); 1530 } 1531 vput(vp); 1532 out1: 1533 cred->cr_uid = t_uid; 1534 cred->cr_groups[0] = t_gid; 1535 return (error); 1536 } 1537 1538 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1539 /* 1540 * Get file status; this version follows links. 1541 */ 1542 #ifndef _SYS_SYSPROTO_H_ 1543 struct ostat_args { 1544 char *path; 1545 struct ostat *ub; 1546 }; 1547 #endif 1548 /* ARGSUSED */ 1549 int 1550 ostat(p, uap) 1551 struct proc *p; 1552 register struct ostat_args /* { 1553 syscallarg(char *) path; 1554 syscallarg(struct ostat *) ub; 1555 } */ *uap; 1556 { 1557 struct stat sb; 1558 struct ostat osb; 1559 int error; 1560 struct nameidata nd; 1561 1562 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1563 SCARG(uap, path), p); 1564 if ((error = namei(&nd)) != 0) 1565 return (error); 1566 error = vn_stat(nd.ni_vp, &sb, p); 1567 vput(nd.ni_vp); 1568 if (error) 1569 return (error); 1570 cvtstat(&sb, &osb); 1571 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb)); 1572 return (error); 1573 } 1574 1575 /* 1576 * Get file status; this version does not follow links. 1577 */ 1578 #ifndef _SYS_SYSPROTO_H_ 1579 struct olstat_args { 1580 char *path; 1581 struct ostat *ub; 1582 }; 1583 #endif 1584 /* ARGSUSED */ 1585 int 1586 olstat(p, uap) 1587 struct proc *p; 1588 register struct olstat_args /* { 1589 syscallarg(char *) path; 1590 syscallarg(struct ostat *) ub; 1591 } */ *uap; 1592 { 1593 struct vnode *vp; 1594 struct stat sb; 1595 struct ostat osb; 1596 int error; 1597 struct nameidata nd; 1598 1599 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1600 SCARG(uap, path), p); 1601 if ((error = namei(&nd)) != 0) 1602 return (error); 1603 vp = nd.ni_vp; 1604 error = vn_stat(vp, &sb, p); 1605 vput(vp); 1606 if (error) 1607 return (error); 1608 cvtstat(&sb, &osb); 1609 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb)); 1610 return (error); 1611 } 1612 1613 /* 1614 * Convert from an old to a new stat structure. 1615 */ 1616 void 1617 cvtstat(st, ost) 1618 struct stat *st; 1619 struct ostat *ost; 1620 { 1621 1622 ost->st_dev = st->st_dev; 1623 ost->st_ino = st->st_ino; 1624 ost->st_mode = st->st_mode; 1625 ost->st_nlink = st->st_nlink; 1626 ost->st_uid = st->st_uid; 1627 ost->st_gid = st->st_gid; 1628 ost->st_rdev = st->st_rdev; 1629 if (st->st_size < (quad_t)1 << 32) 1630 ost->st_size = st->st_size; 1631 else 1632 ost->st_size = -2; 1633 ost->st_atime = st->st_atime; 1634 ost->st_mtime = st->st_mtime; 1635 ost->st_ctime = st->st_ctime; 1636 ost->st_blksize = st->st_blksize; 1637 ost->st_blocks = st->st_blocks; 1638 ost->st_flags = st->st_flags; 1639 ost->st_gen = st->st_gen; 1640 } 1641 #endif /* COMPAT_43 || COMPAT_SUNOS */ 1642 1643 /* 1644 * Get file status; this version follows links. 1645 */ 1646 #ifndef _SYS_SYSPROTO_H_ 1647 struct stat_args { 1648 char *path; 1649 struct stat *ub; 1650 }; 1651 #endif 1652 /* ARGSUSED */ 1653 int 1654 stat(p, uap) 1655 struct proc *p; 1656 register struct stat_args /* { 1657 syscallarg(char *) path; 1658 syscallarg(struct stat *) ub; 1659 } */ *uap; 1660 { 1661 struct stat sb; 1662 int error; 1663 struct nameidata nd; 1664 1665 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1666 SCARG(uap, path), p); 1667 if ((error = namei(&nd)) != 0) 1668 return (error); 1669 error = vn_stat(nd.ni_vp, &sb, p); 1670 vput(nd.ni_vp); 1671 if (error) 1672 return (error); 1673 error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb)); 1674 return (error); 1675 } 1676 1677 /* 1678 * Get file status; this version does not follow links. 1679 */ 1680 #ifndef _SYS_SYSPROTO_H_ 1681 struct lstat_args { 1682 char *path; 1683 struct stat *ub; 1684 }; 1685 #endif 1686 /* ARGSUSED */ 1687 int 1688 lstat(p, uap) 1689 struct proc *p; 1690 register struct lstat_args /* { 1691 syscallarg(char *) path; 1692 syscallarg(struct stat *) ub; 1693 } */ *uap; 1694 { 1695 int error; 1696 struct vnode *vp; 1697 struct stat sb; 1698 struct nameidata nd; 1699 1700 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1701 SCARG(uap, path), p); 1702 if ((error = namei(&nd)) != 0) 1703 return (error); 1704 vp = nd.ni_vp; 1705 error = vn_stat(vp, &sb, p); 1706 vput(vp); 1707 if (error) 1708 return (error); 1709 error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb)); 1710 return (error); 1711 } 1712 1713 void 1714 cvtnstat(sb, nsb) 1715 struct stat *sb; 1716 struct nstat *nsb; 1717 { 1718 nsb->st_dev = sb->st_dev; 1719 nsb->st_ino = sb->st_ino; 1720 nsb->st_mode = sb->st_mode; 1721 nsb->st_nlink = sb->st_nlink; 1722 nsb->st_uid = sb->st_uid; 1723 nsb->st_gid = sb->st_gid; 1724 nsb->st_rdev = sb->st_rdev; 1725 nsb->st_atimespec = sb->st_atimespec; 1726 nsb->st_mtimespec = sb->st_mtimespec; 1727 nsb->st_ctimespec = sb->st_ctimespec; 1728 nsb->st_size = sb->st_size; 1729 nsb->st_blocks = sb->st_blocks; 1730 nsb->st_blksize = sb->st_blksize; 1731 nsb->st_flags = sb->st_flags; 1732 nsb->st_gen = sb->st_gen; 1733 } 1734 1735 #ifndef _SYS_SYSPROTO_H_ 1736 struct nstat_args { 1737 char *path; 1738 struct nstat *ub; 1739 }; 1740 #endif 1741 /* ARGSUSED */ 1742 int 1743 nstat(p, uap) 1744 struct proc *p; 1745 register struct nstat_args /* { 1746 syscallarg(char *) path; 1747 syscallarg(struct nstat *) ub; 1748 } */ *uap; 1749 { 1750 struct stat sb; 1751 struct nstat nsb; 1752 int error; 1753 struct nameidata nd; 1754 1755 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1756 SCARG(uap, path), p); 1757 if ((error = namei(&nd)) != 0) 1758 return (error); 1759 error = vn_stat(nd.ni_vp, &sb, p); 1760 vput(nd.ni_vp); 1761 if (error) 1762 return (error); 1763 cvtnstat(&sb, &nsb); 1764 error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb)); 1765 return (error); 1766 } 1767 1768 /* 1769 * Get file status; this version does not follow links. 1770 */ 1771 #ifndef _SYS_SYSPROTO_H_ 1772 struct lstat_args { 1773 char *path; 1774 struct stat *ub; 1775 }; 1776 #endif 1777 /* ARGSUSED */ 1778 int 1779 nlstat(p, uap) 1780 struct proc *p; 1781 register struct nlstat_args /* { 1782 syscallarg(char *) path; 1783 syscallarg(struct nstat *) ub; 1784 } */ *uap; 1785 { 1786 int error; 1787 struct vnode *vp; 1788 struct stat sb; 1789 struct nstat nsb; 1790 struct nameidata nd; 1791 1792 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1793 SCARG(uap, path), p); 1794 if ((error = namei(&nd)) != 0) 1795 return (error); 1796 vp = nd.ni_vp; 1797 error = vn_stat(vp, &sb, p); 1798 vput(vp); 1799 if (error) 1800 return (error); 1801 cvtnstat(&sb, &nsb); 1802 error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb)); 1803 return (error); 1804 } 1805 1806 /* 1807 * Get configurable pathname variables. 1808 */ 1809 #ifndef _SYS_SYSPROTO_H_ 1810 struct pathconf_args { 1811 char *path; 1812 int name; 1813 }; 1814 #endif 1815 /* ARGSUSED */ 1816 int 1817 pathconf(p, uap) 1818 struct proc *p; 1819 register struct pathconf_args /* { 1820 syscallarg(char *) path; 1821 syscallarg(int) name; 1822 } */ *uap; 1823 { 1824 int error; 1825 struct nameidata nd; 1826 1827 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1828 SCARG(uap, path), p); 1829 if ((error = namei(&nd)) != 0) 1830 return (error); 1831 error = VOP_PATHCONF(nd.ni_vp, SCARG(uap, name), p->p_retval); 1832 vput(nd.ni_vp); 1833 return (error); 1834 } 1835 1836 /* 1837 * Return target name of a symbolic link. 1838 */ 1839 #ifndef _SYS_SYSPROTO_H_ 1840 struct readlink_args { 1841 char *path; 1842 char *buf; 1843 int count; 1844 }; 1845 #endif 1846 /* ARGSUSED */ 1847 int 1848 readlink(p, uap) 1849 struct proc *p; 1850 register struct readlink_args /* { 1851 syscallarg(char *) path; 1852 syscallarg(char *) buf; 1853 syscallarg(int) count; 1854 } */ *uap; 1855 { 1856 register struct vnode *vp; 1857 struct iovec aiov; 1858 struct uio auio; 1859 int error; 1860 struct nameidata nd; 1861 1862 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1863 SCARG(uap, path), p); 1864 if ((error = namei(&nd)) != 0) 1865 return (error); 1866 vp = nd.ni_vp; 1867 if (vp->v_type != VLNK) 1868 error = EINVAL; 1869 else { 1870 aiov.iov_base = SCARG(uap, buf); 1871 aiov.iov_len = SCARG(uap, count); 1872 auio.uio_iov = &aiov; 1873 auio.uio_iovcnt = 1; 1874 auio.uio_offset = 0; 1875 auio.uio_rw = UIO_READ; 1876 auio.uio_segflg = UIO_USERSPACE; 1877 auio.uio_procp = p; 1878 auio.uio_resid = SCARG(uap, count); 1879 error = VOP_READLINK(vp, &auio, p->p_ucred); 1880 } 1881 vput(vp); 1882 p->p_retval[0] = SCARG(uap, count) - auio.uio_resid; 1883 return (error); 1884 } 1885 1886 static int 1887 setfflags(p, vp, flags) 1888 struct proc *p; 1889 struct vnode *vp; 1890 int flags; 1891 { 1892 int error; 1893 struct vattr vattr; 1894 1895 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 1896 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1897 VATTR_NULL(&vattr); 1898 vattr.va_flags = flags; 1899 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1900 VOP_UNLOCK(vp, 0, p); 1901 return error; 1902 } 1903 1904 /* 1905 * Change flags of a file given a path name. 1906 */ 1907 #ifndef _SYS_SYSPROTO_H_ 1908 struct chflags_args { 1909 char *path; 1910 int flags; 1911 }; 1912 #endif 1913 /* ARGSUSED */ 1914 int 1915 chflags(p, uap) 1916 struct proc *p; 1917 register struct chflags_args /* { 1918 syscallarg(char *) path; 1919 syscallarg(int) flags; 1920 } */ *uap; 1921 { 1922 int error; 1923 struct nameidata nd; 1924 1925 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 1926 if ((error = namei(&nd)) != 0) 1927 return (error); 1928 error = setfflags(p, nd.ni_vp, SCARG(uap, flags)); 1929 vrele(nd.ni_vp); 1930 return error; 1931 } 1932 1933 /* 1934 * Change flags of a file given a file descriptor. 1935 */ 1936 #ifndef _SYS_SYSPROTO_H_ 1937 struct fchflags_args { 1938 int fd; 1939 int flags; 1940 }; 1941 #endif 1942 /* ARGSUSED */ 1943 int 1944 fchflags(p, uap) 1945 struct proc *p; 1946 register struct fchflags_args /* { 1947 syscallarg(int) fd; 1948 syscallarg(int) flags; 1949 } */ *uap; 1950 { 1951 struct file *fp; 1952 int error; 1953 1954 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 1955 return (error); 1956 return setfflags(p, (struct vnode *) fp->f_data, SCARG(uap, flags)); 1957 } 1958 1959 static int 1960 setfmode(p, vp, mode) 1961 struct proc *p; 1962 struct vnode *vp; 1963 int mode; 1964 { 1965 int error; 1966 struct vattr vattr; 1967 1968 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 1969 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 1970 VATTR_NULL(&vattr); 1971 vattr.va_mode = mode & ALLPERMS; 1972 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 1973 VOP_UNLOCK(vp, 0, p); 1974 return error; 1975 } 1976 1977 /* 1978 * Change mode of a file given path name. 1979 */ 1980 #ifndef _SYS_SYSPROTO_H_ 1981 struct chmod_args { 1982 char *path; 1983 int mode; 1984 }; 1985 #endif 1986 /* ARGSUSED */ 1987 int 1988 chmod(p, uap) 1989 struct proc *p; 1990 register struct chmod_args /* { 1991 syscallarg(char *) path; 1992 syscallarg(int) mode; 1993 } */ *uap; 1994 { 1995 int error; 1996 struct nameidata nd; 1997 1998 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 1999 if ((error = namei(&nd)) != 0) 2000 return (error); 2001 error = setfmode(p, nd.ni_vp, SCARG(uap, mode)); 2002 vrele(nd.ni_vp); 2003 return error; 2004 } 2005 2006 /* 2007 * Change mode of a file given path name (don't follow links.) 2008 */ 2009 #ifndef _SYS_SYSPROTO_H_ 2010 struct lchmod_args { 2011 char *path; 2012 int mode; 2013 }; 2014 #endif 2015 /* ARGSUSED */ 2016 int 2017 lchmod(p, uap) 2018 struct proc *p; 2019 register struct lchmod_args /* { 2020 syscallarg(char *) path; 2021 syscallarg(int) mode; 2022 } */ *uap; 2023 { 2024 int error; 2025 struct nameidata nd; 2026 2027 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2028 if ((error = namei(&nd)) != 0) 2029 return (error); 2030 error = setfmode(p, nd.ni_vp, SCARG(uap, mode)); 2031 vrele(nd.ni_vp); 2032 return error; 2033 } 2034 2035 /* 2036 * Change mode of a file given a file descriptor. 2037 */ 2038 #ifndef _SYS_SYSPROTO_H_ 2039 struct fchmod_args { 2040 int fd; 2041 int mode; 2042 }; 2043 #endif 2044 /* ARGSUSED */ 2045 int 2046 fchmod(p, uap) 2047 struct proc *p; 2048 register struct fchmod_args /* { 2049 syscallarg(int) fd; 2050 syscallarg(int) mode; 2051 } */ *uap; 2052 { 2053 struct file *fp; 2054 int error; 2055 2056 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2057 return (error); 2058 return setfmode(p, (struct vnode *)fp->f_data, SCARG(uap, mode)); 2059 } 2060 2061 static int 2062 setfown(p, vp, uid, gid) 2063 struct proc *p; 2064 struct vnode *vp; 2065 uid_t uid; 2066 gid_t gid; 2067 { 2068 int error; 2069 struct vattr vattr; 2070 2071 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2072 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2073 VATTR_NULL(&vattr); 2074 vattr.va_uid = uid; 2075 vattr.va_gid = gid; 2076 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 2077 VOP_UNLOCK(vp, 0, p); 2078 return error; 2079 } 2080 2081 /* 2082 * Set ownership given a path name. 2083 */ 2084 #ifndef _SYS_SYSPROTO_H_ 2085 struct chown_args { 2086 char *path; 2087 int uid; 2088 int gid; 2089 }; 2090 #endif 2091 /* ARGSUSED */ 2092 int 2093 chown(p, uap) 2094 struct proc *p; 2095 register struct chown_args /* { 2096 syscallarg(char *) path; 2097 syscallarg(int) uid; 2098 syscallarg(int) gid; 2099 } */ *uap; 2100 { 2101 int error; 2102 struct nameidata nd; 2103 2104 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2105 if ((error = namei(&nd)) != 0) 2106 return (error); 2107 error = setfown(p, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid)); 2108 vrele(nd.ni_vp); 2109 2110 return (error); 2111 } 2112 2113 /* 2114 * Set ownership given a path name, do not cross symlinks. 2115 */ 2116 #ifndef _SYS_SYSPROTO_H_ 2117 struct lchown_args { 2118 char *path; 2119 int uid; 2120 int gid; 2121 }; 2122 #endif 2123 /* ARGSUSED */ 2124 int 2125 lchown(p, uap) 2126 struct proc *p; 2127 register struct lchown_args /* { 2128 syscallarg(char *) path; 2129 syscallarg(int) uid; 2130 syscallarg(int) gid; 2131 } */ *uap; 2132 { 2133 int error; 2134 struct nameidata nd; 2135 2136 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2137 if ((error = namei(&nd)) != 0) 2138 return (error); 2139 error = setfown(p, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid)); 2140 vrele(nd.ni_vp); 2141 return (error); 2142 } 2143 2144 /* 2145 * Set ownership given a file descriptor. 2146 */ 2147 #ifndef _SYS_SYSPROTO_H_ 2148 struct fchown_args { 2149 int fd; 2150 int uid; 2151 int gid; 2152 }; 2153 #endif 2154 /* ARGSUSED */ 2155 int 2156 fchown(p, uap) 2157 struct proc *p; 2158 register struct fchown_args /* { 2159 syscallarg(int) fd; 2160 syscallarg(int) uid; 2161 syscallarg(int) gid; 2162 } */ *uap; 2163 { 2164 struct file *fp; 2165 int error; 2166 2167 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2168 return (error); 2169 return setfown(p, (struct vnode *)fp->f_data, 2170 SCARG(uap, uid), SCARG(uap, gid)); 2171 } 2172 2173 static int 2174 setutimes(p, vp, tv, nullflag) 2175 struct proc *p; 2176 struct vnode *vp; 2177 struct timeval *tv; 2178 int nullflag; 2179 { 2180 int error; 2181 struct vattr vattr; 2182 2183 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2184 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2185 VATTR_NULL(&vattr); 2186 vattr.va_atime.tv_sec = tv[0].tv_sec; 2187 vattr.va_atime.tv_nsec = tv[0].tv_usec * 1000; 2188 vattr.va_mtime.tv_sec = tv[1].tv_sec; 2189 vattr.va_mtime.tv_nsec = tv[1].tv_usec * 1000; 2190 if (nullflag) 2191 vattr.va_vaflags |= VA_UTIMES_NULL; 2192 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 2193 VOP_UNLOCK(vp, 0, p); 2194 return error; 2195 } 2196 2197 /* 2198 * Set the access and modification times of a file. 2199 */ 2200 #ifndef _SYS_SYSPROTO_H_ 2201 struct utimes_args { 2202 char *path; 2203 struct timeval *tptr; 2204 }; 2205 #endif 2206 /* ARGSUSED */ 2207 int 2208 utimes(p, uap) 2209 struct proc *p; 2210 register struct utimes_args /* { 2211 syscallarg(char *) path; 2212 syscallarg(struct timeval *) tptr; 2213 } */ *uap; 2214 { 2215 struct timeval tv[2]; 2216 int error; 2217 struct nameidata nd; 2218 int nullflag; 2219 2220 nullflag = 0; 2221 if (SCARG(uap, tptr) == NULL) { 2222 microtime(&tv[0]); 2223 tv[1] = tv[0]; 2224 nullflag = 1; 2225 } else if ((error = copyin((caddr_t)SCARG(uap, tptr), (caddr_t)tv, 2226 sizeof (tv))) != 0) 2227 return (error); 2228 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2229 if ((error = namei(&nd)) != 0) 2230 return (error); 2231 error = setutimes(p, nd.ni_vp, tv, nullflag); 2232 vrele(nd.ni_vp); 2233 return (error); 2234 } 2235 2236 /* 2237 * Set the access and modification times of a file. 2238 */ 2239 #ifndef _SYS_SYSPROTO_H_ 2240 struct lutimes_args { 2241 char *path; 2242 struct timeval *tptr; 2243 }; 2244 #endif 2245 /* ARGSUSED */ 2246 int 2247 lutimes(p, uap) 2248 struct proc *p; 2249 register struct lutimes_args /* { 2250 syscallarg(char *) path; 2251 syscallarg(struct timeval *) tptr; 2252 } */ *uap; 2253 { 2254 struct timeval tv[2]; 2255 int error; 2256 struct nameidata nd; 2257 int nullflag; 2258 2259 nullflag = 0; 2260 if (SCARG(uap, tptr) == NULL) { 2261 microtime(&tv[0]); 2262 tv[1] = tv[0]; 2263 nullflag = 1; 2264 } else if ((error = copyin((caddr_t)SCARG(uap, tptr), (caddr_t)tv, 2265 sizeof (tv))) != 0) 2266 return (error); 2267 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2268 if ((error = namei(&nd)) != 0) 2269 return (error); 2270 2271 error = setutimes(p, nd.ni_vp, tv, nullflag); 2272 vrele(nd.ni_vp); 2273 return (error); 2274 } 2275 2276 /* 2277 * Set the access and modification times of a file. 2278 */ 2279 #ifndef _SYS_SYSPROTO_H_ 2280 struct futimes_args { 2281 int fd; 2282 struct timeval *tptr; 2283 }; 2284 #endif 2285 /* ARGSUSED */ 2286 int 2287 futimes(p, uap) 2288 struct proc *p; 2289 register struct futimes_args /* { 2290 syscallarg(int ) fd; 2291 syscallarg(struct timeval *) tptr; 2292 } */ *uap; 2293 { 2294 struct timeval tv[2]; 2295 struct file *fp; 2296 int error; 2297 int nullflag; 2298 2299 nullflag = 0; 2300 if (SCARG(uap, tptr) == NULL) { 2301 microtime(&tv[0]); 2302 tv[1] = tv[0]; 2303 nullflag = 1; 2304 } else if ((error = copyin((caddr_t)SCARG(uap, tptr), (caddr_t)tv, 2305 sizeof (tv))) != 0) 2306 return (error); 2307 2308 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2309 return (error); 2310 return setutimes(p, (struct vnode *)fp->f_data, tv, nullflag); 2311 } 2312 2313 /* 2314 * Truncate a file given its path name. 2315 */ 2316 #ifndef _SYS_SYSPROTO_H_ 2317 struct truncate_args { 2318 char *path; 2319 int pad; 2320 off_t length; 2321 }; 2322 #endif 2323 /* ARGSUSED */ 2324 int 2325 truncate(p, uap) 2326 struct proc *p; 2327 register struct truncate_args /* { 2328 syscallarg(char *) path; 2329 syscallarg(int) pad; 2330 syscallarg(off_t) length; 2331 } */ *uap; 2332 { 2333 register struct vnode *vp; 2334 struct vattr vattr; 2335 int error; 2336 struct nameidata nd; 2337 2338 if (uap->length < 0) 2339 return(EINVAL); 2340 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2341 if ((error = namei(&nd)) != 0) 2342 return (error); 2343 vp = nd.ni_vp; 2344 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2345 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2346 if (vp->v_type == VDIR) 2347 error = EISDIR; 2348 else if ((error = vn_writechk(vp)) == 0 && 2349 (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p)) == 0) { 2350 VATTR_NULL(&vattr); 2351 vattr.va_size = SCARG(uap, length); 2352 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p); 2353 } 2354 vput(vp); 2355 return (error); 2356 } 2357 2358 /* 2359 * Truncate a file given a file descriptor. 2360 */ 2361 #ifndef _SYS_SYSPROTO_H_ 2362 struct ftruncate_args { 2363 int fd; 2364 int pad; 2365 off_t length; 2366 }; 2367 #endif 2368 /* ARGSUSED */ 2369 int 2370 ftruncate(p, uap) 2371 struct proc *p; 2372 register struct ftruncate_args /* { 2373 syscallarg(int) fd; 2374 syscallarg(int) pad; 2375 syscallarg(off_t) length; 2376 } */ *uap; 2377 { 2378 struct vattr vattr; 2379 struct vnode *vp; 2380 struct file *fp; 2381 int error; 2382 2383 if (uap->length < 0) 2384 return(EINVAL); 2385 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2386 return (error); 2387 if ((fp->f_flag & FWRITE) == 0) 2388 return (EINVAL); 2389 vp = (struct vnode *)fp->f_data; 2390 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2391 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2392 if (vp->v_type == VDIR) 2393 error = EISDIR; 2394 else if ((error = vn_writechk(vp)) == 0) { 2395 VATTR_NULL(&vattr); 2396 vattr.va_size = SCARG(uap, length); 2397 error = VOP_SETATTR(vp, &vattr, fp->f_cred, p); 2398 } 2399 VOP_UNLOCK(vp, 0, p); 2400 return (error); 2401 } 2402 2403 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 2404 /* 2405 * Truncate a file given its path name. 2406 */ 2407 #ifndef _SYS_SYSPROTO_H_ 2408 struct otruncate_args { 2409 char *path; 2410 long length; 2411 }; 2412 #endif 2413 /* ARGSUSED */ 2414 int 2415 otruncate(p, uap) 2416 struct proc *p; 2417 register struct otruncate_args /* { 2418 syscallarg(char *) path; 2419 syscallarg(long) length; 2420 } */ *uap; 2421 { 2422 struct truncate_args /* { 2423 syscallarg(char *) path; 2424 syscallarg(int) pad; 2425 syscallarg(off_t) length; 2426 } */ nuap; 2427 2428 SCARG(&nuap, path) = SCARG(uap, path); 2429 SCARG(&nuap, length) = SCARG(uap, length); 2430 return (truncate(p, &nuap)); 2431 } 2432 2433 /* 2434 * Truncate a file given a file descriptor. 2435 */ 2436 #ifndef _SYS_SYSPROTO_H_ 2437 struct oftruncate_args { 2438 int fd; 2439 long length; 2440 }; 2441 #endif 2442 /* ARGSUSED */ 2443 int 2444 oftruncate(p, uap) 2445 struct proc *p; 2446 register struct oftruncate_args /* { 2447 syscallarg(int) fd; 2448 syscallarg(long) length; 2449 } */ *uap; 2450 { 2451 struct ftruncate_args /* { 2452 syscallarg(int) fd; 2453 syscallarg(int) pad; 2454 syscallarg(off_t) length; 2455 } */ nuap; 2456 2457 SCARG(&nuap, fd) = SCARG(uap, fd); 2458 SCARG(&nuap, length) = SCARG(uap, length); 2459 return (ftruncate(p, &nuap)); 2460 } 2461 #endif /* COMPAT_43 || COMPAT_SUNOS */ 2462 2463 /* 2464 * Sync an open file. 2465 */ 2466 #ifndef _SYS_SYSPROTO_H_ 2467 struct fsync_args { 2468 int fd; 2469 }; 2470 #endif 2471 /* ARGSUSED */ 2472 int 2473 fsync(p, uap) 2474 struct proc *p; 2475 struct fsync_args /* { 2476 syscallarg(int) fd; 2477 } */ *uap; 2478 { 2479 register struct vnode *vp; 2480 struct file *fp; 2481 int error; 2482 2483 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2484 return (error); 2485 vp = (struct vnode *)fp->f_data; 2486 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2487 if (vp->v_object) 2488 vm_object_page_clean(vp->v_object, 0, 0, 0); 2489 if ((error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p)) == 0 && 2490 vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP) && 2491 bioops.io_fsync) 2492 error = (*bioops.io_fsync)(vp); 2493 VOP_UNLOCK(vp, 0, p); 2494 return (error); 2495 } 2496 2497 /* 2498 * Rename files. Source and destination must either both be directories, 2499 * or both not be directories. If target is a directory, it must be empty. 2500 */ 2501 #ifndef _SYS_SYSPROTO_H_ 2502 struct rename_args { 2503 char *from; 2504 char *to; 2505 }; 2506 #endif 2507 /* ARGSUSED */ 2508 int 2509 rename(p, uap) 2510 struct proc *p; 2511 register struct rename_args /* { 2512 syscallarg(char *) from; 2513 syscallarg(char *) to; 2514 } */ *uap; 2515 { 2516 register struct vnode *tvp, *fvp, *tdvp; 2517 struct nameidata fromnd, tond; 2518 int error; 2519 2520 NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE, 2521 SCARG(uap, from), p); 2522 if ((error = namei(&fromnd)) != 0) 2523 return (error); 2524 fvp = fromnd.ni_vp; 2525 NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | NOOBJ, 2526 UIO_USERSPACE, SCARG(uap, to), p); 2527 if (fromnd.ni_vp->v_type == VDIR) 2528 tond.ni_cnd.cn_flags |= WILLBEDIR; 2529 if ((error = namei(&tond)) != 0) { 2530 /* Translate error code for rename("dir1", "dir2/."). */ 2531 if (error == EISDIR && fvp->v_type == VDIR) 2532 error = EINVAL; 2533 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd); 2534 vrele(fromnd.ni_dvp); 2535 vrele(fvp); 2536 goto out1; 2537 } 2538 tdvp = tond.ni_dvp; 2539 tvp = tond.ni_vp; 2540 if (tvp != NULL) { 2541 if (fvp->v_type == VDIR && tvp->v_type != VDIR) { 2542 error = ENOTDIR; 2543 goto out; 2544 } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { 2545 error = EISDIR; 2546 goto out; 2547 } 2548 } 2549 if (fvp == tdvp) 2550 error = EINVAL; 2551 /* 2552 * If source is the same as the destination (that is the 2553 * same inode number with the same name in the same directory), 2554 * then there is nothing to do. 2555 */ 2556 if (fvp == tvp && fromnd.ni_dvp == tdvp && 2557 fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen && 2558 !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr, 2559 fromnd.ni_cnd.cn_namelen)) 2560 error = -1; 2561 out: 2562 if (!error) { 2563 VOP_LEASE(tdvp, p, p->p_ucred, LEASE_WRITE); 2564 if (fromnd.ni_dvp != tdvp) { 2565 VOP_LEASE(fromnd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 2566 } 2567 if (tvp) { 2568 VOP_LEASE(tvp, p, p->p_ucred, LEASE_WRITE); 2569 } 2570 error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, 2571 tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); 2572 } else { 2573 VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd); 2574 if (tdvp == tvp) 2575 vrele(tdvp); 2576 else 2577 vput(tdvp); 2578 if (tvp) 2579 vput(tvp); 2580 VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd); 2581 vrele(fromnd.ni_dvp); 2582 vrele(fvp); 2583 } 2584 vrele(tond.ni_startdir); 2585 ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename"); 2586 ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename"); 2587 ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename"); 2588 ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename"); 2589 zfree(namei_zone, tond.ni_cnd.cn_pnbuf); 2590 out1: 2591 if (fromnd.ni_startdir) 2592 vrele(fromnd.ni_startdir); 2593 zfree(namei_zone, fromnd.ni_cnd.cn_pnbuf); 2594 if (error == -1) 2595 return (0); 2596 return (error); 2597 } 2598 2599 /* 2600 * Make a directory file. 2601 */ 2602 #ifndef _SYS_SYSPROTO_H_ 2603 struct mkdir_args { 2604 char *path; 2605 int mode; 2606 }; 2607 #endif 2608 /* ARGSUSED */ 2609 int 2610 mkdir(p, uap) 2611 struct proc *p; 2612 register struct mkdir_args /* { 2613 syscallarg(char *) path; 2614 syscallarg(int) mode; 2615 } */ *uap; 2616 { 2617 register struct vnode *vp; 2618 struct vattr vattr; 2619 int error; 2620 struct nameidata nd; 2621 2622 NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p); 2623 nd.ni_cnd.cn_flags |= WILLBEDIR; 2624 if ((error = namei(&nd)) != 0) 2625 return (error); 2626 vp = nd.ni_vp; 2627 if (vp != NULL) { 2628 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 2629 if (nd.ni_dvp == vp) 2630 vrele(nd.ni_dvp); 2631 else 2632 vput(nd.ni_dvp); 2633 vrele(vp); 2634 return (EEXIST); 2635 } 2636 VATTR_NULL(&vattr); 2637 vattr.va_type = VDIR; 2638 vattr.va_mode = (SCARG(uap, mode) & ACCESSPERMS) &~ p->p_fd->fd_cmask; 2639 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 2640 error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); 2641 vput(nd.ni_dvp); 2642 if (!error) 2643 vput(nd.ni_vp); 2644 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir"); 2645 ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir"); 2646 return (error); 2647 } 2648 2649 /* 2650 * Remove a directory file. 2651 */ 2652 #ifndef _SYS_SYSPROTO_H_ 2653 struct rmdir_args { 2654 char *path; 2655 }; 2656 #endif 2657 /* ARGSUSED */ 2658 int 2659 rmdir(p, uap) 2660 struct proc *p; 2661 struct rmdir_args /* { 2662 syscallarg(char *) path; 2663 } */ *uap; 2664 { 2665 register struct vnode *vp; 2666 int error; 2667 struct nameidata nd; 2668 2669 NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE, 2670 SCARG(uap, path), p); 2671 if ((error = namei(&nd)) != 0) 2672 return (error); 2673 vp = nd.ni_vp; 2674 if (vp->v_type != VDIR) { 2675 error = ENOTDIR; 2676 goto out; 2677 } 2678 /* 2679 * No rmdir "." please. 2680 */ 2681 if (nd.ni_dvp == vp) { 2682 error = EINVAL; 2683 goto out; 2684 } 2685 /* 2686 * The root of a mounted filesystem cannot be deleted. 2687 */ 2688 if (vp->v_flag & VROOT) 2689 error = EBUSY; 2690 out: 2691 if (!error) { 2692 VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); 2693 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE); 2694 error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); 2695 } else { 2696 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); 2697 } 2698 if (nd.ni_dvp == vp) 2699 vrele(nd.ni_dvp); 2700 else 2701 vput(nd.ni_dvp); 2702 if (vp != NULLVP) 2703 vput(vp); 2704 ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir"); 2705 ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir"); 2706 return (error); 2707 } 2708 2709 #ifdef COMPAT_43 2710 /* 2711 * Read a block of directory entries in a file system independent format. 2712 */ 2713 #ifndef _SYS_SYSPROTO_H_ 2714 struct ogetdirentries_args { 2715 int fd; 2716 char *buf; 2717 u_int count; 2718 long *basep; 2719 }; 2720 #endif 2721 int 2722 ogetdirentries(p, uap) 2723 struct proc *p; 2724 register struct ogetdirentries_args /* { 2725 syscallarg(int) fd; 2726 syscallarg(char *) buf; 2727 syscallarg(u_int) count; 2728 syscallarg(long *) basep; 2729 } */ *uap; 2730 { 2731 struct vnode *vp; 2732 struct file *fp; 2733 struct uio auio, kuio; 2734 struct iovec aiov, kiov; 2735 struct dirent *dp, *edp; 2736 caddr_t dirbuf; 2737 int error, eofflag, readcnt; 2738 long loff; 2739 2740 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2741 return (error); 2742 if ((fp->f_flag & FREAD) == 0) 2743 return (EBADF); 2744 vp = (struct vnode *)fp->f_data; 2745 unionread: 2746 if (vp->v_type != VDIR) 2747 return (EINVAL); 2748 aiov.iov_base = SCARG(uap, buf); 2749 aiov.iov_len = SCARG(uap, count); 2750 auio.uio_iov = &aiov; 2751 auio.uio_iovcnt = 1; 2752 auio.uio_rw = UIO_READ; 2753 auio.uio_segflg = UIO_USERSPACE; 2754 auio.uio_procp = p; 2755 auio.uio_resid = SCARG(uap, count); 2756 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2757 loff = auio.uio_offset = fp->f_offset; 2758 # if (BYTE_ORDER != LITTLE_ENDIAN) 2759 if (vp->v_mount->mnt_maxsymlinklen <= 0) { 2760 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 2761 NULL, NULL); 2762 fp->f_offset = auio.uio_offset; 2763 } else 2764 # endif 2765 { 2766 kuio = auio; 2767 kuio.uio_iov = &kiov; 2768 kuio.uio_segflg = UIO_SYSSPACE; 2769 kiov.iov_len = SCARG(uap, count); 2770 MALLOC(dirbuf, caddr_t, SCARG(uap, count), M_TEMP, M_WAITOK); 2771 kiov.iov_base = dirbuf; 2772 error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag, 2773 NULL, NULL); 2774 fp->f_offset = kuio.uio_offset; 2775 if (error == 0) { 2776 readcnt = SCARG(uap, count) - kuio.uio_resid; 2777 edp = (struct dirent *)&dirbuf[readcnt]; 2778 for (dp = (struct dirent *)dirbuf; dp < edp; ) { 2779 # if (BYTE_ORDER == LITTLE_ENDIAN) 2780 /* 2781 * The expected low byte of 2782 * dp->d_namlen is our dp->d_type. 2783 * The high MBZ byte of dp->d_namlen 2784 * is our dp->d_namlen. 2785 */ 2786 dp->d_type = dp->d_namlen; 2787 dp->d_namlen = 0; 2788 # else 2789 /* 2790 * The dp->d_type is the high byte 2791 * of the expected dp->d_namlen, 2792 * so must be zero'ed. 2793 */ 2794 dp->d_type = 0; 2795 # endif 2796 if (dp->d_reclen > 0) { 2797 dp = (struct dirent *) 2798 ((char *)dp + dp->d_reclen); 2799 } else { 2800 error = EIO; 2801 break; 2802 } 2803 } 2804 if (dp >= edp) 2805 error = uiomove(dirbuf, readcnt, &auio); 2806 } 2807 FREE(dirbuf, M_TEMP); 2808 } 2809 VOP_UNLOCK(vp, 0, p); 2810 if (error) 2811 return (error); 2812 if (SCARG(uap, count) == auio.uio_resid) { 2813 if (union_dircheckp) { 2814 error = union_dircheckp(p, &vp, fp); 2815 if (error == -1) 2816 goto unionread; 2817 if (error) 2818 return (error); 2819 } 2820 if ((vp->v_flag & VROOT) && 2821 (vp->v_mount->mnt_flag & MNT_UNION)) { 2822 struct vnode *tvp = vp; 2823 vp = vp->v_mount->mnt_vnodecovered; 2824 VREF(vp); 2825 fp->f_data = (caddr_t) vp; 2826 fp->f_offset = 0; 2827 vrele(tvp); 2828 goto unionread; 2829 } 2830 } 2831 error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), 2832 sizeof(long)); 2833 p->p_retval[0] = SCARG(uap, count) - auio.uio_resid; 2834 return (error); 2835 } 2836 #endif /* COMPAT_43 */ 2837 2838 /* 2839 * Read a block of directory entries in a file system independent format. 2840 */ 2841 #ifndef _SYS_SYSPROTO_H_ 2842 struct getdirentries_args { 2843 int fd; 2844 char *buf; 2845 u_int count; 2846 long *basep; 2847 }; 2848 #endif 2849 int 2850 getdirentries(p, uap) 2851 struct proc *p; 2852 register struct getdirentries_args /* { 2853 syscallarg(int) fd; 2854 syscallarg(char *) buf; 2855 syscallarg(u_int) count; 2856 syscallarg(long *) basep; 2857 } */ *uap; 2858 { 2859 struct vnode *vp; 2860 struct file *fp; 2861 struct uio auio; 2862 struct iovec aiov; 2863 long loff; 2864 int error, eofflag; 2865 2866 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) 2867 return (error); 2868 if ((fp->f_flag & FREAD) == 0) 2869 return (EBADF); 2870 vp = (struct vnode *)fp->f_data; 2871 unionread: 2872 if (vp->v_type != VDIR) 2873 return (EINVAL); 2874 aiov.iov_base = SCARG(uap, buf); 2875 aiov.iov_len = SCARG(uap, count); 2876 auio.uio_iov = &aiov; 2877 auio.uio_iovcnt = 1; 2878 auio.uio_rw = UIO_READ; 2879 auio.uio_segflg = UIO_USERSPACE; 2880 auio.uio_procp = p; 2881 auio.uio_resid = SCARG(uap, count); 2882 /* vn_lock(vp, LK_SHARED | LK_RETRY, p); */ 2883 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2884 loff = auio.uio_offset = fp->f_offset; 2885 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL); 2886 fp->f_offset = auio.uio_offset; 2887 VOP_UNLOCK(vp, 0, p); 2888 if (error) 2889 return (error); 2890 if (SCARG(uap, count) == auio.uio_resid) { 2891 if (union_dircheckp) { 2892 error = union_dircheckp(p, &vp, fp); 2893 if (error == -1) 2894 goto unionread; 2895 if (error) 2896 return (error); 2897 } 2898 if ((vp->v_flag & VROOT) && 2899 (vp->v_mount->mnt_flag & MNT_UNION)) { 2900 struct vnode *tvp = vp; 2901 vp = vp->v_mount->mnt_vnodecovered; 2902 VREF(vp); 2903 fp->f_data = (caddr_t) vp; 2904 fp->f_offset = 0; 2905 vrele(tvp); 2906 goto unionread; 2907 } 2908 } 2909 if (SCARG(uap, basep) != NULL) { 2910 error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), 2911 sizeof(long)); 2912 } 2913 p->p_retval[0] = SCARG(uap, count) - auio.uio_resid; 2914 return (error); 2915 } 2916 #ifndef _SYS_SYSPROTO_H_ 2917 struct getdents_args { 2918 int fd; 2919 char *buf; 2920 size_t count; 2921 }; 2922 #endif 2923 int 2924 getdents(p, uap) 2925 struct proc *p; 2926 register struct getdents_args /* { 2927 syscallarg(int) fd; 2928 syscallarg(char *) buf; 2929 syscallarg(u_int) count; 2930 } */ *uap; 2931 { 2932 struct getdirentries_args ap; 2933 ap.fd = uap->fd; 2934 ap.buf = uap->buf; 2935 ap.count = uap->count; 2936 ap.basep = NULL; 2937 return getdirentries(p, &ap); 2938 } 2939 2940 /* 2941 * Set the mode mask for creation of filesystem nodes. 2942 */ 2943 #ifndef _SYS_SYSPROTO_H_ 2944 struct umask_args { 2945 int newmask; 2946 }; 2947 #endif 2948 int 2949 umask(p, uap) 2950 struct proc *p; 2951 struct umask_args /* { 2952 syscallarg(int) newmask; 2953 } */ *uap; 2954 { 2955 register struct filedesc *fdp; 2956 2957 fdp = p->p_fd; 2958 p->p_retval[0] = fdp->fd_cmask; 2959 fdp->fd_cmask = SCARG(uap, newmask) & ALLPERMS; 2960 return (0); 2961 } 2962 2963 /* 2964 * Void all references to file by ripping underlying filesystem 2965 * away from vnode. 2966 */ 2967 #ifndef _SYS_SYSPROTO_H_ 2968 struct revoke_args { 2969 char *path; 2970 }; 2971 #endif 2972 /* ARGSUSED */ 2973 int 2974 revoke(p, uap) 2975 struct proc *p; 2976 register struct revoke_args /* { 2977 syscallarg(char *) path; 2978 } */ *uap; 2979 { 2980 register struct vnode *vp; 2981 struct vattr vattr; 2982 int error; 2983 struct nameidata nd; 2984 2985 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); 2986 if ((error = namei(&nd)) != 0) 2987 return (error); 2988 vp = nd.ni_vp; 2989 if (vp->v_type != VCHR && vp->v_type != VBLK) { 2990 error = EINVAL; 2991 goto out; 2992 } 2993 if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0) 2994 goto out; 2995 if (p->p_ucred->cr_uid != vattr.va_uid && 2996 (error = suser_xxx(0, p, PRISON_ROOT))) 2997 goto out; 2998 if (vp->v_usecount > 1 || (vp->v_flag & VALIASED)) 2999 VOP_REVOKE(vp, REVOKEALL); 3000 out: 3001 vrele(vp); 3002 return (error); 3003 } 3004 3005 /* 3006 * Convert a user file descriptor to a kernel file entry. 3007 */ 3008 int 3009 getvnode(fdp, fd, fpp) 3010 struct filedesc *fdp; 3011 int fd; 3012 struct file **fpp; 3013 { 3014 struct file *fp; 3015 3016 if ((u_int)fd >= fdp->fd_nfiles || 3017 (fp = fdp->fd_ofiles[fd]) == NULL) 3018 return (EBADF); 3019 if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO) 3020 return (EINVAL); 3021 *fpp = fp; 3022 return (0); 3023 } 3024 #ifndef _SYS_SYSPROTO_H_ 3025 struct __getcwd_args { 3026 u_char *buf; 3027 u_int buflen; 3028 }; 3029 #endif 3030 3031 SYSCTL_DECL(_vfs_cache); 3032 #define STATNODE(mode, name, var) \ 3033 SYSCTL_INT(_vfs_cache, OID_AUTO, name, mode, var, 0, ""); 3034 3035 static int disablecwd; 3036 SYSCTL_INT(_debug, OID_AUTO, disablecwd, CTLFLAG_RW, &disablecwd, 0, ""); 3037 3038 static u_long numcwdcalls; STATNODE(CTLFLAG_RD, numcwdcalls, &numcwdcalls); 3039 static u_long numcwdfail1; STATNODE(CTLFLAG_RD, numcwdfail1, &numcwdfail1); 3040 static u_long numcwdfail2; STATNODE(CTLFLAG_RD, numcwdfail2, &numcwdfail2); 3041 static u_long numcwdfail3; STATNODE(CTLFLAG_RD, numcwdfail3, &numcwdfail3); 3042 static u_long numcwdfail4; STATNODE(CTLFLAG_RD, numcwdfail4, &numcwdfail4); 3043 static u_long numcwdfound; STATNODE(CTLFLAG_RD, numcwdfound, &numcwdfound); 3044 int 3045 __getcwd(p, uap) 3046 struct proc *p; 3047 struct __getcwd_args *uap; 3048 { 3049 char *bp, *buf; 3050 int error, i, slash_prefixed; 3051 struct filedesc *fdp; 3052 struct namecache *ncp; 3053 struct vnode *vp; 3054 3055 numcwdcalls++; 3056 if (disablecwd) 3057 return (ENODEV); 3058 if (uap->buflen < 2) 3059 return (EINVAL); 3060 if (uap->buflen > MAXPATHLEN) 3061 uap->buflen = MAXPATHLEN; 3062 buf = bp = malloc(uap->buflen, M_TEMP, M_WAITOK); 3063 bp += uap->buflen - 1; 3064 *bp = '\0'; 3065 fdp = p->p_fd; 3066 slash_prefixed = 0; 3067 for (vp = fdp->fd_cdir; vp != fdp->fd_rdir && vp != rootvnode;) { 3068 if (vp->v_flag & VROOT) { 3069 vp = vp->v_mount->mnt_vnodecovered; 3070 continue; 3071 } 3072 if (vp->v_dd->v_id != vp->v_ddid) { 3073 numcwdfail1++; 3074 free(buf, M_TEMP); 3075 return (ENOTDIR); 3076 } 3077 ncp = TAILQ_FIRST(&vp->v_cache_dst); 3078 if (!ncp) { 3079 numcwdfail2++; 3080 free(buf, M_TEMP); 3081 return (ENOENT); 3082 } 3083 if (ncp->nc_dvp != vp->v_dd) { 3084 numcwdfail3++; 3085 free(buf, M_TEMP); 3086 return (EBADF); 3087 } 3088 for (i = ncp->nc_nlen - 1; i >= 0; i--) { 3089 if (bp == buf) { 3090 numcwdfail4++; 3091 free(buf, M_TEMP); 3092 return (ENOMEM); 3093 } 3094 *--bp = ncp->nc_name[i]; 3095 } 3096 if (bp == buf) { 3097 numcwdfail4++; 3098 free(buf, M_TEMP); 3099 return (ENOMEM); 3100 } 3101 *--bp = '/'; 3102 slash_prefixed = 1; 3103 vp = vp->v_dd; 3104 } 3105 if (!slash_prefixed) { 3106 if (bp == buf) { 3107 numcwdfail4++; 3108 free(buf, M_TEMP); 3109 return (ENOMEM); 3110 } 3111 *--bp = '/'; 3112 } 3113 numcwdfound++; 3114 error = copyout(bp, uap->buf, strlen(bp) + 1); 3115 free(buf, M_TEMP); 3116 return (error); 3117 } 3118