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