#include <linux/init.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
+#include <linux/parser.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
sb->s_fs_info = NULL;
}
+enum {Opt_uid, Opt_gid, Opt_ownmask, Opt_othmask, Opt_err};
+
+static match_table_t tokens = {
+ {Opt_uid, "uid=%u"},
+ {Opt_gid, "gid=%u"},
+ {Opt_ownmask, "ownmask=%o"},
+ {Opt_othmask, "othmask=%o"},
+ {Opt_err, NULL}
+};
+
static int parse_options(struct super_block *sb, char *options)
{
- char *value, *opt;
+ char *p;
struct adfs_sb_info *asb = ADFS_SB(sb);
+ int option;
if (!options)
return 0;
- while ((opt = strsep(&options, ",")) != NULL) {
- if (!*opt)
+ while ((p = strsep(&options, ",")) != NULL) {
+ substring_t args[MAX_OPT_ARGS];
+ int token;
+ if (!*p)
continue;
- value = strchr(opt, '=');
- if (value)
- *value++ = '\0';
- if (!strcmp(opt, "uid")) { /* owner of all files */
- if (!value || !*value)
- return -EINVAL;
- asb->s_uid = simple_strtoul(value, &value, 0);
- if (*value)
- return -EINVAL;
- } else
- if (!strcmp(opt, "gid")) { /* group owner of all files */
- if (!value || !*value)
- return -EINVAL;
- asb->s_gid = simple_strtoul(value, &value, 0);
- if (*value)
- return -EINVAL;
- } else
- if (!strcmp(opt, "ownmask")) { /* owner permission mask */
- if (!value || !*value)
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_uid:
+ if (match_int(args, &option))
return -EINVAL;
- asb->s_owner_mask = simple_strtoul(value, &value, 8);
- if (*value)
+ asb->s_uid = option;
+ break;
+ case Opt_gid:
+ if (match_int(args, &option))
return -EINVAL;
- } else
- if (!strcmp(opt, "othmask")) { /* others permission mask */
- if (!value || !*value)
+ asb->s_gid = option;
+ break;
+ case Opt_ownmask:
+ if (match_octal(args, &option))
return -EINVAL;
- asb->s_other_mask = simple_strtoul(value, &value, 8);
- if (*value)
+ asb->s_owner_mask = option;
+ break;
+ case Opt_othmask:
+ if (match_octal(args, &option))
return -EINVAL;
- } else { /* eh? say again. */
- printk("ADFS-fs: unrecognised mount option %s\n", opt);
+ asb->s_other_mask = option;
+ break;
+ default:
+ printk("ADFS-fs: unrecognised mount option \"%s\" "
+ "or missing value\n", p);
return -EINVAL;
}
}
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
+#include <linux/parser.h>
#include <asm/system.h>
#include <asm/uaccess.h>
.remount_fs = affs_remount,
};
+enum {
+ Opt_bs, Opt_mode, Opt_mufs, Opt_prefix, Opt_protect,
+ Opt_reserved, Opt_root, Opt_setgid, Opt_setuid,
+ Opt_verbose, Opt_volume, Opt_ignore, Opt_err,
+};
+
+static match_table_t tokens = {
+ {Opt_bs, "bs=%d"},
+ {Opt_mode, "mode=%o"},
+ {Opt_mufs, "mufs"},
+ {Opt_prefix, "prefix=%s"},
+ {Opt_protect, "protect"},
+ {Opt_reserved, "reserved=%d"},
+ {Opt_root, "root=%d"},
+ {Opt_setgid, "setgid=%d"},
+ {Opt_setuid, "setuid=%d"},
+ {Opt_verbose, "verbose"},
+ {Opt_volume, "volume=%s"},
+ {Opt_ignore, "grpquota"},
+ {Opt_ignore, "noquota"},
+ {Opt_ignore, "quota"},
+ {Opt_ignore, "usrquota"},
+ {Opt_err, NULL},
+};
+
static int
parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s32 *root,
int *blocksize, char **prefix, char *volume, unsigned long *mount_opts)
{
- char *this_char, *value, *optn;
- int f;
+ char *p;
+ substring_t args[MAX_OPT_ARGS];
/* Fill in defaults */
*mount_opts = 0;
if (!options)
return 1;
- while ((this_char = strsep(&options, ",")) != NULL) {
- if (!*this_char)
+
+ while ((p = strsep(&options, ",")) != NULL) {
+ int token, n, option;
+ if (!*p)
continue;
- f = 0;
- if ((value = strchr(this_char,'=')) != NULL)
- *value++ = 0;
- if ((optn = "protect") && !strcmp(this_char, optn)) {
- if (value)
- goto out_inv_arg;
- *mount_opts |= SF_IMMUTABLE;
- } else if ((optn = "verbose") && !strcmp(this_char, optn)) {
- if (value)
- goto out_inv_arg;
- *mount_opts |= SF_VERBOSE;
- } else if ((optn = "mufs") && !strcmp(this_char, optn)) {
- if (value)
- goto out_inv_arg;
- *mount_opts |= SF_MUFS;
- } else if ((f = !strcmp(this_char,"setuid")) || !strcmp(this_char,"setgid")) {
- if (value) {
- if (!*value) {
- printk("AFFS: Argument for set[ug]id option missing\n");
- return 0;
- } else {
- (f ? *uid : *gid) = simple_strtoul(value,&value,0);
- if (*value) {
- printk("AFFS: Bad set[ug]id argument\n");
- return 0;
- }
- *mount_opts |= f ? SF_SETUID : SF_SETGID;
- }
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_bs:
+ if (match_int(&args[0], &n))
+ return -EINVAL;
+ if (n != 512 && n != 1024 && n != 2048
+ && n != 4096) {
+ printk ("AFFS: Invalid blocksize (512, 1024, 2048, 4096 allowed)\n");
+ return 0;
}
- } else if (!strcmp(this_char,"prefix")) {
- optn = "prefix";
- if (!value || !*value)
- goto out_no_arg;
+ *blocksize = n;
+ break;
+ case Opt_mode:
+ if (match_octal(&args[0], &option))
+ return 1;
+ *mode = option & 0777;
+ *mount_opts |= SF_SETMODE;
+ break;
+ case Opt_mufs:
+ *mount_opts |= SF_MUFS;
+ break;
+ case Opt_prefix:
if (*prefix) { /* Free any previous prefix */
kfree(*prefix);
*prefix = NULL;
}
- *prefix = kmalloc(strlen(value) + 1,GFP_KERNEL);
+ *prefix = match_strdup(&args[0]);
if (!*prefix)
return 0;
- strcpy(*prefix,value);
*mount_opts |= SF_PREFIX;
- } else if (!strcmp(this_char,"volume")) {
- optn = "volume";
- if (!value || !*value)
- goto out_no_arg;
- strlcpy(volume,value,31);
- } else if (!strcmp(this_char,"mode")) {
- optn = "mode";
- if (!value || !*value)
- goto out_no_arg;
- *mode = simple_strtoul(value,&value,8) & 0777;
- if (*value)
- return 0;
- *mount_opts |= SF_SETMODE;
- } else if (!strcmp(this_char,"reserved")) {
- optn = "reserved";
- if (!value || !*value)
- goto out_no_arg;
- *reserved = simple_strtoul(value,&value,0);
- if (*value)
- return 0;
- } else if (!strcmp(this_char,"root")) {
- optn = "root";
- if (!value || !*value)
- goto out_no_arg;
- *root = simple_strtoul(value,&value,0);
- if (*value)
- return 0;
- } else if (!strcmp(this_char,"bs")) {
- optn = "bs";
- if (!value || !*value)
- goto out_no_arg;
- *blocksize = simple_strtoul(value,&value,0);
- if (*value)
- return 0;
- if (*blocksize != 512 && *blocksize != 1024 && *blocksize != 2048
- && *blocksize != 4096) {
- printk ("AFFS: Invalid blocksize (512, 1024, 2048, 4096 allowed)\n");
- return 0;
- }
- } else if (!strcmp (this_char, "grpquota")
- || !strcmp (this_char, "noquota")
- || !strcmp (this_char, "quota")
- || !strcmp (this_char, "usrquota"))
- /* Silently ignore the quota options */
- ;
- else {
- printk("AFFS: Unrecognized mount option %s\n", this_char);
+ break;
+ case Opt_protect:
+ *mount_opts |= SF_IMMUTABLE;
+ break;
+ case Opt_reserved:
+ if (match_int(&args[0], reserved))
+ return 1;
+ break;
+ case Opt_root:
+ if (match_int(&args[0], root))
+ return 1;
+ break;
+ case Opt_setgid:
+ if (match_int(&args[0], &option))
+ return 1;
+ *gid = option;
+ *mount_opts |= SF_SETGID;
+ break;
+ case Opt_setuid:
+ if (match_int(&args[0], &option))
+ return -EINVAL;
+ *uid = option;
+ *mount_opts |= SF_SETUID;
+ break;
+ case Opt_verbose:
+ *mount_opts |= SF_VERBOSE;
+ break;
+ case Opt_volume: {
+ char *vol = match_strdup(&args[0]);
+ strlcpy(volume, vol, 32);
+ kfree(vol);
+ break;
+ }
+ case Opt_ignore:
+ /* Silently ignore the quota options */
+ break;
+ default:
+ printk("AFFS: Unrecognized mount option \"%s\" "
+ "or missing value\n", p);
return 0;
}
}
return 1;
-
-out_no_arg:
- printk("AFFS: The %s option requires an argument\n", optn);
- return 0;
-out_inv_arg:
- printk("AFFS: Option %s does not take an argument\n", optn);
- return 0;
}
/* This function definitely needs to be split up. Some fine day I'll
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/file.h>
+#include <linux/parser.h>
#include <asm/bitops.h>
#include "autofs_i.h"
#include <linux/module.h>
.statfs = simple_statfs,
};
+enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto};
+
+static match_table_t autofs_tokens = {
+ {Opt_fd, "fd=%d"},
+ {Opt_uid, "uid=%d"},
+ {Opt_gid, "gid=%d"},
+ {Opt_pgrp, "pgrp=%d"},
+ {Opt_minproto, "minproto=%d"},
+ {Opt_maxproto, "maxproto=%d"},
+ {Opt_err, NULL}
+};
+
static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, pid_t *pgrp, int *minproto, int *maxproto)
{
- char *this_char, *value;
-
+ char *p;
+ substring_t args[MAX_OPT_ARGS];
+ int option;
+
*uid = current->uid;
*gid = current->gid;
*pgrp = process_group(current);
*pipefd = -1;
- if ( !options ) return 1;
- while ((this_char = strsep(&options,",")) != NULL) {
- if (!*this_char)
+ if (!options)
+ return 1;
+
+ while ((p = strsep(&options, ",")) != NULL) {
+ int token;
+ if (!*p)
continue;
- if ((value = strchr(this_char,'=')) != NULL)
- *value++ = 0;
- if (!strcmp(this_char,"fd")) {
- if (!value || !*value)
- return 1;
- *pipefd = simple_strtoul(value,&value,0);
- if (*value)
- return 1;
- }
- else if (!strcmp(this_char,"uid")) {
- if (!value || !*value)
- return 1;
- *uid = simple_strtoul(value,&value,0);
- if (*value)
- return 1;
- }
- else if (!strcmp(this_char,"gid")) {
- if (!value || !*value)
- return 1;
- *gid = simple_strtoul(value,&value,0);
- if (*value)
- return 1;
- }
- else if (!strcmp(this_char,"pgrp")) {
- if (!value || !*value)
+
+ token = match_token(p, autofs_tokens, args);
+ switch (token) {
+ case Opt_fd:
+ if (match_int(&args[0], &option))
return 1;
- *pgrp = simple_strtoul(value,&value,0);
- if (*value)
+ *pipefd = option;
+ break;
+ case Opt_uid:
+ if (match_int(&args[0], &option))
return 1;
- }
- else if (!strcmp(this_char,"minproto")) {
- if (!value || !*value)
+ *uid = option;
+ break;
+ case Opt_gid:
+ if (match_int(&args[0], &option))
return 1;
- *minproto = simple_strtoul(value,&value,0);
- if (*value)
+ *gid = option;
+ break;
+ case Opt_pgrp:
+ if (match_int(&args[0], &option))
return 1;
- }
- else if (!strcmp(this_char,"maxproto")) {
- if (!value || !*value)
+ *pgrp = option;
+ break;
+ case Opt_minproto:
+ if (match_int(&args[0], &option))
return 1;
- *maxproto = simple_strtoul(value,&value,0);
- if (*value)
+ *minproto = option;
+ break;
+ case Opt_maxproto:
+ if (match_int(&args[0], &option))
return 1;
+ *maxproto = option;
+ break;
+ default:
+ return 1;
}
- else break;
}
return (*pipefd < 0);
}
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/pagemap.h>
+#include <linux/parser.h>
#include <asm/bitops.h>
#include "autofs_i.h"
#include <linux/module.h>
.statfs = simple_statfs,
};
+enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto};
+
+static match_table_t tokens = {
+ {Opt_fd, "fd=%d"},
+ {Opt_uid, "uid=%d"},
+ {Opt_gid, "gid=%d"},
+ {Opt_pgrp, "pgrp=%d"},
+ {Opt_minproto, "minproto=%d"},
+ {Opt_maxproto, "maxproto=%d"},
+ {Opt_err, NULL}
+};
+
static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
pid_t *pgrp, int *minproto, int *maxproto)
{
- char *this_char, *value;
-
+ char *p;
+ substring_t args[MAX_OPT_ARGS];
+ int option;
+
*uid = current->uid;
*gid = current->gid;
*pgrp = process_group(current);
*pipefd = -1;
- if ( !options ) return 1;
- while ((this_char = strsep(&options,",")) != NULL) {
- if (!*this_char)
+ if (!options)
+ return 1;
+
+ while ((p = strsep(&options, ",")) != NULL) {
+ int token;
+ if (!*p)
continue;
- if ((value = strchr(this_char,'=')) != NULL)
- *value++ = 0;
- if (!strcmp(this_char,"fd")) {
- if (!value || !*value)
- return 1;
- *pipefd = simple_strtoul(value,&value,0);
- if (*value)
- return 1;
- }
- else if (!strcmp(this_char,"uid")) {
- if (!value || !*value)
- return 1;
- *uid = simple_strtoul(value,&value,0);
- if (*value)
- return 1;
- }
- else if (!strcmp(this_char,"gid")) {
- if (!value || !*value)
- return 1;
- *gid = simple_strtoul(value,&value,0);
- if (*value)
- return 1;
- }
- else if (!strcmp(this_char,"pgrp")) {
- if (!value || !*value)
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_fd:
+ if (match_int(args, pipefd))
return 1;
- *pgrp = simple_strtoul(value,&value,0);
- if (*value)
+ break;
+ case Opt_uid:
+ if (match_int(args, &option))
return 1;
- }
- else if (!strcmp(this_char,"minproto")) {
- if (!value || !*value)
+ *uid = option;
+ break;
+ case Opt_gid:
+ if (match_int(args, &option))
return 1;
- *minproto = simple_strtoul(value,&value,0);
- if (*value)
+ *gid = option;
+ break;
+ case Opt_pgrp:
+ if (match_int(args, &option))
return 1;
- }
- else if (!strcmp(this_char,"maxproto")) {
- if (!value || !*value)
+ *pgrp = option;
+ break;
+ case Opt_minproto:
+ if (match_int(args, &option))
return 1;
- *maxproto = simple_strtoul(value,&value,0);
- if (*value)
+ *minproto = option;
+ break;
+ case Opt_maxproto:
+ if (match_int(args, &option))
return 1;
+ *maxproto = option;
+ break;
+ default:
+ return 1;
}
- else break;
}
return (*pipefd < 0);
}
#include <linux/nls.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
+#include <linux/parser.h>
#include "befs.h"
#include "btree.h"
return -EILSEQ;
}
+/**
+ * Use the
+ *
+ */
+enum {
+ Opt_uid, Opt_gid, Opt_charset, Opt_debug,
+};
+
+static match_table_t befs_tokens = {
+ {Opt_uid, "uid=%d"},
+ {Opt_gid, "gid=%d"},
+ {Opt_charset, "iocharset=%s"},
+ {Opt_debug, "debug"}
+};
+
static int
parse_options(char *options, befs_mount_options * opts)
{
- char *this_char;
- char *value;
- int ret = 1;
+ char *p;
+ substring_t args[MAX_OPT_ARGS];
+ int option;
/* Initialize options */
opts->uid = 0;
opts->debug = 0;
if (!options)
- return ret;
-
- while ((this_char = strsep(&options, ",")) != NULL) {
-
- if ((value = strchr(this_char, '=')) != NULL)
- *value++ = 0;
-
- if (!strcmp(this_char, "uid")) {
- if (!value || !*value) {
- ret = 0;
- } else {
- opts->uid = simple_strtoul(value, &value, 0);
- opts->use_uid = 1;
- if (*value) {
- printk(KERN_ERR "BEFS: Invalid uid "
- "option: %s\n", value);
- ret = 0;
- }
+ return 1;
+
+ while ((p = strsep(&options, ",")) != NULL) {
+ int token;
+ if (!*p)
+ continue;
+
+ token = match_token(p, befs_tokens, args);
+ switch (token) {
+ case Opt_uid:
+ if (match_int(&args[0], &option))
+ return 0;
+ if (option < 0) {
+ printk(KERN_ERR "BeFS: Invalid uid %d, "
+ "using default\n", option);
+ break;
}
- } else if (!strcmp(this_char, "gid")) {
- if (!value || !*value)
- ret = 0;
- else {
- opts->gid = simple_strtoul(value, &value, 0);
- opts->use_gid = 1;
- if (*value) {
- printk(KERN_ERR
- "BEFS: Invalid gid option: "
- "%s\n", value);
- ret = 0;
- }
+ opts->uid = option;
+ opts->use_uid = 1;
+ break;
+ case Opt_gid:
+ if (match_int(&args[0], &option))
+ return 0;
+ if (option < 0) {
+ printk(KERN_ERR "BeFS: Invalid gid %d, "
+ "using default\n", option);
+ break;
}
- } else if (!strcmp(this_char, "iocharset") && value) {
- char *p = value;
- int len;
-
- while (*value && *value != ',')
- value++;
- len = value - p;
- if (len) {
- char *buffer = kmalloc(len + 1, GFP_NOFS);
- if (buffer) {
- opts->iocharset = buffer;
- memcpy(buffer, p, len);
- buffer[len] = 0;
-
- } else {
- printk(KERN_ERR "BEFS: "
- "cannot allocate memory\n");
- ret = 0;
- }
+ opts->gid = option;
+ opts->use_gid = 1;
+ break;
+ case Opt_charset:
+ kfree(opts->iocharset);
+ opts->iocharset = match_strdup(&args[0]);
+ if (!opts->iocharset) {
+ printk(KERN_ERR "BeFS: allocation failure for "
+ "iocharset string\n");
+ return 0;
}
- } else if (!strcmp(this_char, "debug")) {
+ break;
+ case Opt_debug:
opts->debug = 1;
+ break;
+ default:
+ printk(KERN_ERR "BeFS: Unrecognized mount option \"%s\" "
+ "or missing value\n", p);
+ return 0;
}
}
-
- return ret;
+ return 1;
}
/* This function has the responsibiltiy of getting the
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/blkdev.h>
+#include <linux/parser.h>
#include <linux/random.h>
#include <linux/buffer_head.h>
#include <linux/smp_lock.h>
return sb_block;
}
-static int want_value(char *value, char *option)
-{
- if (!value || !*value) {
- printk(KERN_NOTICE "EXT2-fs: the %s option needs an argument\n",
- option);
- return -1;
- }
- return 0;
-}
-
-static int want_null_value(char *value, char *option)
-{
- if (*value) {
- printk(KERN_NOTICE "EXT2-fs: Invalid %s argument: %s\n",
- option, value);
- return -1;
- }
- return 0;
-}
+enum {
+ Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
+ Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
+ Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, Opt_nobh,
+ Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
+ Opt_ignore, Opt_err,
+};
-static int want_numeric(char *value, char *option, unsigned long *number)
-{
- if (want_value(value, option))
- return -1;
- *number = simple_strtoul(value, &value, 0);
- if (want_null_value(value, option))
- return -1;
- return 0;
-}
+static match_table_t tokens = {
+ {Opt_bsd_df, "bsddf"},
+ {Opt_minix_df, "minixdf"},
+ {Opt_grpid, "grpid"},
+ {Opt_grpid, "bsdgroups"},
+ {Opt_nogrpid, "nogrpid"},
+ {Opt_nogrpid, "sysvgroups"},
+ {Opt_resgid, "resgid=%d"},
+ {Opt_resuid, "resuid=%d"},
+ {Opt_sb, "sb=%d"},
+ {Opt_err_cont, "errors=continue"},
+ {Opt_err_panic, "errors=panic"},
+ {Opt_err_ro, "errors=remount-ro"},
+ {Opt_nouid32, "nouid32"},
+ {Opt_nocheck, "check=none"},
+ {Opt_nocheck, "nocheck"},
+ {Opt_check, "check"},
+ {Opt_debug, "debug"},
+ {Opt_oldalloc, "oldalloc"},
+ {Opt_orlov, "orlov"},
+ {Opt_nobh, "nobh"},
+ {Opt_user_xattr, "user_xattr"},
+ {Opt_nouser_xattr, "nouser_xattr"},
+ {Opt_acl, "acl"},
+ {Opt_noacl, "noacl"},
+ {Opt_ignore, "grpquota"},
+ {Opt_ignore, "noquota"},
+ {Opt_ignore, "quota"},
+ {Opt_ignore, "usrquota"},
+ {Opt_err, NULL}
+};
-/*
- * This function has been shamelessly adapted from the msdos fs
- */
static int parse_options (char * options,
struct ext2_sb_info *sbi)
{
- char * this_char;
- char * value;
+ char * p;
+ substring_t args[MAX_OPT_ARGS];
+ unsigned long kind = EXT2_MOUNT_ERRORS_CONT;
+ int option;
if (!options)
return 1;
- while ((this_char = strsep (&options, ",")) != NULL) {
- if (!*this_char)
+
+ while ((p = strsep (&options, ",")) != NULL) {
+ int token;
+ if (!*p)
continue;
- if ((value = strchr (this_char, '=')) != NULL)
- *value++ = 0;
+
+ 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:
+ kind = EXT2_MOUNT_ERRORS_PANIC;
+ break;
+ case Opt_err_ro:
+ kind = EXT2_MOUNT_ERRORS_RO;
+ break;
+ case Opt_err_cont:
+ kind = EXT2_MOUNT_ERRORS_CONT;
+ break;
+ case Opt_nouid32:
+ set_opt (sbi->s_mount_opt, NO_UID32);
+ break;
+ case Opt_check:
+#ifdef CONFIG_EXT2_CHECK
+ set_opt (sbi->s_mount_opt, CHECK);
+#else
+ printk("EXT2 Check option not supported\n");
+#endif
+ 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
- if (!strcmp (this_char, "user_xattr"))
+ case Opt_user_xattr:
set_opt (sbi->s_mount_opt, XATTR_USER);
- else if (!strcmp (this_char, "nouser_xattr"))
+ break;
+ case Opt_nouser_xattr:
clear_opt (sbi->s_mount_opt, XATTR_USER);
- else
+ 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
- if (!strcmp(this_char, "acl"))
+ case Opt_acl:
set_opt(sbi->s_mount_opt, POSIX_ACL);
- else if (!strcmp(this_char, "noacl"))
+ break;
+ case Opt_noacl:
clear_opt(sbi->s_mount_opt, POSIX_ACL);
- else
-#endif
- if (!strcmp (this_char, "bsddf"))
- clear_opt (sbi->s_mount_opt, MINIX_DF);
- else if (!strcmp (this_char, "nouid32")) {
- set_opt (sbi->s_mount_opt, NO_UID32);
- }
- else if (!strcmp (this_char, "check")) {
- if (!value || !*value || !strcmp (value, "none"))
- clear_opt (sbi->s_mount_opt, CHECK);
- else
-#ifdef CONFIG_EXT2_CHECK
- set_opt (sbi->s_mount_opt, CHECK);
+ break;
#else
- printk("EXT2 Check option not supported\n");
+ case Opt_acl:
+ case Opt_noacl:
+ printk("EXT2 (no)acl options not supported\n");
+ break;
#endif
- }
- else if (!strcmp (this_char, "debug"))
- set_opt (sbi->s_mount_opt, DEBUG);
- else if (!strcmp (this_char, "errors")) {
- if (!value || !*value) {
- printk ("EXT2-fs: the errors option requires "
- "an argument\n");
- return 0;
- }
- if (!strcmp (value, "continue")) {
- clear_opt (sbi->s_mount_opt, ERRORS_RO);
- clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
- set_opt (sbi->s_mount_opt, ERRORS_CONT);
- }
- else if (!strcmp (value, "remount-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);
- }
- else if (!strcmp (value, "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);
- }
- else {
- printk ("EXT2-fs: Invalid errors option: %s\n",
- value);
- return 0;
- }
- }
- else if (!strcmp (this_char, "grpid") ||
- !strcmp (this_char, "bsdgroups"))
- set_opt (sbi->s_mount_opt, GRPID);
- else if (!strcmp (this_char, "minixdf"))
- set_opt (sbi->s_mount_opt, MINIX_DF);
- else if (!strcmp (this_char, "nocheck"))
- clear_opt (sbi->s_mount_opt, CHECK);
- else if (!strcmp (this_char, "nogrpid") ||
- !strcmp (this_char, "sysvgroups"))
- clear_opt (sbi->s_mount_opt, GRPID);
- else if (!strcmp (this_char, "resgid")) {
- unsigned long v;
- if (want_numeric(value, "resgid", &v))
- return 0;
- sbi->s_resgid = v;
- }
- else if (!strcmp (this_char, "resuid")) {
- unsigned long v;
- if (want_numeric(value, "resuid", &v))
- return 0;
- sbi->s_resuid = v;
- }
- else if (!strcmp (this_char, "oldalloc"))
- set_opt (sbi->s_mount_opt, OLDALLOC);
- else if (!strcmp (this_char, "orlov"))
- clear_opt (sbi->s_mount_opt, OLDALLOC);
- else if (!strcmp (this_char, "nobh"))
- set_opt(sbi->s_mount_opt, NOBH);
- /* Silently ignore the quota options */
- else if (!strcmp (this_char, "grpquota")
- || !strcmp (this_char, "noquota")
- || !strcmp (this_char, "quota")
- || !strcmp (this_char, "usrquota"))
- /* Don't do anything ;-) */ ;
- else {
- printk ("EXT2-fs: Unrecognized mount option %s\n", this_char);
+ case Opt_ignore:
+ break;
+ default:
return 0;
}
}
+ sbi->s_mount_opt |= kind;
return 1;
}
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/blkdev.h>
+#include <linux/parser.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
.get_parent = ext3_get_parent,
};
+enum {
+ Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
+ Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
+ Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
+ Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_noload,
+ Opt_commit, Opt_journal_update, Opt_journal_inum,
+ Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
+ Opt_ignore, Opt_err,
+};
-static int want_value(char *value, char *option)
-{
- if (!value || !*value) {
- printk(KERN_NOTICE "EXT3-fs: the %s option needs an argument\n",
- option);
- return -1;
- }
- return 0;
-}
-
-static int want_null_value(char *value, char *option)
-{
- if (*value) {
- printk(KERN_NOTICE "EXT3-fs: Invalid %s argument: %s\n",
- option, value);
- return -1;
- }
- return 0;
-}
-
-static int want_numeric(char *value, char *option, unsigned long *number)
-{
- if (want_value(value, option))
- return -1;
- *number = simple_strtoul(value, &value, 0);
- if (want_null_value(value, option))
- return -1;
- return 0;
-}
+static match_table_t tokens = {
+ {Opt_bsd_df, "bsddf"},
+ {Opt_minix_df, "minixdf"},
+ {Opt_grpid, "grpid"},
+ {Opt_grpid, "bsdgroups"},
+ {Opt_nogrpid, "nogrpid"},
+ {Opt_nogrpid, "sysvgroups"},
+ {Opt_resgid, "resgid=%d"},
+ {Opt_resuid, "resuid=%d"},
+ {Opt_sb, "sb=%d"},
+ {Opt_err_cont, "errors=continue"},
+ {Opt_err_panic, "errors=panic"},
+ {Opt_err_ro, "errors=remount-ro"},
+ {Opt_nouid32, "nouid32"},
+ {Opt_nocheck, "nocheck"},
+ {Opt_nocheck, "check=none"},
+ {Opt_check, "check"},
+ {Opt_debug, "debug"},
+ {Opt_oldalloc, "oldalloc"},
+ {Opt_orlov, "orlov"},
+ {Opt_user_xattr, "user_xattr"},
+ {Opt_nouser_xattr, "nouser_xattr"},
+ {Opt_acl, "acl"},
+ {Opt_noacl, "noacl"},
+ {Opt_noload, "noload"},
+ {Opt_commit, "commit=%u"},
+ {Opt_journal_update, "journal=update"},
+ {Opt_journal_inum, "journal=%u"},
+ {Opt_abort, "abort"},
+ {Opt_data_journal, "data=journal"},
+ {Opt_data_ordered, "data=ordered"},
+ {Opt_data_writeback, "data=writeback"},
+ {Opt_ignore, "grpquota"},
+ {Opt_ignore, "noquota"},
+ {Opt_ignore, "quota"},
+ {Opt_ignore, "usrquota"},
+ {Opt_err, NULL}
+};
static unsigned long get_sb_block(void **data)
{
return sb_block;
}
-/*
- * This function has been shamelessly adapted from the msdos fs
- */
static int parse_options (char * options, struct ext3_sb_info *sbi,
unsigned long * inum, int is_remount)
{
- char * this_char;
- char * value;
+ char * p;
+ substring_t args[MAX_OPT_ARGS];
+ int data_opt = 0;
+ int option;
if (!options)
return 1;
- while ((this_char = strsep (&options, ",")) != NULL) {
- if (!*this_char)
+
+ while ((p = strsep (&options, ",")) != NULL) {
+ int token;
+ if (!*p)
continue;
- if ((value = strchr (this_char, '=')) != NULL)
- *value++ = 0;
-#ifdef CONFIG_EXT3_FS_XATTR
- if (!strcmp (this_char, "user_xattr"))
- set_opt (sbi->s_mount_opt, XATTR_USER);
- else if (!strcmp (this_char, "nouser_xattr"))
- clear_opt (sbi->s_mount_opt, XATTR_USER);
- else
-#endif
-#ifdef CONFIG_EXT3_FS_POSIX_ACL
- if (!strcmp(this_char, "acl"))
- set_opt (sbi->s_mount_opt, POSIX_ACL);
- else if (!strcmp(this_char, "noacl"))
- clear_opt (sbi->s_mount_opt, POSIX_ACL);
- else
-#endif
- if (!strcmp (this_char, "bsddf"))
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_bsd_df:
clear_opt (sbi->s_mount_opt, MINIX_DF);
- else if (!strcmp (this_char, "nouid32")) {
+ 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);
- }
- else if (!strcmp (this_char, "abort"))
- set_opt (sbi->s_mount_opt, ABORT);
- else if (!strcmp (this_char, "check")) {
- if (!value || !*value || !strcmp (value, "none"))
- clear_opt (sbi->s_mount_opt, CHECK);
- else
+ break;
+ case Opt_check:
#ifdef CONFIG_EXT3_CHECK
- set_opt (sbi->s_mount_opt, CHECK);
+ set_opt (sbi->s_mount_opt, CHECK);
#else
- printk(KERN_ERR
- "EXT3 Check option not supported\n");
+ printk(KERN_ERR
+ "EXT3 Check option not supported\n");
#endif
- }
- else if (!strcmp (this_char, "debug"))
- set_opt (sbi->s_mount_opt, DEBUG);
- else if (!strcmp (this_char, "errors")) {
- if (want_value(value, "errors"))
- return 0;
- if (!strcmp (value, "continue")) {
- clear_opt (sbi->s_mount_opt, ERRORS_RO);
- clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
- set_opt (sbi->s_mount_opt, ERRORS_CONT);
- }
- else if (!strcmp (value, "remount-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);
- }
- else if (!strcmp (value, "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);
- }
- else {
- printk (KERN_ERR
- "EXT3-fs: Invalid errors option: %s\n",
- value);
- return 0;
- }
- }
- else if (!strcmp (this_char, "grpid") ||
- !strcmp (this_char, "bsdgroups"))
- set_opt (sbi->s_mount_opt, GRPID);
- else if (!strcmp (this_char, "minixdf"))
- set_opt (sbi->s_mount_opt, MINIX_DF);
- else if (!strcmp (this_char, "nocheck"))
+ break;
+ case Opt_nocheck:
clear_opt (sbi->s_mount_opt, CHECK);
- else if (!strcmp (this_char, "nogrpid") ||
- !strcmp (this_char, "sysvgroups"))
- clear_opt (sbi->s_mount_opt, GRPID);
- else if (!strcmp (this_char, "resgid")) {
- unsigned long v;
- if (want_numeric(value, "resgid", &v))
- return 0;
- sbi->s_resgid = v;
- }
- else if (!strcmp (this_char, "resuid")) {
- unsigned long v;
- if (want_numeric(value, "resuid", &v))
- return 0;
- sbi->s_resuid = v;
- }
- else if (!strcmp (this_char, "oldalloc"))
+ break;
+ case Opt_debug:
+ set_opt (sbi->s_mount_opt, DEBUG);
+ break;
+ case Opt_oldalloc:
set_opt (sbi->s_mount_opt, OLDALLOC);
- else if (!strcmp (this_char, "orlov"))
+ break;
+ case Opt_orlov:
clear_opt (sbi->s_mount_opt, OLDALLOC);
- /* Silently ignore the quota options */
- else if (!strcmp (this_char, "grpquota")
- || !strcmp (this_char, "noquota")
- || !strcmp (this_char, "quota")
- || !strcmp (this_char, "usrquota"))
- /* Don't do anything ;-) */ ;
- else if (!strcmp (this_char, "journal")) {
+ break;
+#ifdef CONFIG_EXT3_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("EXT3 (no)user_xattr options not supported\n");
+ break;
+#endif
+#ifdef CONFIG_EXT3_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("EXT3 (no)acl options not supported\n");
+ break;
+#endif
+ case Opt_journal_update:
/* @@@ FIXME */
/* Eventually we will want to be able to create
- a journal file here. For now, only allow the
- user to specify an existing inode to be the
- journal file. */
+ a journal file here. For now, only allow the
+ user to specify an existing inode to be the
+ journal file. */
if (is_remount) {
printk(KERN_ERR "EXT3-fs: cannot specify "
"journal on remount\n");
return 0;
}
-
- if (want_value(value, "journal"))
+ set_opt (sbi->s_mount_opt, UPDATE_JOURNAL);
+ break;
+ case Opt_journal_inum:
+ if (is_remount) {
+ printk(KERN_ERR "EXT3-fs: cannot specify "
+ "journal on remount\n");
return 0;
- if (!strcmp (value, "update"))
- set_opt (sbi->s_mount_opt, UPDATE_JOURNAL);
- else if (want_numeric(value, "journal", inum))
+ }
+ if (match_int(&args[0], &option))
return 0;
- }
- else if (!strcmp (this_char, "noload"))
+ *inum = option;
+ break;
+ case Opt_noload:
set_opt (sbi->s_mount_opt, NOLOAD);
- else if (!strcmp (this_char, "data")) {
- int data_opt = 0;
-
- if (want_value(value, "data"))
- return 0;
- if (!strcmp (value, "journal"))
- data_opt = EXT3_MOUNT_JOURNAL_DATA;
- else if (!strcmp (value, "ordered"))
- data_opt = EXT3_MOUNT_ORDERED_DATA;
- else if (!strcmp (value, "writeback"))
- data_opt = EXT3_MOUNT_WRITEBACK_DATA;
- else {
- printk (KERN_ERR
- "EXT3-fs: Invalid data option: %s\n",
- value);
+ break;
+ case Opt_commit:
+ if (match_int(&args[0], &option))
return 0;
- }
+ sbi->s_commit_interval = HZ * option;
+ break;
+ case Opt_data_journal:
+ data_opt = EXT3_MOUNT_JOURNAL_DATA;
+ goto datacheck;
+ case Opt_data_ordered:
+ data_opt = EXT3_MOUNT_ORDERED_DATA;
+ goto datacheck;
+ case Opt_data_writeback:
+ data_opt = EXT3_MOUNT_WRITEBACK_DATA;
+ datacheck:
if (is_remount) {
- if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS) !=
- data_opt) {
+ if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS)
+ != data_opt) {
printk(KERN_ERR
- "EXT3-fs: cannot change data "
- "mode on remount\n");
+ "EXT3-fs: cannot change data "
+ "mode on remount\n");
return 0;
}
} else {
sbi->s_mount_opt &= ~EXT3_MOUNT_DATA_FLAGS;
sbi->s_mount_opt |= data_opt;
}
- } else if (!strcmp (this_char, "commit")) {
- unsigned long v;
- if (want_numeric(value, "commit", &v))
- return 0;
- sbi->s_commit_interval = (HZ * v);
- } else {
- printk (KERN_ERR
- "EXT3-fs: Unrecognized mount option %s\n",
- this_char);
+ break;
+ case Opt_abort:
+ set_opt(sbi->s_mount_opt, ABORT);
+ break;
+ case Opt_ignore:
+ break;
+ default:
+ printk (KERN_ERR
+ "EXT3-fs: Unrecognized mount option \"%s\" "
+ "or missing value\n", p);
return 0;
}
}
+
return 1;
}
#include <linux/buffer_head.h>
#include <linux/mount.h>
#include <linux/vfs.h>
+#include <linux/parser.h>
#include <asm/unaligned.h>
/*
kfree(sbi);
}
-static int simple_getbool(char *s, int *setval)
-{
- if (s) {
- if (!strcmp(s,"1") || !strcmp(s,"yes") || !strcmp(s,"true"))
- *setval = 1;
- else if (!strcmp(s,"0") || !strcmp(s,"no") || !strcmp(s,"false"))
- *setval = 0;
- else
- return 0;
- } else
- *setval = 1;
- return 1;
-}
-
static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
{
struct msdos_sb_info *sbi = MSDOS_SB(mnt->mnt_sb);
return 0;
}
+static void print_obsolete_option(char *optname)
+{
+ printk(KERN_INFO "FAT: %s option is obsolete, "
+ "not supported now\n", optname);
+}
+
+enum {
+ Opt_blocksize, Opt_charset, Opt_check_n, Opt_check_r, Opt_check_s,
+ Opt_fat, Opt_codepage, Opt_conv_a, Opt_conv_b, Opt_conv_t,
+ Opt_debug, Opt_dots, Opt_err, Opt_gid, Opt_immutable,
+ Opt_nocase, Opt_nodots, Opt_quiet, Opt_showexec, Opt_uid,
+ Opt_shortname_lower, Opt_shortname_win95, Opt_shortname_winnt, Opt_shortname_mixed,
+ Opt_umask, Opt_dmask, Opt_fmask, Opt_posix, Opt_cvf_format, Opt_cvf_options,
+ Opt_utf8_off, Opt_utf8_no, Opt_utf8_false,
+ Opt_utf8_on, Opt_utf8_yes, Opt_utf8_true, Opt_utf8_opt,
+ Opt_uni_xl_off, Opt_uni_xl_no, Opt_uni_xl_false,
+ Opt_uni_xl_on, Opt_uni_xl_yes, Opt_uni_xl_true, Opt_uni_xl_opt,
+ Opt_nonumtail_off, Opt_nonumtail_no, Opt_nonumtail_false,
+ Opt_nonumtail_on, Opt_nonumtail_yes, Opt_nonumtail_true, Opt_nonumtail_opt,
+};
+
+static match_table_t FAT_tokens = {
+ {Opt_check_r, "check=relaxed"},
+ {Opt_check_s, "check=strict"},
+ {Opt_check_n, "check=normal"},
+ {Opt_check_r, "check=r"},
+ {Opt_check_s, "check=s"},
+ {Opt_check_n, "check=n"},
+ {Opt_conv_b, "conv=binary"},
+ {Opt_conv_t, "conv=text"},
+ {Opt_conv_a, "conv=auto"},
+ {Opt_conv_b, "conv=b"},
+ {Opt_conv_t, "conv=t"},
+ {Opt_conv_a, "conv=a"},
+ {Opt_nodots, "nodots"},
+ {Opt_nodots, "dotsOK=no"},
+ {Opt_dots, "dotsOK=yes"},
+ {Opt_dots, "dots"},
+ {Opt_uid, "uid=%d"},
+ {Opt_gid, "gid=%d"},
+ {Opt_umask, "umask=%o"},
+ {Opt_dmask, "dmask=%o"},
+ {Opt_fmask, "fmask=%o"},
+ {Opt_fat, "fat=%d"},
+ {Opt_codepage, "codepage=%d"},
+ {Opt_charset, "iocharset=%s"},
+ {Opt_blocksize, "blocksize=%d"},
+ {Opt_nocase, "nocase"},
+ {Opt_cvf_format, "cvf_format=%20s"},
+ {Opt_cvf_options, "cvf_options=%100s"},
+ {Opt_shortname_lower, "shortname=lower"},
+ {Opt_shortname_win95, "shortname=win95"},
+ {Opt_shortname_winnt, "shortname=winnt"},
+ {Opt_shortname_mixed, "shortname=mixed"},
+ {Opt_utf8_off, "utf8=0"}, /* 0 or no or false */
+ {Opt_utf8_no, "utf8=no"},
+ {Opt_utf8_false, "utf8=false"},
+ {Opt_utf8_on, "utf8=1"}, /* empty or 1 or yes or true */
+ {Opt_utf8_yes, "utf8=yes"},
+ {Opt_utf8_true, "utf8=true"},
+ {Opt_utf8_opt, "utf8"},
+ {Opt_uni_xl_off, "uni_xlate=0"}, /* 0 or no or false */
+ {Opt_uni_xl_no, "uni_xlate=no"},
+ {Opt_uni_xl_false, "uni_xlate=false"},
+ {Opt_uni_xl_on, "uni_xlate=1"}, /* empty or 1 or yes or true */
+ {Opt_uni_xl_yes, "uni_xlate=yes"},
+ {Opt_uni_xl_true, "uni_xlate=true"},
+ {Opt_uni_xl_opt, "uni_xlate"},
+ {Opt_nonumtail_off, "nonumtail=0"}, /* 0 or no or false */
+ {Opt_nonumtail_no, "nonumtail=no"},
+ {Opt_nonumtail_false, "nonumtail=false"},
+ {Opt_nonumtail_on, "nonumtail=1"}, /* empty or 1 or yes or true */
+ {Opt_nonumtail_yes, "nonumtail=yes"},
+ {Opt_nonumtail_true, "nonumtail=true"},
+ {Opt_nonumtail_opt, "nonumtail"},
+ {Opt_quiet, "quiet"},
+ {Opt_showexec, "showexec"},
+ {Opt_debug, "debug"},
+ {Opt_immutable, "sys_immutable"},
+ {Opt_posix, "posix"},
+ {Opt_err, NULL}
+};
+
static int parse_options(char *options, int is_vfat, int *debug,
struct fat_mount_options *opts)
{
- char *this_char, *value, *p;
- int ret = 1, val, len;
+ char *p;
+ substring_t args[MAX_OPT_ARGS];
+ int option;
opts->isvfat = is_vfat;
*debug = 0;
if (!options)
- goto out;
- while ((this_char = strsep(&options,",")) != NULL) {
- if (!*this_char)
+ return 1;
+
+ while ((p = strsep(&options, ",")) != NULL) {
+ int token;
+ if (!*p)
continue;
- if ((value = strchr(this_char,'=')) != NULL)
- *value++ = 0;
-
- if (!strcmp(this_char,"check") && value) {
- if (value[0] && !value[1] && strchr("rns",*value))
- opts->name_check = *value;
- else if (!strcmp(value,"relaxed"))
- opts->name_check = 'r';
- else if (!strcmp(value,"normal"))
- opts->name_check = 'n';
- else if (!strcmp(value,"strict"))
- opts->name_check = 's';
- else ret = 0;
- }
- else if (!strcmp(this_char,"conv") && value) {
- printk(KERN_INFO "FAT: conv option is obsolete, "
- "not supported now\n");
- }
- else if (!strcmp(this_char,"nocase")) {
+
+ token = match_token(p, FAT_tokens, args);
+ switch (token) {
+ case Opt_check_s:
+ opts->name_check = 's';
+ break;
+ case Opt_check_r:
+ opts->name_check = 'r';
+ break;
+ case Opt_check_n:
+ opts->name_check = 'n';
+ break;
+ case Opt_dots: /* msdos specific */
+ if (!is_vfat)
+ opts->dotsOK = 1;
+ break;
+ case Opt_nodots: /* msdos specific */
+ if (!is_vfat)
+ opts->dotsOK = 0;
+ break;
+ case Opt_nocase:
if (!is_vfat)
opts->nocase = 1;
else {
- /* for backward compatible */
+ /* for backward compatibility */
opts->shortname = VFAT_SFN_DISPLAY_WIN95
| VFAT_SFN_CREATE_WIN95;
}
- }
- else if (!strcmp(this_char,"showexec")) {
+ break;
+ case Opt_quiet:
+ opts->quiet = 1;
+ break;
+ case Opt_showexec:
opts->showexec = 1;
- }
- else if (!strcmp(this_char,"uid")) {
- if (!value || !*value) ret = 0;
- else {
- opts->fs_uid = simple_strtoul(value,&value,0);
- if (*value) ret = 0;
- }
- }
- else if (!strcmp(this_char,"gid")) {
- if (!value || !*value) ret= 0;
- else {
- opts->fs_gid = simple_strtoul(value,&value,0);
- if (*value) ret = 0;
- }
- }
- else if (!strcmp(this_char,"umask")) {
- if (!value || !*value) ret = 0;
- else {
- opts->fs_fmask = opts->fs_dmask =
- simple_strtoul(value,&value,8);
- if (*value) ret = 0;
- }
- }
- else if (!strcmp(this_char,"fmask")) {
- if (!value || !*value) ret = 0;
- else {
- opts->fs_fmask = simple_strtoul(value,&value,8);
- if (*value) ret = 0;
- }
- }
- else if (!strcmp(this_char,"dmask")) {
- if (!value || !*value) ret = 0;
- else {
- opts->fs_dmask = simple_strtoul(value,&value,8);
- if (*value) ret = 0;
- }
- }
- else if (!strcmp(this_char,"debug")) {
- if (value) ret = 0;
- else *debug = 1;
- }
- else if (!strcmp(this_char,"fat")) {
- printk(KERN_INFO "FAT: fat option is obsolete, "
- "not supported now\n");
- }
- else if (!strcmp(this_char,"quiet")) {
- if (value) ret = 0;
- else opts->quiet = 1;
- }
- else if (!strcmp(this_char,"blocksize")) {
- printk(KERN_INFO "FAT: blocksize option is obsolete, "
- "not supported now\n");
- }
- else if (!strcmp(this_char,"sys_immutable")) {
- if (value) ret = 0;
- else opts->sys_immutable = 1;
- }
- else if (!strcmp(this_char,"codepage") && value) {
- opts->codepage = simple_strtoul(value,&value,0);
- if (*value) ret = 0;
- }
-
- /* msdos specific */
- else if (!is_vfat && !strcmp(this_char,"dots")) {
- opts->dotsOK = 1;
- }
- else if (!is_vfat && !strcmp(this_char,"nodots")) {
- opts->dotsOK = 0;
- }
- else if (!is_vfat && !strcmp(this_char,"dotsOK") && value) {
- if (!strcmp(value,"yes")) opts->dotsOK = 1;
- else if (!strcmp(value,"no")) opts->dotsOK = 0;
- else ret = 0;
- }
+ break;
+ case Opt_debug:
+ *debug = 1;
+ break;
+ case Opt_immutable:
+ opts->sys_immutable = 1;
+ break;
+ case Opt_uid:
+ if (match_int(&args[0], &option))
+ return 0;
+ opts->fs_uid = option;
+ break;
+ case Opt_gid:
+ if (match_int(&args[0], &option))
+ return 0;
+ opts->fs_gid = option;
+ break;
+ case Opt_umask:
+ if (match_octal(&args[0], &option))
+ return 0;
+ opts->fs_fmask = opts->fs_dmask = option;
+ break;
+ case Opt_dmask:
+ if (match_octal(&args[0], &option))
+ return 0;
+ opts->fs_dmask = option;
+ break;
+ case Opt_fmask:
+ if (match_octal(&args[0], &option))
+ return 0;
+ opts->fs_fmask = option;
+ break;
+ case Opt_codepage:
+ if (match_int(&args[0], &option))
+ return 0;
+ opts->codepage = option;
+ printk("MSDOS FS: Using codepage %d\n",
+ opts->codepage);
+ break;
/* vfat specific */
- else if (is_vfat && !strcmp(this_char,"iocharset") && value) {
- p = value;
- while (*value && *value != ',')
- value++;
- len = value - p;
- if (len) {
- char *buffer;
-
- if (opts->iocharset != NULL) {
- kfree(opts->iocharset);
- opts->iocharset = NULL;
- }
- buffer = kmalloc(len + 1, GFP_KERNEL);
- if (buffer != NULL) {
- opts->iocharset = buffer;
- memcpy(buffer, p, len);
- buffer[len] = 0;
- } else
- ret = 0;
+ case Opt_charset:
+ if (is_vfat) {
+ kfree(opts->iocharset);
+ opts->iocharset = match_strdup(&args[0]);
+ if (!opts->iocharset)
+ return 0;
+ printk("MSDOS FS: IO charset %s\n",
+ opts->iocharset);
}
- }
- else if (is_vfat && !strcmp(this_char,"utf8")) {
- ret = simple_getbool(value, &val);
- if (ret) opts->utf8 = val;
- }
- else if (is_vfat && !strcmp(this_char,"uni_xlate")) {
- ret = simple_getbool(value, &val);
- if (ret) opts->unicode_xlate = val;
- }
- else if (is_vfat && !strcmp(this_char,"posix")) {
- printk(KERN_INFO "FAT: posix option is obsolete, "
- "not supported now\n");
- }
- else if (is_vfat && !strcmp(this_char,"nonumtail")) {
- ret = simple_getbool(value, &val);
- if (ret) {
- opts->numtail = !val;
- }
- }
- else if (is_vfat && !strcmp(this_char, "shortname")) {
- if (!strcmp(value, "lower"))
+ break;
+ case Opt_shortname_lower:
+ if (is_vfat) {
opts->shortname = VFAT_SFN_DISPLAY_LOWER
| VFAT_SFN_CREATE_WIN95;
- else if (!strcmp(value, "win95"))
+ }
+ break;
+ case Opt_shortname_win95:
+ if (is_vfat) {
opts->shortname = VFAT_SFN_DISPLAY_WIN95
| VFAT_SFN_CREATE_WIN95;
- else if (!strcmp(value, "winnt"))
+ }
+ break;
+ case Opt_shortname_winnt:
+ if (is_vfat) {
opts->shortname = VFAT_SFN_DISPLAY_WINNT
| VFAT_SFN_CREATE_WINNT;
- else if (!strcmp(value, "mixed"))
+ }
+ break;
+ case Opt_shortname_mixed:
+ if (is_vfat) {
opts->shortname = VFAT_SFN_DISPLAY_WINNT
| VFAT_SFN_CREATE_WIN95;
- else
- ret = 0;
- } else {
- printk(KERN_ERR "FAT: Unrecognized mount option %s\n",
- this_char);
- ret = 0;
- }
+ }
+ break;
+ case Opt_utf8_off: /* 0 or no or false */
+ case Opt_utf8_no:
+ case Opt_utf8_false:
+ if (is_vfat) {
+ opts->utf8 = 0;
+ }
+ break;
+ case Opt_utf8_on: /* empty or 1 or yes or true */
+ case Opt_utf8_opt:
+ case Opt_utf8_yes:
+ case Opt_utf8_true:
+ if (is_vfat) {
+ opts->utf8 = 1;
+ }
+ break;
+ case Opt_uni_xl_off: /* 0 or no or false */
+ case Opt_uni_xl_no:
+ case Opt_uni_xl_false:
+ if (is_vfat) {
+ opts->unicode_xlate = 0;
+ }
+ break;
+ case Opt_uni_xl_on: /* empty or 1 or yes or true */
+ case Opt_uni_xl_yes:
+ case Opt_uni_xl_true:
+ case Opt_uni_xl_opt:
+ if (is_vfat) {
+ opts->unicode_xlate = 1;
+ }
+ break;
+ case Opt_nonumtail_off: /* 0 or no or false */
+ case Opt_nonumtail_no:
+ case Opt_nonumtail_false:
+ if (is_vfat) {
+ opts->numtail = 1; /* negated option */
+ }
+ break;
+ case Opt_nonumtail_on: /* empty or 1 or yes or true */
+ case Opt_nonumtail_yes:
+ case Opt_nonumtail_true:
+ case Opt_nonumtail_opt:
+ if (is_vfat) {
+ opts->numtail = 0; /* negated option */
+ }
+ break;
- if (ret == 0)
+ /* obsolete mount options */
+ case Opt_conv_b:
+ case Opt_conv_t:
+ case Opt_conv_a:
+ print_obsolete_option("conv");
+ break;
+ case Opt_blocksize:
+ print_obsolete_option("blocksize");
+ break;
+ case Opt_posix:
+ print_obsolete_option("posix");
+ break;
+ case Opt_fat:
+ print_obsolete_option("fat");
+ break;
+ case Opt_cvf_format:
+ case Opt_cvf_options:
+ print_obsolete_option("cvf");
break;
+ /* unknown option */
+ default:
+ printk(KERN_ERR "FAT: Unrecognized mount option \"%s\" "
+ "or missing value\n", p);
+ return 0;
+ }
}
-out:
+
if (opts->unicode_xlate)
opts->utf8 = 0;
- return ret;
+ return 1;
}
static int fat_calc_dir_size(struct inode *inode)
#include <linux/blkdev.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/parser.h>
#include <linux/smp_lock.h>
#include <linux/vfs.h>
return 0;
}
+enum {
+ Opt_version, Opt_uid, Opt_gid, Opt_umask, Opt_part,
+ Opt_type, Opt_creator, Opt_quiet, Opt_afpd,
+ Opt_names_netatalk, Opt_names_trivial, Opt_names_alpha, Opt_names_latin,
+ Opt_names_7bit, Opt_names_8bit, Opt_names_cap,
+ Opt_fork_netatalk, Opt_fork_single, Opt_fork_double, Opt_fork_cap,
+ Opt_case_lower, Opt_case_asis,
+ Opt_conv_binary, Opt_conv_text, Opt_conv_auto,
+};
+
+static match_table_t tokens = {
+ {Opt_version, "version=%u"},
+ {Opt_uid, "uid=%u"},
+ {Opt_gid, "gid=%u"},
+ {Opt_umask, "umask=%o"},
+ {Opt_part, "part=%u"},
+ {Opt_type, "type=%s"},
+ {Opt_creator, "creator=%s"},
+ {Opt_quiet, "quiet"},
+ {Opt_afpd, "afpd"},
+ {Opt_names_netatalk, "names=netatalk"},
+ {Opt_names_trivial, "names=trivial"},
+ {Opt_names_alpha, "names=alpha"},
+ {Opt_names_latin, "names=latin"},
+ {Opt_names_7bit, "names=7bit"},
+ {Opt_names_8bit, "names=8bit"},
+ {Opt_names_cap, "names=cap"},
+ {Opt_names_netatalk, "names=n"},
+ {Opt_names_trivial, "names=t"},
+ {Opt_names_alpha, "names=a"},
+ {Opt_names_latin, "names=l"},
+ {Opt_names_7bit, "names=7"},
+ {Opt_names_8bit, "names=8"},
+ {Opt_names_cap, "names=c"},
+ {Opt_fork_netatalk, "fork=netatalk"},
+ {Opt_fork_single, "fork=single"},
+ {Opt_fork_double, "fork=double"},
+ {Opt_fork_cap, "fork=cap"},
+ {Opt_fork_netatalk, "fork=n"},
+ {Opt_fork_single, "fork=s"},
+ {Opt_fork_double, "fork=d"},
+ {Opt_fork_cap, "fork=c"},
+ {Opt_case_lower, "case=lower"},
+ {Opt_case_asis, "case=asis"},
+ {Opt_case_lower, "case=l"},
+ {Opt_case_asis, "case=a"},
+ {Opt_conv_binary, "conv=binary"},
+ {Opt_conv_text, "conv=text"},
+ {Opt_conv_auto, "conv=auto"},
+ {Opt_conv_binary, "conv=b"},
+ {Opt_conv_text, "conv=t"},
+ {Opt_conv_auto, "conv=a"},
+};
+
/*
* parse_options()
*
*/
static int parse_options(char *options, struct hfs_sb_info *hsb, int *part)
{
- char *this_char, *value;
+ char *p;
char names, fork;
+ substring_t args[MAX_OPT_ARGS];
+ int option;
/* initialize the sb with defaults */
memset(hsb, 0, sizeof(*hsb));
if (!options) {
goto done;
}
- while ((this_char = strsep(&options,",")) != NULL) {
- if (!*this_char)
+ while ((p = strsep(&options,",")) != NULL) {
+ int token;
+ if (!*p)
continue;
- if ((value = strchr(this_char,'=')) != NULL) {
- *value++ = 0;
- }
- /* Numeric-valued options */
- if (!strcmp(this_char, "version")) {
- if (!value || !*value) {
- return 0;
- }
- hsb->s_version = simple_strtoul(value,&value,0);
- if (*value) {
- return 0;
- }
- } else if (!strcmp(this_char,"uid")) {
- if (!value || !*value) {
- return 0;
- }
- hsb->s_uid = simple_strtoul(value,&value,0);
- if (*value) {
- return 0;
- }
- } else if (!strcmp(this_char,"gid")) {
- if (!value || !*value) {
- return 0;
- }
- hsb->s_gid = simple_strtoul(value,&value,0);
- if (*value) {
- return 0;
- }
- } else if (!strcmp(this_char,"umask")) {
- if (!value || !*value) {
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ /* Numeric-valued options */
+ case Opt_version:
+ if (match_int(&args[0], &option))
return 0;
- }
- hsb->s_umask = simple_strtoul(value,&value,8);
- if (*value) {
+ hsb->s_version = option;
+ break;
+ case Opt_uid:
+ if (match_int(&args[0], &option))
return 0;
- }
- } else if (!strcmp(this_char,"part")) {
- if (!value || !*value) {
+ hsb->s_uid = option;
+ break;
+ case Opt_gid:
+ if (match_int(&args[0], &option))
return 0;
- }
- *part = simple_strtoul(value,&value,0);
- if (*value) {
+ hsb->s_gid = option;
+ break;
+ case Opt_umask:
+ if (match_octal(&args[0], &option))
return 0;
- }
- /* String-valued options */
- } else if (!strcmp(this_char,"type") && value) {
- if (strlen(value) != 4) {
+ hsb->s_umask = option;
+ break;
+ case Opt_part:
+ if (match_int(&args[0], &option))
return 0;
- }
- hsb->s_type = hfs_get_nl(value);
- } else if (!strcmp(this_char,"creator") && value) {
- if (strlen(value) != 4) {
+ *part = option;
+ break;
+ /* String-valued options */
+ case Opt_type:
+ if (strlen(args[0].from) != 4) {
return 0;
}
- hsb->s_creator = hfs_get_nl(value);
- /* Boolean-valued options */
- } else if (!strcmp(this_char,"quiet")) {
- if (value) {
+ hsb->s_type = hfs_get_nl(args[0].from);
+ break;
+ case Opt_creator:
+ if (strlen(args[0].from) != 4) {
return 0;
}
+ hsb->s_creator = hfs_get_nl(args[0].from);
+ break;
+ /* Boolean-valued options */
+ case Opt_quiet:
hsb->s_quiet = 1;
- } else if (!strcmp(this_char,"afpd")) {
- if (value) {
- return 0;
- }
+ break;
+ case Opt_afpd:
hsb->s_afpd = 1;
- /* Multiple choice options */
- } else if (!strcmp(this_char,"names") && value) {
- if ((*value && !value[1] && strchr("ntal78c",*value)) ||
- !strcmp(value,"netatalk") ||
- !strcmp(value,"trivial") ||
- !strcmp(value,"alpha") ||
- !strcmp(value,"latin") ||
- !strcmp(value,"7bit") ||
- !strcmp(value,"8bit") ||
- !strcmp(value,"cap")) {
- names = *value;
- } else {
- return 0;
- }
- } else if (!strcmp(this_char,"fork") && value) {
- if ((*value && !value[1] && strchr("nsdc",*value)) ||
- !strcmp(value,"netatalk") ||
- !strcmp(value,"single") ||
- !strcmp(value,"double") ||
- !strcmp(value,"cap")) {
- fork = *value;
- } else {
- return 0;
- }
- } else if (!strcmp(this_char,"case") && value) {
- if ((*value && !value[1] && strchr("la",*value)) ||
- !strcmp(value,"lower") ||
- !strcmp(value,"asis")) {
- hsb->s_lowercase = (*value == 'l');
- } else {
- return 0;
- }
- } else if (!strcmp(this_char,"conv") && value) {
- if ((*value && !value[1] && strchr("bta",*value)) ||
- !strcmp(value,"binary") ||
- !strcmp(value,"text") ||
- !strcmp(value,"auto")) {
- hsb->s_conv = *value;
- } else {
- return 0;
- }
- } else {
+ break;
+ /* Multiple choice options */
+ case Opt_names_netatalk:
+ names = 'n';
+ break;
+ case Opt_names_trivial:
+ names = 't';
+ break;
+ case Opt_names_alpha:
+ names = 'a';
+ break;
+ case Opt_names_latin:
+ names = 'l';
+ break;
+ case Opt_names_7bit:
+ names = '7';
+ break;
+ case Opt_names_8bit:
+ names = '8';
+ break;
+ case Opt_names_cap:
+ names = 'c';
+ break;
+ case Opt_fork_netatalk:
+ fork = 'n';
+ break;
+ case Opt_fork_single:
+ fork = 's';
+ break;
+ case Opt_fork_double:
+ fork = 'd';
+ break;
+ case Opt_fork_cap:
+ fork = 'c';
+ break;
+ case Opt_case_lower:
+ hsb->s_lowercase = 1;
+ break;
+ case Opt_case_asis:
+ hsb->s_lowercase = 0;
+ break;
+ case Opt_conv_binary:
+ hsb->s_conv = 'b';
+ break;
+ case Opt_conv_text:
+ hsb->s_conv = 't';
+ break;
+ case Opt_conv_auto:
+ hsb->s_conv = 'a';
+ break;
+ default:
return 0;
}
}
#include <linux/string.h>
#include "hpfs_fn.h"
#include <linux/module.h>
+#include <linux/parser.h>
#include <linux/init.h>
#include <linux/vfs.h>
/*
* A tiny parser for option strings, stolen from dosfs.
- *
* Stolen again from read-only hpfs.
+ * And updated for table-driven option parsing.
*/
+enum {
+ Opt_help, Opt_uid, Opt_gid, Opt_umask, Opt_case_lower, Opt_case_asis,
+ Opt_conv_binary, Opt_conv_text, Opt_conv_auto,
+ Opt_check_none, Opt_check_normal, Opt_check_strict,
+ Opt_err_cont, Opt_err_ro, Opt_err_panic,
+ Opt_eas_no, Opt_eas_ro, Opt_eas_rw,
+ Opt_chkdsk_no, Opt_chkdsk_errors, Opt_chkdsk_always,
+ Opt_timeshift, Opt_err,
+};
+
+static match_table_t tokens = {
+ {Opt_help, "help"},
+ {Opt_uid, "uid=%u"},
+ {Opt_gid, "gid=%u"},
+ {Opt_umask, "umask=%o"},
+ {Opt_case_lower, "case=lower"},
+ {Opt_case_asis, "case=asis"},
+ {Opt_conv_binary, "conv=binary"},
+ {Opt_conv_text, "conv=text"},
+ {Opt_conv_auto, "conv=auto"},
+ {Opt_check_none, "check=none"},
+ {Opt_check_normal, "check=normal"},
+ {Opt_check_strict, "check=strict"},
+ {Opt_err_cont, "errors=continue"},
+ {Opt_err_ro, "errors=remount-ro"},
+ {Opt_err_panic, "errors=panic"},
+ {Opt_eas_no, "eas=no"},
+ {Opt_eas_ro, "eas=ro"},
+ {Opt_eas_rw, "eas=rw"},
+ {Opt_chkdsk_no, "chkdsk=no"},
+ {Opt_chkdsk_errors, "chkdsk=errors"},
+ {Opt_chkdsk_always, "chkdsk=always"},
+ {Opt_timeshift, "timeshift=%d"},
+ {Opt_err, NULL},
+};
+
int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask,
int *lowercase, int *conv, int *eas, int *chk, int *errs,
int *chkdsk, int *timeshift)
{
- char *p, *rhs;
+ char *p;
+ int option;
if (!opts)
return 1;
/*printk("Parsing opts: '%s'\n",opts);*/
while ((p = strsep(&opts, ",")) != NULL) {
+ substring_t args[MAX_OPT_ARGS];
+ int token;
if (!*p)
continue;
- if ((rhs = strchr(p, '=')) != 0)
- *rhs++ = '\0';
- if (!strcmp(p, "help")) return 2;
- if (!strcmp(p, "uid")) {
- if (!rhs || !*rhs)
- return 0;
- *uid = simple_strtoul(rhs, &rhs, 0);
- if (*rhs)
- return 0;
- }
- else if (!strcmp(p, "gid")) {
- if (!rhs || !*rhs)
- return 0;
- *gid = simple_strtoul(rhs, &rhs, 0);
- if (*rhs)
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_help:
+ return 2;
+ case Opt_uid:
+ if (match_int(args, &option))
return 0;
- }
- else if (!strcmp(p, "umask")) {
- if (!rhs || !*rhs)
+ *uid = option;
+ break;
+ case Opt_gid:
+ if (match_int(args, &option))
return 0;
- *umask = simple_strtoul(rhs, &rhs, 8);
- if (*rhs)
+ *gid = option;
+ break;
+ case Opt_umask:
+ if (match_octal(args, &option))
return 0;
- }
- else if (!strcmp(p, "timeshift")) {
+ *umask = option;
+ break;
+ case Opt_case_lower:
+ *lowercase = 1;
+ break;
+ case Opt_case_asis:
+ *lowercase = 0;
+ break;
+ case Opt_conv_binary:
+ *conv = CONV_BINARY;
+ break;
+ case Opt_conv_text:
+ *conv = CONV_TEXT;
+ break;
+ case Opt_conv_auto:
+ *conv = CONV_AUTO;
+ break;
+ case Opt_check_none:
+ *chk = 0;
+ break;
+ case Opt_check_normal:
+ *chk = 1;
+ break;
+ case Opt_check_strict:
+ *chk = 2;
+ break;
+ case Opt_err_cont:
+ *errs = 0;
+ break;
+ case Opt_err_ro:
+ *errs = 1;
+ break;
+ case Opt_err_panic:
+ *errs = 2;
+ break;
+ case Opt_eas_no:
+ *eas = 0;
+ break;
+ case Opt_eas_ro:
+ *eas = 1;
+ break;
+ case Opt_eas_rw:
+ *eas = 2;
+ break;
+ case Opt_chkdsk_no:
+ *chkdsk = 0;
+ break;
+ case Opt_chkdsk_errors:
+ *chkdsk = 1;
+ break;
+ case Opt_chkdsk_always:
+ *chkdsk = 2;
+ break;
+ case Opt_timeshift:
+ {
int m = 1;
+ char *rhs = args[0].from;
if (!rhs || !*rhs)
return 0;
if (*rhs == '-') m = -1;
*timeshift = simple_strtoul(rhs, &rhs, 0) * m;
if (*rhs)
return 0;
+ break;
}
- else if (!strcmp(p, "case")) {
- if (!rhs || !*rhs)
- return 0;
- if (!strcmp(rhs, "lower"))
- *lowercase = 1;
- else if (!strcmp(rhs, "asis"))
- *lowercase = 0;
- else
- return 0;
- }
- else if (!strcmp(p, "conv")) {
- if (!rhs || !*rhs)
- return 0;
- if (!strcmp(rhs, "binary"))
- *conv = CONV_BINARY;
- else if (!strcmp(rhs, "text"))
- *conv = CONV_TEXT;
- else if (!strcmp(rhs, "auto"))
- *conv = CONV_AUTO;
- else
- return 0;
- }
- else if (!strcmp(p, "check")) {
- if (!rhs || !*rhs)
- return 0;
- if (!strcmp(rhs, "none"))
- *chk = 0;
- else if (!strcmp(rhs, "normal"))
- *chk = 1;
- else if (!strcmp(rhs, "strict"))
- *chk = 2;
- else
- return 0;
- }
- else if (!strcmp(p, "errors")) {
- if (!rhs || !*rhs)
- return 0;
- if (!strcmp(rhs, "continue"))
- *errs = 0;
- else if (!strcmp(rhs, "remount-ro"))
- *errs = 1;
- else if (!strcmp(rhs, "panic"))
- *errs = 2;
- else
- return 0;
- }
- else if (!strcmp(p, "eas")) {
- if (!rhs || !*rhs)
- return 0;
- if (!strcmp(rhs, "no"))
- *eas = 0;
- else if (!strcmp(rhs, "ro"))
- *eas = 1;
- else if (!strcmp(rhs, "rw"))
- *eas = 2;
- else
- return 0;
- }
- else if (!strcmp(p, "chkdsk")) {
- if (!rhs || !*rhs)
- return 0;
- if (!strcmp(rhs, "no"))
- *chkdsk = 0;
- else if (!strcmp(rhs, "errors"))
- *chkdsk = 1;
- else if (!strcmp(rhs, "always"))
- *chkdsk = 2;
- else
- return 0;
- }
- else
+ default:
return 0;
+ }
}
return 1;
}
#include <linux/blkdev.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
+#include <linux/parser.h>
#include <asm/system.h>
#include <asm/uaccess.h>
}
#endif
+enum {
+ Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore,
+ Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet,
+ Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err,
+ Opt_nocompress,
+};
+
+static match_table_t tokens = {
+ {Opt_norock, "norock"},
+ {Opt_nojoliet, "nojoliet"},
+ {Opt_unhide, "unhide"},
+ {Opt_cruft, "cruft"},
+ {Opt_utf8, "utf8"},
+ {Opt_iocharset, "iocharset=%s"},
+ {Opt_map_a, "map=acorn"},
+ {Opt_map_a, "map=a"},
+ {Opt_map_n, "map=normal"},
+ {Opt_map_n, "map=n"},
+ {Opt_map_o, "map=off"},
+ {Opt_map_o, "map=o"},
+ {Opt_session, "session=%u"},
+ {Opt_sb, "sbsector=%u"},
+ {Opt_check_r, "check=relaxed"},
+ {Opt_check_r, "check=r"},
+ {Opt_check_s, "check=strict"},
+ {Opt_check_s, "check=s"},
+ {Opt_uid, "uid=%u"},
+ {Opt_gid, "gid=%u"},
+ {Opt_mode, "mode=%u"},
+ {Opt_block, "block=%u"},
+ {Opt_ignore, "conv=binary"},
+ {Opt_ignore, "conv=b"},
+ {Opt_ignore, "conv=text"},
+ {Opt_ignore, "conv=t"},
+ {Opt_ignore, "conv=mtext"},
+ {Opt_ignore, "conv=m"},
+ {Opt_ignore, "conv=auto"},
+ {Opt_ignore, "conv=a"},
+ {Opt_nocompress, "nocompress"},
+ {Opt_err, NULL}
+};
+
static int parse_options(char *options, struct iso9660_options * popt)
{
- char *this_char,*value;
+ char *p;
+ int option;
popt->map = 'n';
popt->rock = 'y';
popt->utf8 = 0;
popt->session=-1;
popt->sbsector=-1;
- if (!options) return 1;
- while ((this_char = strsep(&options,",")) != NULL) {
- if (!*this_char)
+ if (!options)
+ return 1;
+
+ while ((p = strsep(&options, ",")) != NULL) {
+ int token;
+ substring_t args[MAX_OPT_ARGS];
+ unsigned n;
+
+ if (!*p)
continue;
- if (strncmp(this_char,"norock",6) == 0) {
- popt->rock = 'n';
- continue;
- }
- if (strncmp(this_char,"nojoliet",8) == 0) {
- popt->joliet = 'n';
- continue;
- }
- if (strncmp(this_char,"unhide",6) == 0) {
- popt->unhide = 'y';
- continue;
- }
- if (strncmp(this_char,"cruft",5) == 0) {
- popt->cruft = 'y';
- continue;
- }
- if (strncmp(this_char,"utf8",4) == 0) {
- popt->utf8 = 1;
- continue;
- }
- if (strncmp(this_char,"nocompress",10) == 0) {
- popt->nocompress = 1;
- continue;
- }
- if ((value = strchr(this_char,'=')) != NULL)
- *value++ = 0;
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_norock:
+ popt->rock = 'n';
+ break;
+ case Opt_nojoliet:
+ popt->joliet = 'n';
+ break;
+ case Opt_unhide:
+ popt->unhide = 'y';
+ break;
+ case Opt_cruft:
+ popt->cruft = 'y';
+ break;
+ case Opt_utf8:
+ popt->utf8 = 1;
+ break;
#ifdef CONFIG_JOLIET
- if (!strcmp(this_char,"iocharset") && value) {
- popt->iocharset = value;
- while (*value && *value != ',')
- value++;
- if (value == popt->iocharset)
- return 0;
- *value = 0;
- } else
+ case Opt_iocharset:
+ popt->iocharset = match_strdup(&args[0]);
+ break;
#endif
- if (!strcmp(this_char,"map") && value) {
- if (value[0] && !value[1] && strchr("ano",*value))
- popt->map = *value;
- else if (!strcmp(value,"off")) popt->map = 'o';
- else if (!strcmp(value,"normal")) popt->map = 'n';
- else if (!strcmp(value,"acorn")) popt->map = 'a';
- else return 0;
- }
- if (!strcmp(this_char,"session") && value) {
- char * vpnt = value;
- unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);
- if(ivalue < 0 || ivalue >99) return 0;
- popt->session=ivalue+1;
- }
- if (!strcmp(this_char,"sbsector") && value) {
- char * vpnt = value;
- unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);
- if(ivalue < 0 || ivalue >660*512) return 0;
- popt->sbsector=ivalue;
- }
- else if (!strcmp(this_char,"check") && value) {
- if (value[0] && !value[1] && strchr("rs",*value))
- popt->check = *value;
- else if (!strcmp(value,"relaxed")) popt->check = 'r';
- else if (!strcmp(value,"strict")) popt->check = 's';
- else return 0;
- }
- else if (!strcmp(this_char,"conv") && value) {
- /* no conversion is done anymore;
- we still accept the same mount options,
- but ignore them */
- if (value[0] && !value[1] && strchr("btma",*value)) ;
- else if (!strcmp(value,"binary")) ;
- else if (!strcmp(value,"text")) ;
- else if (!strcmp(value,"mtext")) ;
- else if (!strcmp(value,"auto")) ;
- else return 0;
- }
- else if (value &&
- (!strcmp(this_char,"block") ||
- !strcmp(this_char,"mode") ||
- !strcmp(this_char,"uid") ||
- !strcmp(this_char,"gid"))) {
- char * vpnt = value;
- unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);
- if (*vpnt) return 0;
- switch(*this_char) {
- case 'b':
- if ( ivalue != 512
- && ivalue != 1024
- && ivalue != 2048) return 0;
- popt->blocksize = ivalue;
- break;
- case 'u':
- popt->uid = ivalue;
- break;
- case 'g':
- popt->gid = ivalue;
- break;
- case 'm':
- popt->mode = ivalue;
- break;
- }
+ case Opt_map_a:
+ popt->map = 'a';
+ break;
+ case Opt_map_o:
+ popt->map = 'o';
+ break;
+ case Opt_map_n:
+ popt->map = 'n';
+ break;
+ case Opt_session:
+ if (match_int(&args[0], &option))
+ return 0;
+ n = option;
+ if (n > 99)
+ return 0;
+ popt->session = n + 1;
+ break;
+ case Opt_sb:
+ if (match_int(&args[0], &option))
+ return 0;
+ n = option;
+ if (n > 660 * 512)
+ return 0;
+ popt->sbsector = n;
+ break;
+ case Opt_check_r:
+ popt->check = 'r';
+ break;
+ case Opt_check_s:
+ popt->check = 's';
+ break;
+ case Opt_ignore:
+ break;
+ case Opt_uid:
+ if (match_int(&args[0], &option))
+ return 0;
+ popt->uid = option;
+ break;
+ case Opt_gid:
+ if (match_int(&args[0], &option))
+ return 0;
+ popt->gid = option;
+ break;
+ case Opt_mode:
+ if (match_int(&args[0], &option))
+ return 0;
+ popt->mode = option;
+ break;
+ case Opt_block:
+ if (match_int(&args[0], &option))
+ return 0;
+ n = option;
+ if (n != 512 && n != 1024 && n != 2048)
+ return 0;
+ popt->blocksize = n;
+ break;
+ case Opt_nocompress:
+ popt->nocompress = 1;
+ break;
+ default:
+ return 0;
}
- else return 1;
}
return 1;
}
if (opt.check == 'r') table++;
s->s_root->d_op = &isofs_dentry_ops[table];
+ if (opt.iocharset)
+ kfree(opt.iocharset);
+
return 0;
/*
out_freebh:
brelse(bh);
out_freesbi:
+ if (opt.iocharset)
+ kfree(opt.iocharset);
kfree(sbi);
s->s_fs_info = NULL;
return -EINVAL;
#include <linux/fs.h>
#include <linux/config.h>
#include <linux/module.h>
+#include <linux/parser.h>
#include <linux/completion.h>
#include <linux/vfs.h>
#include <asm/uaccess.h>
kfree(sbi);
}
+enum {
+ Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
+ Opt_ignore, Opt_err,
+};
+
+static match_table_t tokens = {
+ {Opt_integrity, "integrity"},
+ {Opt_nointegrity, "nointegrity"},
+ {Opt_iocharset, "iocharset=%s"},
+ {Opt_resize, "resize=%u"},
+ {Opt_ignore, "noquota"},
+ {Opt_ignore, "quota"},
+ {Opt_ignore, "usrquota"},
+ {Opt_ignore, "grpquota"},
+ {Opt_err, NULL}
+};
+
static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
int *flag)
{
void *nls_map = NULL;
- char *this_char;
- char *value;
+ char *p;
struct jfs_sb_info *sbi = JFS_SBI(sb);
*newLVSize = 0;
if (!options)
return 1;
- while ((this_char = strsep(&options, ",")) != NULL) {
- if (!*this_char)
+
+ while ((p = strsep(&options, ",")) != NULL) {
+ substring_t args[MAX_OPT_ARGS];
+ int token;
+ if (!*p)
continue;
- if ((value = strchr(this_char, '=')) != NULL)
- *value++ = 0;
- if (!strcmp(this_char, "integrity")) {
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_integrity:
*flag &= ~JFS_NOINTEGRITY;
- } else if (!strcmp(this_char, "nointegrity")) {
+ break;
+ case Opt_nointegrity:
*flag |= JFS_NOINTEGRITY;
- } else if (!strcmp(this_char, "iocharset")) {
- if (!value || !*value)
- goto needs_arg;
+ break;
+ case Opt_ignore:
+ /* Silently ignore the quota options */
+ /* Don't do anything ;-) */
+ break;
+ case Opt_iocharset:
if (nls_map) /* specified iocharset twice! */
unload_nls(nls_map);
- nls_map = load_nls(value);
+ nls_map = load_nls(args[0].from);
if (!nls_map) {
printk(KERN_ERR "JFS: charset not found\n");
goto cleanup;
}
- } else if (!strcmp(this_char, "resize")) {
- if (!value || !*value) {
+ break;
+ case Opt_resize:
+ {
+ char *resize = args[0].from;
+ if (!resize || !*resize) {
*newLVSize = sb->s_bdev->bd_inode->i_size >>
sb->s_blocksize_bits;
if (*newLVSize == 0)
printk(KERN_ERR
- "JFS: Cannot determine volume size\n");
+ "JFS: Cannot determine volume size\n");
} else
- *newLVSize = simple_strtoull(value, &value, 0);
-
- /* Silently ignore the quota options */
- } else if (!strcmp(this_char, "grpquota")
- || !strcmp(this_char, "noquota")
- || !strcmp(this_char, "quota")
- || !strcmp(this_char, "usrquota"))
- /* Don't do anything ;-) */ ;
- else {
- printk("jfs: Unrecognized mount option %s\n",
- this_char);
+ *newLVSize = simple_strtoull(resize, &resize, 0);
+ break;
+ }
+ default:
+ printk("jfs: Unrecognized mount option \"%s\" "
+ " or missing value\n", p);
goto cleanup;
}
}
+
if (nls_map) {
/* Discard old (if remount) */
if (sbi->nls_tab)
sbi->nls_tab = nls_map;
}
return 1;
-needs_arg:
- printk(KERN_ERR "JFS: %s needs an argument\n", this_char);
+
cleanup:
if (nls_map)
unload_nls(nls_map);
#include <linux/limits.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/parser.h>
#include <linux/smp_lock.h>
#include <asm/system.h>
.statfs = simple_statfs,
};
+enum {
+ Opt_uid, Opt_gid, Opt_err
+};
+
+static match_table_t tokens = {
+ {Opt_uid, "uid=%u"},
+ {Opt_gid, "gid=%u"},
+ {Opt_err, NULL}
+};
+
static int parse_options(char *options,uid_t *uid,gid_t *gid)
{
- char *this_char,*value;
+ char *p;
+ int option;
*uid = current->uid;
*gid = current->gid;
if (!options)
return 1;
- while ((this_char = strsep(&options,",")) != NULL) {
- if (!*this_char)
+
+ while ((p = strsep(&options, ",")) != NULL) {
+ substring_t args[MAX_OPT_ARGS];
+ int token;
+ if (!*p)
continue;
- if ((value = strchr(this_char,'=')) != NULL)
- *value++ = 0;
- if (!strcmp(this_char,"uid")) {
- if (!value || !*value)
- return 0;
- *uid = simple_strtoul(value,&value,0);
- if (*value)
- return 0;
- }
- else if (!strcmp(this_char,"gid")) {
- if (!value || !*value)
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_uid:
+ if (match_int(args, &option))
return 0;
- *gid = simple_strtoul(value,&value,0);
- if (*value)
+ *uid = option;
+ break;
+ case Opt_gid:
+ if (match_int(args, &option))
return 0;
+ *gid = option;
+ break;
+ default:
+ return 0;
}
- else return 1;
}
return 1;
}
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/parser.h>
#include <linux/stat.h>
#include <linux/cdrom.h>
#include <linux/nls.h>
* gid= Set the default group.
* umask= Set the default umask.
* uid= Set the default user.
- * bs= Set the block size.
+ * bs= Set the block size.
* unhide Show otherwise hidden files.
* undelete Show deleted files in lists.
* adinicb Embed data in the inode (default)
* uopts Pointer to mount options variable.
*
* POST-CONDITIONS
- * <return> 0 Mount options parsed okay.
- * <return> -1 Error parsing mount options.
+ * <return> 1 Mount options parsed okay.
+ * <return> 0 Error parsing mount options.
*
* HISTORY
* July 1, 1997 - Andrew E. Mileski
* Written, tested, and released.
*/
+enum {
+ Opt_novrs, Opt_nostrict, Opt_bs, Opt_unhide, Opt_undelete,
+ Opt_noadinicb, Opt_adinicb, Opt_shortad, Opt_longad,
+ Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
+ Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
+ Opt_rootdir, Opt_utf8, Opt_iocharset,
+ Opt_err
+};
+
+static match_table_t tokens = {
+ {Opt_novrs, "novrs"},
+ {Opt_nostrict, "nostrict"},
+ {Opt_bs, "bs=%u"},
+ {Opt_unhide, "unhide"},
+ {Opt_undelete, "undelete"},
+ {Opt_noadinicb, "noadinicb"},
+ {Opt_adinicb, "adinicb"},
+ {Opt_shortad, "shortad"},
+ {Opt_longad, "longad"},
+ {Opt_gid, "gid=%u"},
+ {Opt_uid, "uid=%u"},
+ {Opt_umask, "umask=%o"},
+ {Opt_session, "session=%u"},
+ {Opt_lastblock, "lastblock=%u"},
+ {Opt_anchor, "anchor=%u"},
+ {Opt_volume, "volume=%u"},
+ {Opt_partition, "partition=%u"},
+ {Opt_fileset, "fileset=%u"},
+ {Opt_rootdir, "rootdir=%u"},
+ {Opt_utf8, "utf8"},
+ {Opt_iocharset, "iocharset=%s"},
+ {Opt_err, NULL}
+};
+
static int
udf_parse_options(char *options, struct udf_options *uopt)
{
- char *opt, *val;
+ char *p;
+ int option;
uopt->novrs = 0;
uopt->blocksize = 2048;
if (!options)
return 1;
- while ((opt = strsep(&options, ",")) != NULL)
- {
- if (!*opt)
+ while ((p = strsep(&options, ",")) != NULL) {
+ substring_t args[MAX_OPT_ARGS];
+ int token;
+ if (!*p)
continue;
- /* Make "opt=val" into two strings */
- val = strchr(opt, '=');
- if (val)
- *(val++) = 0;
- if (!strcmp(opt, "novrs") && !val)
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_novrs:
uopt->novrs = 1;
- else if (!strcmp(opt, "bs") && val)
- uopt->blocksize = simple_strtoul(val, NULL, 0);
- else if (!strcmp(opt, "unhide") && !val)
+ break;
+ case Opt_bs:
+ if (match_int(&args[0], &option))
+ return 0;
+ uopt->blocksize = option;
+ break;
+ case Opt_unhide:
uopt->flags |= (1 << UDF_FLAG_UNHIDE);
- else if (!strcmp(opt, "undelete") && !val)
+ break;
+ case Opt_undelete:
uopt->flags |= (1 << UDF_FLAG_UNDELETE);
- else if (!strcmp(opt, "noadinicb") && !val)
+ break;
+ case Opt_noadinicb:
uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB);
- else if (!strcmp(opt, "adinicb") && !val)
+ break;
+ case Opt_adinicb:
uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB);
- else if (!strcmp(opt, "shortad") && !val)
+ break;
+ case Opt_shortad:
uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD);
- else if (!strcmp(opt, "longad") && !val)
+ break;
+ case Opt_longad:
uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD);
- else if (!strcmp(opt, "gid") && val)
- uopt->gid = simple_strtoul(val, NULL, 0);
- else if (!strcmp(opt, "umask") && val)
- uopt->umask = simple_strtoul(val, NULL, 0);
- else if (!strcmp(opt, "nostrict") && !val)
+ break;
+ case Opt_gid:
+ if (match_int(args, &option))
+ return 0;
+ uopt->gid = option;
+ break;
+ case Opt_uid:
+ if (match_int(args, &option))
+ return 0;
+ uopt->uid = option;
+ break;
+ case Opt_umask:
+ if (match_octal(args, &option))
+ return 0;
+ uopt->umask = option;
+ break;
+ case Opt_nostrict:
uopt->flags &= ~(1 << UDF_FLAG_STRICT);
- else if (!strcmp(opt, "uid") && val)
- uopt->uid = simple_strtoul(val, NULL, 0);
- else if (!strcmp(opt, "session") && val)
- uopt->session = simple_strtoul(val, NULL, 0);
- else if (!strcmp(opt, "lastblock") && val)
- uopt->lastblock = simple_strtoul(val, NULL, 0);
- else if (!strcmp(opt, "anchor") && val)
- uopt->anchor = simple_strtoul(val, NULL, 0);
- else if (!strcmp(opt, "volume") && val)
- uopt->volume = simple_strtoul(val, NULL, 0);
- else if (!strcmp(opt, "partition") && val)
- uopt->partition = simple_strtoul(val, NULL, 0);
- else if (!strcmp(opt, "fileset") && val)
- uopt->fileset = simple_strtoul(val, NULL, 0);
- else if (!strcmp(opt, "rootdir") && val)
- uopt->rootdir = simple_strtoul(val, NULL, 0);
+ break;
+ case Opt_session:
+ if (match_int(args, &option))
+ return 0;
+ uopt->session = option;
+ break;
+ case Opt_lastblock:
+ if (match_int(args, &option))
+ return 0;
+ uopt->lastblock = option;
+ break;
+ case Opt_anchor:
+ if (match_int(args, &option))
+ return 0;
+ uopt->anchor = option;
+ break;
+ case Opt_volume:
+ if (match_int(args, &option))
+ return 0;
+ uopt->volume = option;
+ break;
+ case Opt_partition:
+ if (match_int(args, &option))
+ return 0;
+ uopt->partition = option;
+ break;
+ case Opt_fileset:
+ if (match_int(args, &option))
+ return 0;
+ uopt->fileset = option;
+ break;
+ case Opt_rootdir:
+ if (match_int(args, &option))
+ return 0;
+ uopt->rootdir = option;
+ break;
+ case Opt_utf8:
+ uopt->flags |= (1 << UDF_FLAG_UTF8);
+ break;
#ifdef CONFIG_NLS
- else if (!strcmp(opt, "iocharset") && val)
- {
- uopt->nls_map = load_nls(val);
+ case Opt_iocharset:
+ uopt->nls_map = load_nls(args[0].from);
uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
- }
+ break;
#endif
- else if (!strcmp(opt, "utf8") && !val)
- uopt->flags |= (1 << UDF_FLAG_UTF8);
- else if (val)
- {
- printk(KERN_ERR "udf: bad mount option \"%s=%s\"\n",
- opt, val);
- return 0;
- }
- else
- {
- printk(KERN_ERR "udf: bad mount option \"%s\"\n",
- opt);
+ default:
+ printk(KERN_ERR "udf: bad mount option \"%s\" "
+ "or missing value\n",
+ p);
return 0;
}
}
#include <linux/string.h>
#include <linux/blkdev.h>
#include <linux/init.h>
+#include <linux/parser.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
sb->s_id, function, error_buf);
}
+enum {
+ Opt_type_old, Opt_type_sunx86, Opt_type_sun, Opt_type_44bsd,
+ Opt_type_hp, Opt_type_nextstepcd, Opt_type_nextstep,
+ Opt_type_openstep, Opt_onerror_panic, Opt_onerror_lock,
+ Opt_onerror_umount, Opt_onerror_repair, Opt_err
+};
+
+static match_table_t tokens = {
+ {Opt_type_old, "ufstype=old"},
+ {Opt_type_sunx86, "ufstype=sunx86"},
+ {Opt_type_sun, "ufstype=sun"},
+ {Opt_type_44bsd, "ufstype=44bsd"},
+ {Opt_type_hp, "ufstype=hp"},
+ {Opt_type_nextstepcd, "ufstype=nextstep-cd"},
+ {Opt_type_nextstep, "ufstype=nextstep"},
+ {Opt_type_openstep, "ufstype=openstep"},
+ {Opt_onerror_panic, "onerror=panic"},
+ {Opt_onerror_lock, "onerror=lock"},
+ {Opt_onerror_umount, "onerror=umount"},
+ {Opt_onerror_repair, "onerror=repair"},
+ {Opt_err, NULL}
+};
+
static int ufs_parse_options (char * options, unsigned * mount_options)
{
- char * this_char;
- char * value;
+ char * p;
UFSD(("ENTER\n"))
if (!options)
return 1;
- while ((this_char = strsep (&options, ",")) != NULL) {
- if (!*this_char)
+ while ((p = strsep(&options, ",")) != NULL) {
+ substring_t args[MAX_OPT_ARGS];
+ int token;
+ if (!*p)
continue;
- if ((value = strchr (this_char, '=')) != NULL)
- *value++ = 0;
- if (!strcmp (this_char, "ufstype")) {
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_type_old:
ufs_clear_opt (*mount_options, UFSTYPE);
- if (!strcmp (value, "old"))
- ufs_set_opt (*mount_options, UFSTYPE_OLD);
- else if (!strcmp (value, "sun"))
- ufs_set_opt (*mount_options, UFSTYPE_SUN);
- else if (!strcmp (value, "44bsd"))
- ufs_set_opt (*mount_options, UFSTYPE_44BSD);
- else if (!strcmp (value, "nextstep"))
- ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP);
- else if (!strcmp (value, "nextstep-cd"))
- ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP_CD);
- else if (!strcmp (value, "openstep"))
- ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP);
- else if (!strcmp (value, "sunx86"))
- ufs_set_opt (*mount_options, UFSTYPE_SUNx86);
- else if (!strcmp (value, "hp"))
- ufs_set_opt (*mount_options, UFSTYPE_HP);
- else {
- printk ("UFS-fs: Invalid type option: %s\n", value);
- return 0;
- }
- }
- else if (!strcmp (this_char, "onerror")) {
+ ufs_set_opt (*mount_options, UFSTYPE_OLD);
+ break;
+ case Opt_type_sunx86:
+ ufs_clear_opt (*mount_options, UFSTYPE);
+ ufs_set_opt (*mount_options, UFSTYPE_SUNx86);
+ break;
+ case Opt_type_sun:
+ ufs_clear_opt (*mount_options, UFSTYPE);
+ ufs_set_opt (*mount_options, UFSTYPE_SUN);
+ break;
+ case Opt_type_44bsd:
+ ufs_clear_opt (*mount_options, UFSTYPE);
+ ufs_set_opt (*mount_options, UFSTYPE_44BSD);
+ break;
+ case Opt_type_hp:
+ ufs_clear_opt (*mount_options, UFSTYPE);
+ ufs_set_opt (*mount_options, UFSTYPE_HP);
+ break;
+ case Opt_type_nextstepcd:
+ ufs_clear_opt (*mount_options, UFSTYPE);
+ ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP_CD);
+ break;
+ case Opt_type_nextstep:
+ ufs_clear_opt (*mount_options, UFSTYPE);
+ ufs_set_opt (*mount_options, UFSTYPE_NEXTSTEP);
+ break;
+ case Opt_type_openstep:
+ ufs_clear_opt (*mount_options, UFSTYPE);
+ ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP);
+ break;
+ case Opt_onerror_panic:
ufs_clear_opt (*mount_options, ONERROR);
- if (!strcmp (value, "panic"))
- ufs_set_opt (*mount_options, ONERROR_PANIC);
- else if (!strcmp (value, "lock"))
- ufs_set_opt (*mount_options, ONERROR_LOCK);
- else if (!strcmp (value, "umount"))
- ufs_set_opt (*mount_options, ONERROR_UMOUNT);
- else if (!strcmp (value, "repair")) {
- printk("UFS-fs: Unable to do repair on error, "
- "will lock lock instead \n");
- ufs_set_opt (*mount_options, ONERROR_REPAIR);
- }
- else {
- printk ("UFS-fs: Invalid action onerror: %s\n", value);
- return 0;
- }
- }
- else {
- printk("UFS-fs: Invalid option: %s\n", this_char);
+ ufs_set_opt (*mount_options, ONERROR_PANIC);
+ break;
+ case Opt_onerror_lock:
+ ufs_clear_opt (*mount_options, ONERROR);
+ ufs_set_opt (*mount_options, ONERROR_LOCK);
+ break;
+ case Opt_onerror_umount:
+ ufs_clear_opt (*mount_options, ONERROR);
+ ufs_set_opt (*mount_options, ONERROR_UMOUNT);
+ break;
+ case Opt_onerror_repair:
+ printk("UFS-fs: Unable to do repair on error, "
+ "will lock lock instead\n");
+ ufs_clear_opt (*mount_options, ONERROR);
+ ufs_set_opt (*mount_options, ONERROR_REPAIR);
+ break;
+ default:
+ printk("UFS-fs: Invalid option: \"%s\" "
+ "or missing value\n", p);
return 0;
}
}
--- /dev/null
+struct match_token {
+ int token;
+ char *pattern;
+};
+
+typedef struct match_token match_table_t[];
+
+enum {MAX_OPT_ARGS = 3};
+
+typedef struct {
+ char *from;
+ char *to;
+} substring_t;
+
+int match_token(char *s, match_table_t table, substring_t args[]);
+
+int match_int(substring_t *, int *result);
+int match_octal(substring_t *, int *result);
+int match_hex(substring_t *, int *result);
+void match_strcpy(char *, substring_t *);
+char *match_strdup(substring_t *);
lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
- kobject.o idr.o div64.o
+ kobject.o idr.o div64.o parser.o
lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
--- /dev/null
+/*
+ * lib/parser.c - simple parser for mount, etc. options.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/parser.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+static int match_one(char *s, char *p, substring_t args[])
+{
+ char *meta;
+ int argc = 0;
+
+ if (!p)
+ return 1;
+
+ while(1) {
+ int len = -1;
+ meta = strchr(p, '%');
+ if (!meta)
+ return strcmp(p, s) == 0;
+
+ if (strncmp(p, s, meta-p))
+ return 0;
+
+ s += meta - p;
+ p = meta + 1;
+
+ if (isdigit(*p))
+ len = simple_strtoul(p, &p, 10);
+ else if (*p == '%') {
+ if (*s++ != '%')
+ return 0;
+ continue;
+ }
+
+ if (argc >= MAX_OPT_ARGS)
+ return 0;
+
+ args[argc].from = s;
+ switch (*p++) {
+ case 's':
+ if (len == -1 || len > strlen(s))
+ len = strlen(s);
+ args[argc].to = s + len;
+ break;
+ case 'd':
+ simple_strtol(s, &args[argc].to, 0);
+ goto num;
+ case 'u':
+ simple_strtoul(s, &args[argc].to, 0);
+ goto num;
+ case 'o':
+ simple_strtoul(s, &args[argc].to, 8);
+ goto num;
+ case 'x':
+ simple_strtoul(s, &args[argc].to, 16);
+ num:
+ if (args[argc].to == args[argc].from)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ s = args[argc].to;
+ argc++;
+ }
+}
+
+int match_token(char *s, match_table_t table, substring_t args[])
+{
+ struct match_token *p;
+
+ for (p = table; !match_one(s, p->pattern, args) ; p++)
+ ;
+
+ return p->token;
+}
+
+static int match_number(substring_t *s, int *result, int base)
+{
+ char *endp;
+ char *buf;
+ int ret;
+
+ buf = kmalloc(s->to - s->from + 1, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ memcpy(buf, s->from, s->to - s->from);
+ buf[s->to - s->from] = '\0';
+ *result = simple_strtol(buf, &endp, base);
+ ret = 0;
+ if (endp == buf)
+ ret = -EINVAL;
+ kfree(buf);
+ return ret;
+}
+
+int match_int(substring_t *s, int *result)
+{
+ return match_number(s, result, 0);
+}
+
+int match_octal(substring_t *s, int *result)
+{
+ return match_number(s, result, 8);
+}
+
+int match_hex(substring_t *s, int *result)
+{
+ return match_number(s, result, 16);
+}
+
+void match_strcpy(char *to, substring_t *s)
+{
+ memcpy(to, s->from, s->to - s->from);
+ to[s->to - s->from] = '\0';
+}
+
+char *match_strdup(substring_t *s)
+{
+ char *p = kmalloc(s->to - s->from + 1, GFP_KERNEL);
+ if (p)
+ match_strcpy(p, s);
+ return p;
+}
+
+EXPORT_SYMBOL(match_token);
+EXPORT_SYMBOL(match_int);
+EXPORT_SYMBOL(match_octal);
+EXPORT_SYMBOL(match_hex);
+EXPORT_SYMBOL(match_strcpy);
+EXPORT_SYMBOL(match_strdup);