コード例 #1
0
static void
parse_int(struct mount *mp, const char *opt, int *val, int *error)
{
	char *tmp, *ep;

	tmp = vfs_getopts(mp->mnt_optnew, opt, error);
	if (*error != 0) {
		return;
	}
	if (tmp != NULL) {
		*val = (int)strtol(tmp, &ep, 10);
		if (*ep) {
			*error = EINVAL;
			return;
		}
	}
}
コード例 #2
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);
}
コード例 #3
0
ファイル: coda_vfsops.c プロジェクト: dcui/FreeBSD-9.3_kernel
/*ARGSUSED*/
int
coda_mount(struct mount *vfsp)
{
	struct vnode *dvp;
	struct cnode *cp;
	struct cdev *dev;
	struct coda_mntinfo *mi;
	struct vnode *rootvp;
	struct CodaFid rootfid = INVAL_FID;
	struct CodaFid ctlfid = CTL_FID;
	int error;
	struct nameidata ndp;
	ENTRY;
	char *from;

	if (vfs_filteropt(vfsp->mnt_optnew, coda_opts))
		return (EINVAL);
	from = vfs_getopts(vfsp->mnt_optnew, "from", &error);
	if (error)
		return (error);
	coda_vfsopstats_init();
	coda_vnodeopstats_init();
	MARK_ENTRY(CODA_MOUNT_STATS);
	if (CODA_MOUNTED(vfsp)) {
		MARK_INT_FAIL(CODA_MOUNT_STATS);
		return (EBUSY);
	}

	/*
	 * Validate mount device.  Similar to getmdev().
	 */
	NDINIT(&ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, from, curthread);
	error = namei(&ndp);
	dvp = ndp.ni_vp;
	if (error) {
		MARK_INT_FAIL(CODA_MOUNT_STATS);
		return (error);
	}
	if (dvp->v_type != VCHR) {
		MARK_INT_FAIL(CODA_MOUNT_STATS);
		vrele(dvp);
		NDFREE(&ndp, NDF_ONLY_PNBUF);
		return (ENXIO);
	}
	dev = dvp->v_rdev;
	vrele(dvp);
	NDFREE(&ndp, NDF_ONLY_PNBUF);

	/*
	 * Initialize the mount record and link it to the vfs struct.
	 */
	mi = dev2coda_mntinfo(dev);
	if (!mi) {
		MARK_INT_FAIL(CODA_MOUNT_STATS);
		printf("Coda mount: %s is not a cfs device\n", from);
		return (ENXIO);
	}
	if (!VC_OPEN(&mi->mi_vcomm)) {
		MARK_INT_FAIL(CODA_MOUNT_STATS);
		return (ENODEV);
	}

	/*
	 * No initialization (here) of mi_vcomm!
	 */
	vfsp->mnt_data = mi;
	vfs_getnewfsid (vfsp);
	mi->mi_vfsp = vfsp;
	mi->mi_started = 0;			/* XXX See coda_root() */

	/*
	 * Make a root vnode to placate the Vnode interface, but don't
	 * actually make the CODA_ROOT call to venus until the first call to
	 * coda_root in case a server is down while venus is starting.
	 */
	cp = make_coda_node(&rootfid, vfsp, VDIR);
	rootvp = CTOV(cp);
	rootvp->v_vflag |= VV_ROOT;
	cp = make_coda_node(&ctlfid, vfsp, VREG);
	coda_ctlvp = CTOV(cp);

	/*
	 * Add vfs and rootvp to chain of vfs hanging off mntinfo.
	 */
	mi->mi_vfsp = vfsp;
	mi->mi_rootvp = rootvp;
	vfs_mountedfrom(vfsp, from);

	/*
	 * Error is currently guaranteed to be zero, but in case some code
	 * changes...
	 */
	CODADEBUG(1, myprintf(("coda_mount returned %d\n", error)););
コード例 #4
0
ファイル: ntfs_vfsops.c プロジェクト: vkhromov/freebsd
static int
ntfs_mount(struct mount *mp)
{
	int err = 0, error;
	struct vnode *devvp;
	struct nameidata ndp;
	struct thread *td;
	char *from;

	td = curthread;
	if (vfs_filteropt(mp->mnt_optnew, ntfs_opts))
		return (EINVAL);

	/* Force mount as read-only. */
	MNT_ILOCK(mp);
	mp->mnt_flag |= MNT_RDONLY;
	MNT_IUNLOCK(mp);

	from = vfs_getopts(mp->mnt_optnew, "from", &error);
	if (error)	
		return (error);

	/*
	 * If updating, check whether changing from read-only to
	 * read/write.
	 */
	if (mp->mnt_flag & MNT_UPDATE) {
		if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) {
			/* Process export requests in vfs_mount.c */
			return (0);
		} else {
			printf("ntfs_mount(): MNT_UPDATE not supported\n");
			return (EINVAL);
		}
	}

	/*
	 * 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, from, td);
	err = namei(&ndp);
	if (err)
		return (err);
	NDFREE(&ndp, NDF_ONLY_PNBUF);
	devvp = ndp.ni_vp;

	if (!vn_isdisk(devvp, &err))  {
		vput(devvp);
		return (err);
	}

	/*
	 * If mount by non-root, then verify that user has necessary
	 * permissions on the device.
	 */
	err = VOP_ACCESS(devvp, VREAD, td->td_ucred, td);
	if (err)
		err = priv_check(td, PRIV_VFS_MOUNT_PERM);
	if (err) {
		vput(devvp);
		return (err);
	}


	/*
	 * Since this is a new mount, we want the names for the device and
	 * the mount point copied in.  If an error occurs, the mountpoint is
	 * discarded by the upper level code.  Note that vfs_mount() handles
	 * copying the mountpoint f_mntonname for us, so we don't have to do
	 * it here unless we want to set it to something other than "path"
	 * for some rason.
	 */

	err = ntfs_mountfs(devvp, mp, td);
	if (err == 0) {

		/* Save "mounted from" info for mount point. */
		vfs_mountedfrom(mp, from);
	} else
		vrele(devvp);
	return (err);
}
コード例 #5
0
static int
_xfs_param_copyin(struct mount *mp, struct thread *td)
{
	struct xfsmount *xmp = MNTTOXFS(mp);
	struct xfs_mount_args *args = &xmp->m_args;
	char *path;
	char *fsname;
	char *rtname;
	char *logname;
	int error;

	path = vfs_getopts(mp->mnt_optnew, "fspath", &error);
	if  (error)
		return (error);

	bzero(args, sizeof(struct xfs_mount_args));
	args->logbufs = -1;
	args->logbufsize = -1;

	parse_int(mp, "flags", &args->flags, &error);
	if (error != 0 && error != ENOENT)
		return error;

	args->flags |= XFSMNT_32BITINODES;

	parse_int(mp, "sunit", &args->sunit, &error);
	if (error != 0 && error != ENOENT)
		return error;

	parse_int(mp, "swidth", &args->swidth, &error);
	if (error != 0 && error != ENOENT)
		return error;

	parse_int(mp, "logbufs", &args->logbufs, &error);
	if (error != 0 && error != ENOENT)
		return error;

	parse_int(mp, "logbufsize", &args->logbufsize, &error);
	if (error != 0 && error != ENOENT)
		return error;

	fsname = vfs_getopts(mp->mnt_optnew, "from", &error);
	if (error == 0 && fsname != NULL) {
		strncpy(args->fsname, fsname, sizeof(args->fsname) - 1);
	}

	logname = vfs_getopts(mp->mnt_optnew, "logname", &error);
	if (error == 0 && logname != NULL) {
		strncpy(args->logname, logname, sizeof(args->logname) - 1);
	}

	rtname = vfs_getopts(mp->mnt_optnew, "rtname", &error);
	if (error == 0 && rtname != NULL) {
		strncpy(args->rtname, rtname, sizeof(args->rtname) - 1);
	}

	strncpy(args->mtpt, path, sizeof(args->mtpt));

	printf("fsname '%s' logname '%s' rtname '%s'\n"
	       "flags 0x%x sunit %d swidth %d logbufs %d logbufsize %d\n",
	       args->fsname, args->logname, args->rtname, args->flags,
	       args->sunit, args->swidth, args->logbufs, args->logbufsize);

	vfs_mountedfrom(mp, args->fsname);

	return (0);
}
コード例 #6
0
static int
fuse_vfsop_mount(struct mount *mp)
{
	int err;

	uint64_t mntopts, __mntopts;
	int max_read_set;
	uint32_t max_read;
	int daemon_timeout;
	int fd;

	size_t len;

	struct cdev *fdev;
	struct fuse_data *data;
	struct thread *td;
	struct file *fp, *fptmp;
	char *fspec, *subtype;
	struct vfsoptlist *opts;

	subtype = NULL;
	max_read_set = 0;
	max_read = ~0;
	err = 0;
	mntopts = 0;
	__mntopts = 0;
	td = curthread;

	fuse_trace_printf_vfsop();

	if (mp->mnt_flag & MNT_UPDATE)
		return EOPNOTSUPP;

	mp->mnt_flag |= MNT_SYNCHRONOUS;
	mp->mnt_data = NULL;
	/* Get the new options passed to mount */
	opts = mp->mnt_optnew;

	if (!opts)
		return EINVAL;

	/* `fspath' contains the mount point (eg. /mnt/fuse/sshfs); REQUIRED */
	if (!vfs_getopts(opts, "fspath", &err))
		return err;

	/* `from' contains the device name (eg. /dev/fuse0); REQUIRED */
	fspec = vfs_getopts(opts, "from", &err);
	if (!fspec)
		return err;

	/* `fd' contains the filedescriptor for this session; REQUIRED */
	if (vfs_scanopt(opts, "fd", "%d", &fd) != 1)
		return EINVAL;

	err = fuse_getdevice(fspec, td, &fdev);
	if (err != 0)
		return err;

	/*
         * With the help of underscored options the mount program
         * can inform us from the flags it sets by default
         */
	FUSE_FLAGOPT(allow_other, FSESS_DAEMON_CAN_SPY);
	FUSE_FLAGOPT(push_symlinks_in, FSESS_PUSH_SYMLINKS_IN);
	FUSE_FLAGOPT(default_permissions, FSESS_DEFAULT_PERMISSIONS);
	FUSE_FLAGOPT(no_attrcache, FSESS_NO_ATTRCACHE);
	FUSE_FLAGOPT(no_readahed, FSESS_NO_READAHEAD);
	FUSE_FLAGOPT(no_datacache, FSESS_NO_DATACACHE);
	FUSE_FLAGOPT(no_namecache, FSESS_NO_NAMECACHE);
	FUSE_FLAGOPT(no_mmap, FSESS_NO_MMAP);
	FUSE_FLAGOPT(brokenio, FSESS_BROKENIO);

	if (vfs_scanopt(opts, "max_read=", "%u", &max_read) == 1)
		max_read_set = 1;
	if (vfs_scanopt(opts, "timeout=", "%u", &daemon_timeout) == 1) {
		if (daemon_timeout < FUSE_MIN_DAEMON_TIMEOUT)
			daemon_timeout = FUSE_MIN_DAEMON_TIMEOUT;
		else if (daemon_timeout > FUSE_MAX_DAEMON_TIMEOUT)
			daemon_timeout = FUSE_MAX_DAEMON_TIMEOUT;
	} else {
		daemon_timeout = FUSE_DEFAULT_DAEMON_TIMEOUT;
	}
	subtype = vfs_getopts(opts, "subtype=", &err);

	FS_DEBUG2G("mntopts 0x%jx\n", (uintmax_t)mntopts);

	err = fget(td, fd, CAP_READ, &fp);
	if (err != 0) {
		FS_DEBUG("invalid or not opened device: data=%p\n", data);
		goto out;
	}
	fptmp = td->td_fpop;
	td->td_fpop = fp;
        err = devfs_get_cdevpriv((void **)&data);
	td->td_fpop = fptmp;
	fdrop(fp, td);
	FUSE_LOCK();
	if (err != 0 || data == NULL || data->mp != NULL) {
		FS_DEBUG("invalid or not opened device: data=%p data.mp=%p\n",
		    data, data != NULL ? data->mp : NULL);
		err = ENXIO;
		FUSE_UNLOCK();
		goto out;
	}
	if (fdata_get_dead(data)) {
		FS_DEBUG("device is dead during mount: data=%p\n", data);
		err = ENOTCONN;
		FUSE_UNLOCK();
		goto out;
	}
	/* Sanity + permission checks */
	if (!data->daemoncred)
		panic("fuse daemon found, but identity unknown");
	if (mntopts & FSESS_DAEMON_CAN_SPY)
		err = priv_check(td, PRIV_VFS_FUSE_ALLOWOTHER);
	if (err == 0 && td->td_ucred->cr_uid != data->daemoncred->cr_uid)
		/* are we allowed to do the first mount? */
		err = priv_check(td, PRIV_VFS_FUSE_MOUNT_NONUSER);
	if (err) {
		FUSE_UNLOCK();
		goto out;
	}
	/* We need this here as this slot is used by getnewvnode() */
	mp->mnt_stat.f_iosize = PAGE_SIZE;
	mp->mnt_data = data;
	data->ref++;
	data->mp = mp;
	data->dataflags |= mntopts;
	data->max_read = max_read;
	data->daemon_timeout = daemon_timeout;
#ifdef XXXIP
	if (!priv_check(td, PRIV_VFS_FUSE_SYNC_UNMOUNT))
		data->dataflags |= FSESS_CAN_SYNC_UNMOUNT;
#endif
	FUSE_UNLOCK();

	vfs_getnewfsid(mp);
	mp->mnt_flag |= MNT_LOCAL;
	mp->mnt_kern_flag |= MNTK_MPSAFE;
	if (subtype) {
		strlcat(mp->mnt_stat.f_fstypename, ".", MFSNAMELEN);
		strlcat(mp->mnt_stat.f_fstypename, subtype, MFSNAMELEN);
	}
	copystr(fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &len);
	bzero(mp->mnt_stat.f_mntfromname + len, MNAMELEN - len);
	FS_DEBUG2G("mp %p: %s\n", mp, mp->mnt_stat.f_mntfromname);

	/* Now handshaking with daemon */
	fuse_internal_send_init(data, td);

out:
	if (err) {
		FUSE_LOCK();
		if (data->mp == mp) {
			/*
			 * Destroy device only if we acquired reference to
			 * it
			 */
			FS_DEBUG("mount failed, destroy device: data=%p mp=%p"
			      " err=%d\n",
			    data, mp, err);
			data->mp = NULL;
			fdata_trydestroy(data);
		}
		FUSE_UNLOCK();
		dev_rel(fdev);
	}
	return err;
}