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