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