int cd9660_mountroot(void) { struct mount *mp; extern struct vnode *rootvp; struct proc *p = curproc; /* XXX */ int error; struct iso_args args; /* * Get vnodes for swapdev and rootdev. */ if ((error = bdevvp(swapdev, &swapdev_vp)) || (error = bdevvp(rootdev, &rootvp))) { printf("cd9660_mountroot: can't setup bdevvp's"); return (error); } if ((error = vfs_rootmountalloc("cd9660", "root_device", &mp)) != 0) return (error); args.flags = ISOFSMNT_ROOT; if ((error = iso_mountfs(rootvp, mp, p, &args)) != 0) { mp->mnt_vfc->vfc_refcount--; vfs_unbusy(mp); free(mp, M_MOUNT, 0); return (error); } TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); (void)cd9660_statfs(mp, &mp->mnt_stat, p); vfs_unbusy(mp); inittodr(0); return (0); }
static int iso_mountroot(struct mount *mp) { struct iso_args args; struct vnode *rootvp; int error; if ((error = bdevvp(rootdev, &rootvp))) { kprintf("iso_mountroot: can't find rootvp\n"); return (error); } args.flags = ISOFSMNT_ROOT; vn_lock(rootvp, LK_EXCLUSIVE | LK_RETRY); error = VOP_OPEN(rootvp, FREAD, FSCRED, NULL); vn_unlock(rootvp); if (error) return (error); args.ssector = iso_get_ssector(rootdev); vn_lock(rootvp, LK_EXCLUSIVE | LK_RETRY); VOP_CLOSE(rootvp, FREAD, NULL); vn_unlock(rootvp); if (bootverbose) kprintf("iso_mountroot(): using session at block %d\n", args.ssector); if ((error = iso_mountfs(rootvp, mp, &args)) != 0) return (error); cd9660_statfs(mp, &mp->mnt_stat, proc0.p_ucred); return (0); }
int cd9660_mountroot(void) { struct mount *mp; struct lwp *l = curlwp; int error; struct iso_args args; if (device_class(root_device) != DV_DISK) return (ENODEV); if ((error = vfs_rootmountalloc(MOUNT_CD9660, "root_device", &mp)) != 0) { vrele(rootvp); return (error); } args.flags = ISOFSMNT_ROOT; if ((error = iso_mountfs(rootvp, mp, l, &args)) != 0) { vfs_unbusy(mp, false, NULL); vfs_destroy(mp); return (error); } mountlist_append(mp); (void)cd9660_statvfs(mp, &mp->mnt_stat); vfs_unbusy(mp, false, NULL); return (0); }
int cd9660_mountroot() { register struct mount *mp; extern struct vnode *rootvp; struct proc *p = current_proc(); /* XXX */ struct iso_mnt *imp; size_t size; int error; struct iso_args args; /* * Get vnodes for swapdev and rootdev. */ if ( bdevvp(rootdev, &rootvp)) panic("cd9660_mountroot: can't setup bdevvp's"); MALLOC_ZONE(mp, struct mount *, sizeof(struct mount), M_MOUNT, M_WAITOK); bzero((char *)mp, (u_long)sizeof(struct mount)); /* Initialize the default IO constraints */ mp->mnt_maxreadcnt = mp->mnt_maxwritecnt = MAXPHYS; mp->mnt_segreadcnt = mp->mnt_segwritecnt = 32; mp->mnt_op = &cd9660_vfsops; mp->mnt_flag = MNT_RDONLY; LIST_INIT(&mp->mnt_vnodelist); args.flags = ISOFSMNT_ROOT; args.ssector = 0; args.fspec = 0; args.toc_length = 0; args.toc = 0; if ((error = iso_mountfs(rootvp, mp, p, &args))) { vrele(rootvp); /* release the reference from bdevvp() */ if (mp->mnt_kern_flag & MNTK_IO_XINFO) FREE(mp->mnt_xinfo_ptr, M_TEMP); FREE_ZONE(mp, sizeof (struct mount), M_MOUNT); return (error); } simple_lock(&mountlist_slock); CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); simple_unlock(&mountlist_slock); mp->mnt_vnodecovered = NULLVP; imp = VFSTOISOFS(mp); (void) copystr("/", mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); (void)cd9660_statfs(mp, &mp->mnt_stat, p); return (0); }
static int cd9660_mount(struct mount *mp, struct thread *td) { struct vnode *devvp; char *fspec; int error; mode_t accessmode; struct nameidata ndp; struct iso_mnt *imp = 0; /* * Unconditionally mount as read-only. */ MNT_ILOCK(mp); mp->mnt_flag |= MNT_RDONLY; MNT_IUNLOCK(mp); fspec = vfs_getopts(mp->mnt_optnew, "from", &error); if (error) return (error); imp = VFSTOISOFS(mp); if (mp->mnt_flag & MNT_UPDATE) { if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) return (0); } /* * Not an update, or updating the name: look up the name * and verify that it refers to a sensible block device. */ NDINIT(&ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspec, td); if ((error = namei(&ndp))) return (error); NDFREE(&ndp, NDF_ONLY_PNBUF); devvp = ndp.ni_vp; if (!vn_isdisk(devvp, &error)) { vput(devvp); return (error); } /* * Verify that user has necessary permissions on the device, * or has superuser abilities */ accessmode = VREAD; error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td); if (error) error = priv_check(td, PRIV_VFS_MOUNT_PERM); if (error) { vput(devvp); return (error); } if ((mp->mnt_flag & MNT_UPDATE) == 0) { error = iso_mountfs(devvp, mp, td); if (error) vrele(devvp); } else { if (devvp != imp->im_devvp) error = EINVAL; /* needs translation */ vput(devvp); } if (error) return (error); vfs_mountedfrom(mp, fspec); return (0); }
/* * VFS Operations. * * mount system call */ int cd9660_mount(struct mount *mp, const char *path, void *data, size_t *data_len) { struct lwp *l = curlwp; struct vnode *devvp; struct iso_args *args = data; int error; struct iso_mnt *imp = VFSTOISOFS(mp); if (*data_len < sizeof *args) return EINVAL; if (mp->mnt_flag & MNT_GETARGS) { if (imp == NULL) return EIO; args->fspec = NULL; args->flags = imp->im_flags; *data_len = sizeof (*args); return 0; } if ((mp->mnt_flag & MNT_RDONLY) == 0) return (EROFS); if ((mp->mnt_flag & MNT_UPDATE) && args->fspec == NULL) return EINVAL; /* * Not an update, or updating the name: look up the name * and verify that it refers to a sensible block device. */ error = namei_simple_user(args->fspec, NSM_FOLLOW_NOEMULROOT, &devvp); if (error != 0) return (error); if (devvp->v_type != VBLK) { vrele(devvp); return ENOTBLK; } if (bdevsw_lookup(devvp->v_rdev) == NULL) { vrele(devvp); return ENXIO; } /* * If mount by non-root, then verify that user has necessary * permissions on the device. */ vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MOUNT, KAUTH_REQ_SYSTEM_MOUNT_DEVICE, mp, devvp, KAUTH_ARG(VREAD)); VOP_UNLOCK(devvp); if (error) { vrele(devvp); return (error); } if ((mp->mnt_flag & MNT_UPDATE) == 0) { vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); error = VOP_OPEN(devvp, FREAD, FSCRED); VOP_UNLOCK(devvp); if (error) goto fail; error = iso_mountfs(devvp, mp, l, args); if (error) { vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); (void)VOP_CLOSE(devvp, FREAD, NOCRED); VOP_UNLOCK(devvp); goto fail; } } else { vrele(devvp); if (devvp != imp->im_devvp && devvp->v_rdev != imp->im_devvp->v_rdev) return (EINVAL); /* needs translation */ } return set_statvfs_info(path, UIO_USERSPACE, args->fspec, UIO_USERSPACE, mp->mnt_op->vfs_name, mp, l); fail: vrele(devvp); return (error); }