/* * 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); }
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)); }
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)); }
void zfs_sb_free(zfs_sb_t *zsb) { int i; zfs_fuid_destroy(zsb); mutex_destroy(&zsb->z_znodes_lock); mutex_destroy(&zsb->z_lock); list_destroy(&zsb->z_all_znodes); rrm_destroy(&zsb->z_teardown_lock); rw_destroy(&zsb->z_teardown_inactive_lock); rw_destroy(&zsb->z_fuid_lock); for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) mutex_destroy(&zsb->z_hold_mtx[i]); vmem_free(zsb->z_hold_mtx, sizeof (kmutex_t) * ZFS_OBJ_MTX_SZ); zfs_mntopts_free(zsb->z_mntopts); kmem_free(zsb, sizeof (zfs_sb_t)); }
void zfs_sb_free(zfs_sb_t *zsb) { int i, size = zsb->z_hold_size; zfs_fuid_destroy(zsb); mutex_destroy(&zsb->z_znodes_lock); mutex_destroy(&zsb->z_lock); list_destroy(&zsb->z_all_znodes); rrm_destroy(&zsb->z_teardown_lock); rw_destroy(&zsb->z_teardown_inactive_lock); rw_destroy(&zsb->z_fuid_lock); for (i = 0; i != size; i++) { avl_destroy(&zsb->z_hold_trees[i]); mutex_destroy(&zsb->z_hold_locks[i]); } vmem_free(zsb->z_hold_trees, sizeof (avl_tree_t) * size); vmem_free(zsb->z_hold_locks, sizeof (kmutex_t) * size); zfs_mntopts_free(zsb->z_mntopts); kmem_free(zsb, sizeof (zfs_sb_t)); }