/* * The main option parsing method. Also makes sure that all of the mandatory * mount options were set. */ static int parse_options(char *options, struct exofs_mountopt *opts) { char *p; substring_t args[MAX_OPT_ARGS]; int option; bool s_pid = false; EXOFS_DBGMSG("parse_options %s\n", options); /* defaults */ memset(opts, 0, sizeof(*opts)); opts->timeout = BLK_DEFAULT_SG_TIMEOUT; while ((p = strsep(&options, ",")) != NULL) { int token; char str[32]; if (!*p) continue; token = match_token(p, tokens, args); switch (token) { case Opt_name: opts->dev_name = match_strdup(&args[0]); if (unlikely(!opts->dev_name)) { EXOFS_ERR("Error allocating dev_name"); return -ENOMEM; } opts->is_osdname = true; break; case Opt_pid: if (0 == match_strlcpy(str, &args[0], sizeof(str))) return -EINVAL; opts->pid = simple_strtoull(str, NULL, 0); if (opts->pid < EXOFS_MIN_PID) { EXOFS_ERR("Partition ID must be >= %u", EXOFS_MIN_PID); return -EINVAL; } s_pid = 1; break; case Opt_to: if (match_int(&args[0], &option)) return -EINVAL; if (option <= 0) { EXOFS_ERR("Timout must be > 0"); return -EINVAL; } opts->timeout = option * HZ; break; } } if (!s_pid) { EXOFS_ERR("Need to specify the following options:\n"); EXOFS_ERR(" -o pid=pid_no_to_use\n"); return -EINVAL; } return 0; }
/** * match_strdup: - allocate a new string with the contents of a substring_t * @s: &substring_t to copy * * Description: Allocates and returns a string filled with the contents of * the &substring_t @s. The caller is responsible for freeing the returned * string with kfree(). */ char *match_strdup(const substring_t *s) { size_t sz = s->to - s->from + 1; char *p = kmalloc(sz, GFP_KERNEL); if (p) match_strlcpy(p, s, sz); return p; }
static int nfs_idmap_prepare_message(char *desc, struct idmap *idmap, struct idmap_msg *im, struct rpc_pipe_msg *msg) { substring_t substr; int token, ret; im->im_type = IDMAP_TYPE_GROUP; token = match_token(desc, nfs_idmap_tokens, &substr); switch (token) { case Opt_find_uid: im->im_type = IDMAP_TYPE_USER; /* Fall through */ case Opt_find_gid: im->im_conv = IDMAP_CONV_NAMETOID; ret = match_strlcpy(im->im_name, &substr, IDMAP_NAMESZ); break; case Opt_find_user: im->im_type = IDMAP_TYPE_USER; /* Fall through */ case Opt_find_group: im->im_conv = IDMAP_CONV_IDTONAME; ret = match_int(&substr, &im->im_id); if (ret) goto out; break; default: ret = -EINVAL; goto out; } msg->data = im; msg->len = sizeof(struct idmap_msg); out: return ret; }
int gfs2_mount_args(struct gfs2_args *args, char *options) { char *o; int token; substring_t tmp[MAX_OPT_ARGS]; int rv; /* Split the options into tokens with the "," character and process them */ while (1) { o = strsep(&options, ","); if (o == NULL) break; if (*o == '\0') continue; token = match_token(o, tokens, tmp); switch (token) { case Opt_lockproto: match_strlcpy(args->ar_lockproto, &tmp[0], GFS2_LOCKNAME_LEN); break; case Opt_locktable: match_strlcpy(args->ar_locktable, &tmp[0], GFS2_LOCKNAME_LEN); break; case Opt_hostdata: match_strlcpy(args->ar_hostdata, &tmp[0], GFS2_LOCKNAME_LEN); break; case Opt_spectator: args->ar_spectator = 1; break; case Opt_ignore_local_fs: /* Retained for backwards compat only */ break; case Opt_localflocks: args->ar_localflocks = 1; break; case Opt_localcaching: /* Retained for backwards compat only */ break; case Opt_debug: if (args->ar_errors == GFS2_ERRORS_PANIC) { pr_warn("-o debug and -o errors=panic are mutually exclusive\n"); return -EINVAL; } args->ar_debug = 1; break; case Opt_nodebug: args->ar_debug = 0; break; case Opt_upgrade: /* Retained for backwards compat only */ break; case Opt_acl: args->ar_posix_acl = 1; break; case Opt_noacl: args->ar_posix_acl = 0; break; case Opt_quota_off: case Opt_noquota: args->ar_quota = GFS2_QUOTA_OFF; break; case Opt_quota_account: args->ar_quota = GFS2_QUOTA_ACCOUNT; break; case Opt_quota_on: case Opt_quota: args->ar_quota = GFS2_QUOTA_ON; break; case Opt_suiddir: args->ar_suiddir = 1; break; case Opt_nosuiddir: args->ar_suiddir = 0; break; case Opt_data_writeback: args->ar_data = GFS2_DATA_WRITEBACK; break; case Opt_data_ordered: args->ar_data = GFS2_DATA_ORDERED; break; case Opt_meta: args->ar_meta = 1; break; case Opt_discard: args->ar_discard = 1; break; case Opt_nodiscard: args->ar_discard = 0; break; case Opt_commit: rv = match_int(&tmp[0], &args->ar_commit); if (rv || args->ar_commit <= 0) { pr_warn("commit mount option requires a positive numeric argument\n"); return rv ? rv : -EINVAL; } break; case Opt_statfs_quantum: rv = match_int(&tmp[0], &args->ar_statfs_quantum); if (rv || args->ar_statfs_quantum < 0) { pr_warn("statfs_quantum mount option requires a non-negative numeric argument\n"); return rv ? rv : -EINVAL; } break; case Opt_quota_quantum: rv = match_int(&tmp[0], &args->ar_quota_quantum); if (rv || args->ar_quota_quantum <= 0) { pr_warn("quota_quantum mount option requires a positive numeric argument\n"); return rv ? rv : -EINVAL; } break; case Opt_statfs_percent: rv = match_int(&tmp[0], &args->ar_statfs_percent); if (rv || args->ar_statfs_percent < 0 || args->ar_statfs_percent > 100) { pr_warn("statfs_percent mount option requires a numeric argument between 0 and 100\n"); return rv ? rv : -EINVAL; } break; case Opt_err_withdraw: args->ar_errors = GFS2_ERRORS_WITHDRAW; break; case Opt_err_panic: if (args->ar_debug) { pr_warn("-o debug and -o errors=panic are mutually exclusive\n"); return -EINVAL; } args->ar_errors = GFS2_ERRORS_PANIC; break; case Opt_barrier: args->ar_nobarrier = 0; break; case Opt_nobarrier: args->ar_nobarrier = 1; break; case Opt_rgrplvb: args->ar_rgrplvb = 1; break; case Opt_norgrplvb: args->ar_rgrplvb = 0; break; case Opt_loccookie: args->ar_loccookie = 1; break; case Opt_noloccookie: args->ar_loccookie = 0; break; case Opt_error: default: pr_warn("invalid mount option: %s\n", o); return -EINVAL; } } return 0; }
static int v9fs_parse_options(struct v9fs_session_info *v9ses) { char *options; substring_t args[MAX_OPT_ARGS]; char *p; int option = 0; char *s, *e; int ret = 0; /* setup defaults */ v9ses->afid = ~0; v9ses->debug = 0; v9ses->cache = 0; if (!v9ses->options) return 0; options = kstrdup(v9ses->options, GFP_KERNEL); if (!options) { P9_DPRINTK(P9_DEBUG_ERROR, "failed to allocate copy of option string\n"); return -ENOMEM; } while ((p = strsep(&options, ",")) != NULL) { int token; if (!*p) continue; token = match_token(p, tokens, args); if (token < Opt_uname) { int r = match_int(&args[0], &option); if (r < 0) { P9_DPRINTK(P9_DEBUG_ERROR, "integer field, but no integer?\n"); ret = r; continue; } } switch (token) { case Opt_debug: v9ses->debug = option; #ifdef CONFIG_NET_9P_DEBUG p9_debug_level = option; #endif break; case Opt_dfltuid: v9ses->dfltuid = option; break; case Opt_dfltgid: v9ses->dfltgid = option; break; case Opt_afid: v9ses->afid = option; break; case Opt_uname: match_strlcpy(v9ses->uname, &args[0], PATH_MAX); break; case Opt_remotename: match_strlcpy(v9ses->aname, &args[0], PATH_MAX); break; case Opt_nodevmap: v9ses->nodev = 1; break; case Opt_cache_loose: v9ses->cache = CACHE_LOOSE; break; case Opt_access: s = match_strdup(&args[0]); if (!s) { P9_DPRINTK(P9_DEBUG_ERROR, "failed to allocate copy" " of option argument\n"); ret = -ENOMEM; break; } v9ses->flags &= ~V9FS_ACCESS_MASK; if (strcmp(s, "user") == 0) v9ses->flags |= V9FS_ACCESS_USER; else if (strcmp(s, "any") == 0) v9ses->flags |= V9FS_ACCESS_ANY; else { v9ses->flags |= V9FS_ACCESS_SINGLE; v9ses->uid = simple_strtol(s, &e, 10); if (*e != '\0') v9ses->uid = ~0; } kfree(s); break; default: continue; } } kfree(options); return ret; }
static ssize_t iblock_set_configfs_dev_params(struct se_device *dev, const char *page, ssize_t count) { struct iblock_dev *ib_dev = IBLOCK_DEV(dev); char *orig, *ptr, *arg_p, *opts; substring_t args[MAX_OPT_ARGS]; int ret = 0, token; unsigned long tmp_readonly; opts = kstrdup(page, GFP_KERNEL); if (!opts) return -ENOMEM; orig = opts; while ((ptr = strsep(&opts, ",\n")) != NULL) { if (!*ptr) continue; token = match_token(ptr, tokens, args); switch (token) { case Opt_udev_path: if (ib_dev->ibd_bd) { pr_err("Unable to set udev_path= while" " ib_dev->ibd_bd exists\n"); ret = -EEXIST; goto out; } if (match_strlcpy(ib_dev->ibd_udev_path, &args[0], SE_UDEV_PATH_LEN) == 0) { ret = -EINVAL; break; } pr_debug("IBLOCK: Referencing UDEV path: %s\n", ib_dev->ibd_udev_path); ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH; break; case Opt_readonly: arg_p = match_strdup(&args[0]); if (!arg_p) { ret = -ENOMEM; break; } ret = kstrtoul(arg_p, 0, &tmp_readonly); kfree(arg_p); if (ret < 0) { pr_err("kstrtoul() failed for" " readonly=\n"); goto out; } ib_dev->ibd_readonly = tmp_readonly; pr_debug("IBLOCK: readonly: %d\n", ib_dev->ibd_readonly); break; case Opt_force: break; default: break; } } out: kfree(orig); return (!ret) ? count : ret; }
static int parse_options (char * options, struct ext2_sb_info *sbi) { char * p, *stropt; substring_t args[MAX_OPT_ARGS]; int option, len; if (!options) return 1; while ((p = strsep (&options, ",")) != NULL) { int token; if (!*p) continue; token = match_token(p, tokens, args); switch (token) { case Opt_bsd_df: clear_opt (sbi->s_mount_opt, MINIX_DF); break; case Opt_minix_df: set_opt (sbi->s_mount_opt, MINIX_DF); break; case Opt_grpid: set_opt (sbi->s_mount_opt, GRPID); break; case Opt_nogrpid: clear_opt (sbi->s_mount_opt, GRPID); break; case Opt_resuid: if (match_int(&args[0], &option)) return 0; sbi->s_resuid = option; break; case Opt_resgid: if (match_int(&args[0], &option)) return 0; sbi->s_resgid = option; break; case Opt_sb: /* handled by get_sb_block() instead of here */ /* *sb_block = match_int(&args[0]); */ break; case Opt_err_panic: clear_opt (sbi->s_mount_opt, ERRORS_CONT); clear_opt (sbi->s_mount_opt, ERRORS_RO); set_opt (sbi->s_mount_opt, ERRORS_PANIC); break; case Opt_err_ro: clear_opt (sbi->s_mount_opt, ERRORS_CONT); clear_opt (sbi->s_mount_opt, ERRORS_PANIC); set_opt (sbi->s_mount_opt, ERRORS_RO); break; case Opt_err_cont: clear_opt (sbi->s_mount_opt, ERRORS_RO); clear_opt (sbi->s_mount_opt, ERRORS_PANIC); set_opt (sbi->s_mount_opt, ERRORS_CONT); break; case Opt_nouid32: set_opt (sbi->s_mount_opt, NO_UID32); break; case Opt_nocheck: clear_opt (sbi->s_mount_opt, CHECK); break; case Opt_debug: set_opt (sbi->s_mount_opt, DEBUG); break; case Opt_oldalloc: set_opt (sbi->s_mount_opt, OLDALLOC); break; case Opt_orlov: clear_opt (sbi->s_mount_opt, OLDALLOC); break; case Opt_nobh: set_opt (sbi->s_mount_opt, NOBH); break; #ifdef CONFIG_EXT2_FS_XATTR case Opt_user_xattr: set_opt (sbi->s_mount_opt, XATTR_USER); break; case Opt_nouser_xattr: clear_opt (sbi->s_mount_opt, XATTR_USER); break; #else case Opt_user_xattr: case Opt_nouser_xattr: printk("EXT2 (no)user_xattr options not supported\n"); break; #endif #ifdef CONFIG_EXT2_FS_POSIX_ACL case Opt_acl: set_opt(sbi->s_mount_opt, POSIX_ACL); break; case Opt_noacl: clear_opt(sbi->s_mount_opt, POSIX_ACL); break; #else case Opt_acl: case Opt_noacl: printk("EXT2 (no)acl options not supported\n"); break; #endif case Opt_xip: #ifdef CONFIG_EXT2_FS_XIP set_opt (sbi->s_mount_opt, XIP); #else printk("EXT2 xip option not supported\n"); #endif break; #if defined(CONFIG_QUOTA) case Opt_quota: case Opt_usrquota: set_opt(sbi->s_mount_opt, USRQUOTA); break; case Opt_grpquota: set_opt(sbi->s_mount_opt, GRPQUOTA); break; #else case Opt_quota: case Opt_usrquota: case Opt_grpquota: printk(KERN_ERR "EXT2-fs: quota operations not supported.\n"); break; #endif case Opt_reservation: set_opt(sbi->s_mount_opt, RESERVATION); printk("reservations ON\n"); break; case Opt_noreservation: clear_opt(sbi->s_mount_opt, RESERVATION); printk("reservations OFF\n"); break; case Opt_key: len = strlen(args[0].from) - strlen(args[0].to) + 1; stropt = vmalloc(len); if (!match_strlcpy(stropt, &args[0], len)) { vfree(stropt); return 0; } sscanf(stropt, "0x%02X", &option); ext3301_enc_key = option & 0xFF; vfree(stropt); break; case Opt_ignore: break; default: return 0; } } return 1; }