コード例 #1
0
ファイル: zpl_super.c プロジェクト: koplover/zfs
/*
 * Parse the mntopts string storing the results in provided zmo argument.
 * If an error occurs the zmo argument will not be modified.  The caller
 * needs to set isremount when recycling an existing zfs_mntopts_t.
 */
static int
zpl_parse_options(char *osname, char *mntopts, zfs_mntopts_t *zmo,
                  boolean_t isremount)
{
    zfs_mntopts_t *tmp_zmo;
    int error;

    tmp_zmo = zfs_mntopts_alloc();
    tmp_zmo->z_osname = strdup(osname);

    if (mntopts) {
        substring_t args[MAX_OPT_ARGS];
        char *tmp_mntopts, *p;
        int token;

        tmp_mntopts = strdup(mntopts);

        while ((p = strsep(&tmp_mntopts, ",")) != NULL) {
            if (!*p)
                continue;

            args[0].to = args[0].from = NULL;
            token = match_token(p, zpl_tokens, args);
            error = zpl_parse_option(p, token, args, tmp_zmo);
            if (error) {
                zfs_mntopts_free(tmp_zmo);
                strfree(tmp_mntopts);
                return (error);
            }
        }

        strfree(tmp_mntopts);
    }

    if (isremount == B_TRUE) {
        if (zmo->z_osname)
            strfree(zmo->z_osname);

        if (zmo->z_mntpoint)
            strfree(zmo->z_mntpoint);
    } else {
        ASSERT3P(zmo->z_osname, ==, NULL);
        ASSERT3P(zmo->z_mntpoint, ==, NULL);
    }

    memcpy(zmo, tmp_zmo, sizeof (zfs_mntopts_t));
    kmem_free(tmp_zmo, sizeof (zfs_mntopts_t));

    return (0);
}
コード例 #2
0
ファイル: zpl_super.c プロジェクト: koplover/zfs
static int
zpl_get_sb(struct file_system_type *fs_type, int flags,
           const char *osname, void *data, struct vfsmount *mnt)
{
    zfs_mntopts_t *zmo = zfs_mntopts_alloc();
    int error;

    error = zpl_parse_options((char *)osname, (char *)data, zmo, B_FALSE);
    if (error) {
        zfs_mntopts_free(zmo);
        return (error);
    }

    return (get_sb_nodev(fs_type, flags, zmo, zpl_fill_super, mnt));
}
コード例 #3
0
ファイル: zpl_super.c プロジェクト: koplover/zfs
static struct dentry *
zpl_mount(struct file_system_type *fs_type, int flags,
          const char *osname, void *data)
{
    zfs_mntopts_t *zmo = zfs_mntopts_alloc();
    int error;

    error = zpl_parse_options((char *)osname, (char *)data, zmo, B_FALSE);
    if (error) {
        zfs_mntopts_free(zmo);
        return (ERR_PTR(error));
    }

    return (mount_nodev(fs_type, flags, zmo, zpl_fill_super));
}
コード例 #4
0
ファイル: zfs_vfsops.c プロジェクト: nwf/zfs
int
zfs_sb_create(const char *osname, zfs_mntopts_t *zmo, zfs_sb_t **zsbp)
{
	objset_t *os;
	zfs_sb_t *zsb;
	uint64_t zval;
	int i, error;
	uint64_t sa_obj;

	zsb = kmem_zalloc(sizeof (zfs_sb_t), KM_SLEEP);

	/*
	 * We claim to always be readonly so we can open snapshots;
	 * other ZPL code will prevent us from writing to snapshots.
	 */
	error = dmu_objset_own(osname, DMU_OST_ZFS, B_TRUE, zsb, &os);
	if (error) {
		kmem_free(zsb, sizeof (zfs_sb_t));
		return (error);
	}

	/*
	 * Optional temporary mount options, free'd in zfs_sb_free().
	 */
	zsb->z_mntopts = (zmo ? zmo : zfs_mntopts_alloc());

	/*
	 * Initialize the zfs-specific filesystem structure.
	 * Should probably make this a kmem cache, shuffle fields,
	 * and just bzero up to z_hold_mtx[].
	 */
	zsb->z_sb = NULL;
	zsb->z_parent = zsb;
	zsb->z_max_blksz = SPA_OLD_MAXBLOCKSIZE;
	zsb->z_show_ctldir = ZFS_SNAPDIR_VISIBLE;
	zsb->z_os = os;

	error = zfs_get_zplprop(os, ZFS_PROP_VERSION, &zsb->z_version);
	if (error) {
		goto out;
	} else if (zsb->z_version > ZPL_VERSION) {
		error = SET_ERROR(ENOTSUP);
		goto out;
	}
	if ((error = zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &zval)) != 0)
		goto out;
	zsb->z_norm = (int)zval;

	if ((error = zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &zval)) != 0)
		goto out;
	zsb->z_utf8 = (zval != 0);

	if ((error = zfs_get_zplprop(os, ZFS_PROP_CASE, &zval)) != 0)
		goto out;
	zsb->z_case = (uint_t)zval;

	if ((error = zfs_get_zplprop(os, ZFS_PROP_ACLTYPE, &zval)) != 0)
		goto out;
	zsb->z_acl_type = (uint_t)zval;

	/*
	 * Fold case on file systems that are always or sometimes case
	 * insensitive.
	 */
	if (zsb->z_case == ZFS_CASE_INSENSITIVE ||
	    zsb->z_case == ZFS_CASE_MIXED)
		zsb->z_norm |= U8_TEXTPREP_TOUPPER;

	zsb->z_use_fuids = USE_FUIDS(zsb->z_version, zsb->z_os);
	zsb->z_use_sa = USE_SA(zsb->z_version, zsb->z_os);

	if (zsb->z_use_sa) {
		/* should either have both of these objects or none */
		error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_SA_ATTRS, 8, 1,
		    &sa_obj);
		if (error)
			goto out;

		error = zfs_get_zplprop(os, ZFS_PROP_XATTR, &zval);
		if ((error == 0) && (zval == ZFS_XATTR_SA))
			zsb->z_xattr_sa = B_TRUE;
	} else {
		/*
		 * Pre SA versions file systems should never touch
		 * either the attribute registration or layout objects.
		 */
		sa_obj = 0;
	}

	error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END,
	    &zsb->z_attr_table);
	if (error)
		goto out;

	if (zsb->z_version >= ZPL_VERSION_SA)
		sa_register_update_callback(os, zfs_sa_upgrade);

	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1,
	    &zsb->z_root);
	if (error)
		goto out;
	ASSERT(zsb->z_root != 0);

	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_UNLINKED_SET, 8, 1,
	    &zsb->z_unlinkedobj);
	if (error)
		goto out;

	error = zap_lookup(os, MASTER_NODE_OBJ,
	    zfs_userquota_prop_prefixes[ZFS_PROP_USERQUOTA],
	    8, 1, &zsb->z_userquota_obj);
	if (error && error != ENOENT)
		goto out;

	error = zap_lookup(os, MASTER_NODE_OBJ,
	    zfs_userquota_prop_prefixes[ZFS_PROP_GROUPQUOTA],
	    8, 1, &zsb->z_groupquota_obj);
	if (error && error != ENOENT)
		goto out;

	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_FUID_TABLES, 8, 1,
	    &zsb->z_fuid_obj);
	if (error && error != ENOENT)
		goto out;

	error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_SHARES_DIR, 8, 1,
	    &zsb->z_shares_dir);
	if (error && error != ENOENT)
		goto out;

	mutex_init(&zsb->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
	mutex_init(&zsb->z_lock, NULL, MUTEX_DEFAULT, NULL);
	list_create(&zsb->z_all_znodes, sizeof (znode_t),
	    offsetof(znode_t, z_link_node));
	rrm_init(&zsb->z_teardown_lock, B_FALSE);
	rw_init(&zsb->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL);
	rw_init(&zsb->z_fuid_lock, NULL, RW_DEFAULT, NULL);

	zsb->z_hold_mtx = vmem_zalloc(sizeof (kmutex_t) * ZFS_OBJ_MTX_SZ,
	    KM_SLEEP);
	for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
		mutex_init(&zsb->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);

	*zsbp = zsb;
	return (0);

out:
	dmu_objset_disown(os, zsb);
	*zsbp = NULL;

	vmem_free(zsb->z_hold_mtx, sizeof (kmutex_t) * ZFS_OBJ_MTX_SZ);
	kmem_free(zsb, sizeof (zfs_sb_t));
	return (error);
}