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