Loading drivers/md/dm-crypt.c +3 −4 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ #include <linux/device-mapper.h> #define DM_MSG_PREFIX "crypt" #define MESG_STR(x) x, sizeof(x) /* * context holding the current state of a multi-part conversion Loading Loading @@ -1770,12 +1769,12 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) if (argc < 2) goto error; if (!strnicmp(argv[0], MESG_STR("key"))) { if (!strcasecmp(argv[0], "key")) { if (!test_bit(DM_CRYPT_SUSPENDED, &cc->flags)) { DMWARN("not suspended during key manipulation."); return -EINVAL; } if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) { if (argc == 3 && !strcasecmp(argv[1], "set")) { ret = crypt_set_key(cc, argv[2]); if (ret) return ret; Loading @@ -1783,7 +1782,7 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) ret = cc->iv_gen_ops->init(cc); return ret; } if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) { if (argc == 2 && !strcasecmp(argv[1], "wipe")) { if (cc->iv_gen_ops && cc->iv_gen_ops->wipe) { ret = cc->iv_gen_ops->wipe(cc); if (ret) Loading drivers/md/dm-mpath.c +44 −108 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ #include <linux/atomic.h> #define DM_MSG_PREFIX "multipath" #define MESG_STR(x) x, sizeof(x) #define DM_PG_INIT_DELAY_MSECS 2000 #define DM_PG_INIT_DELAY_DEFAULT ((unsigned) -1) Loading Loading @@ -505,80 +504,29 @@ static void trigger_event(struct work_struct *work) * <#paths> <#per-path selector args> * [<path> [<arg>]* ]+ ]+ *---------------------------------------------------------------*/ struct param { unsigned min; unsigned max; char *error; }; static int read_param(struct param *param, char *str, unsigned *v, char **error) { if (!str || (sscanf(str, "%u", v) != 1) || (*v < param->min) || (*v > param->max)) { *error = param->error; return -EINVAL; } return 0; } struct arg_set { unsigned argc; char **argv; }; static char *shift(struct arg_set *as) { char *r; if (as->argc) { as->argc--; r = *as->argv; as->argv++; return r; } return NULL; } static void consume(struct arg_set *as, unsigned n) { BUG_ON (as->argc < n); as->argc -= n; as->argv += n; } static int parse_path_selector(struct arg_set *as, struct priority_group *pg, static int parse_path_selector(struct dm_arg_set *as, struct priority_group *pg, struct dm_target *ti) { int r; struct path_selector_type *pst; unsigned ps_argc; static struct param _params[] = { static struct dm_arg _args[] = { {0, 1024, "invalid number of path selector args"}, }; pst = dm_get_path_selector(shift(as)); pst = dm_get_path_selector(dm_shift_arg(as)); if (!pst) { ti->error = "unknown path selector type"; return -EINVAL; } r = read_param(_params, shift(as), &ps_argc, &ti->error); r = dm_read_arg_group(_args, as, &ps_argc, &ti->error); if (r) { dm_put_path_selector(pst); return -EINVAL; } if (ps_argc > as->argc) { dm_put_path_selector(pst); ti->error = "not enough arguments for path selector"; return -EINVAL; } r = pst->create(&pg->ps, ps_argc, as->argv); if (r) { dm_put_path_selector(pst); Loading @@ -587,12 +535,12 @@ static int parse_path_selector(struct arg_set *as, struct priority_group *pg, } pg->ps.type = pst; consume(as, ps_argc); dm_consume_args(as, ps_argc); return 0; } static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps, struct dm_target *ti) { int r; Loading @@ -609,7 +557,7 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, if (!p) return ERR_PTR(-ENOMEM); r = dm_get_device(ti, shift(as), dm_table_get_mode(ti->table), r = dm_get_device(ti, dm_shift_arg(as), dm_table_get_mode(ti->table), &p->path.dev); if (r) { ti->error = "error getting device"; Loading Loading @@ -660,16 +608,16 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, return ERR_PTR(r); } static struct priority_group *parse_priority_group(struct arg_set *as, static struct priority_group *parse_priority_group(struct dm_arg_set *as, struct multipath *m) { static struct param _params[] = { static struct dm_arg _args[] = { {1, 1024, "invalid number of paths"}, {0, 1024, "invalid number of selector args"} }; int r; unsigned i, nr_selector_args, nr_params; unsigned i, nr_selector_args, nr_args; struct priority_group *pg; struct dm_target *ti = m->ti; Loading @@ -693,26 +641,26 @@ static struct priority_group *parse_priority_group(struct arg_set *as, /* * read the paths */ r = read_param(_params, shift(as), &pg->nr_pgpaths, &ti->error); r = dm_read_arg(_args, as, &pg->nr_pgpaths, &ti->error); if (r) goto bad; r = read_param(_params + 1, shift(as), &nr_selector_args, &ti->error); r = dm_read_arg(_args + 1, as, &nr_selector_args, &ti->error); if (r) goto bad; nr_params = 1 + nr_selector_args; nr_args = 1 + nr_selector_args; for (i = 0; i < pg->nr_pgpaths; i++) { struct pgpath *pgpath; struct arg_set path_args; struct dm_arg_set path_args; if (as->argc < nr_params) { if (as->argc < nr_args) { ti->error = "not enough path parameters"; r = -EINVAL; goto bad; } path_args.argc = nr_params; path_args.argc = nr_args; path_args.argv = as->argv; pgpath = parse_path(&path_args, &pg->ps, ti); Loading @@ -723,7 +671,7 @@ static struct priority_group *parse_priority_group(struct arg_set *as, pgpath->pg = pg; list_add_tail(&pgpath->list, &pg->pgpaths); consume(as, nr_params); dm_consume_args(as, nr_args); } return pg; Loading @@ -733,28 +681,23 @@ static struct priority_group *parse_priority_group(struct arg_set *as, return ERR_PTR(r); } static int parse_hw_handler(struct arg_set *as, struct multipath *m) static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m) { unsigned hw_argc; int ret; struct dm_target *ti = m->ti; static struct param _params[] = { static struct dm_arg _args[] = { {0, 1024, "invalid number of hardware handler args"}, }; if (read_param(_params, shift(as), &hw_argc, &ti->error)) if (dm_read_arg_group(_args, as, &hw_argc, &ti->error)) return -EINVAL; if (!hw_argc) return 0; if (hw_argc > as->argc) { ti->error = "not enough arguments for hardware handler"; return -EINVAL; } m->hw_handler_name = kstrdup(shift(as), GFP_KERNEL); m->hw_handler_name = kstrdup(dm_shift_arg(as), GFP_KERNEL); request_module("scsi_dh_%s", m->hw_handler_name); if (scsi_dh_handler_exist(m->hw_handler_name) == 0) { ti->error = "unknown hardware handler type"; Loading @@ -778,7 +721,7 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m) for (i = 0, p+=j+1; i <= hw_argc - 2; i++, p+=j+1) j = sprintf(p, "%s", as->argv[i]); } consume(as, hw_argc - 1); dm_consume_args(as, hw_argc - 1); return 0; fail: Loading @@ -787,52 +730,45 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m) return ret; } static int parse_features(struct arg_set *as, struct multipath *m) static int parse_features(struct dm_arg_set *as, struct multipath *m) { int r; unsigned argc; struct dm_target *ti = m->ti; const char *param_name; const char *arg_name; static struct param _params[] = { static struct dm_arg _args[] = { {0, 5, "invalid number of feature args"}, {1, 50, "pg_init_retries must be between 1 and 50"}, {0, 60000, "pg_init_delay_msecs must be between 0 and 60000"}, }; r = read_param(_params, shift(as), &argc, &ti->error); r = dm_read_arg_group(_args, as, &argc, &ti->error); if (r) return -EINVAL; if (!argc) return 0; if (argc > as->argc) { ti->error = "not enough arguments for features"; return -EINVAL; } do { param_name = shift(as); arg_name = dm_shift_arg(as); argc--; if (!strnicmp(param_name, MESG_STR("queue_if_no_path"))) { if (!strcasecmp(arg_name, "queue_if_no_path")) { r = queue_if_no_path(m, 1, 0); continue; } if (!strnicmp(param_name, MESG_STR("pg_init_retries")) && if (!strcasecmp(arg_name, "pg_init_retries") && (argc >= 1)) { r = read_param(_params + 1, shift(as), &m->pg_init_retries, &ti->error); r = dm_read_arg(_args + 1, as, &m->pg_init_retries, &ti->error); argc--; continue; } if (!strnicmp(param_name, MESG_STR("pg_init_delay_msecs")) && if (!strcasecmp(arg_name, "pg_init_delay_msecs") && (argc >= 1)) { r = read_param(_params + 2, shift(as), &m->pg_init_delay_msecs, &ti->error); r = dm_read_arg(_args + 2, as, &m->pg_init_delay_msecs, &ti->error); argc--; continue; } Loading @@ -847,15 +783,15 @@ static int parse_features(struct arg_set *as, struct multipath *m) static int multipath_ctr(struct dm_target *ti, unsigned int argc, char **argv) { /* target parameters */ static struct param _params[] = { /* target arguments */ static struct dm_arg _args[] = { {0, 1024, "invalid number of priority groups"}, {0, 1024, "invalid initial priority group number"}, }; int r; struct multipath *m; struct arg_set as; struct dm_arg_set as; unsigned pg_count = 0; unsigned next_pg_num; Loading @@ -876,11 +812,11 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, if (r) goto bad; r = read_param(_params, shift(&as), &m->nr_priority_groups, &ti->error); r = dm_read_arg(_args, &as, &m->nr_priority_groups, &ti->error); if (r) goto bad; r = read_param(_params + 1, shift(&as), &next_pg_num, &ti->error); r = dm_read_arg(_args + 1, &as, &next_pg_num, &ti->error); if (r) goto bad; Loading Loading @@ -1510,10 +1446,10 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) } if (argc == 1) { if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) { if (!strcasecmp(argv[0], "queue_if_no_path")) { r = queue_if_no_path(m, 1, 0); goto out; } else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path"))) { } else if (!strcasecmp(argv[0], "fail_if_no_path")) { r = queue_if_no_path(m, 0, 0); goto out; } Loading @@ -1524,18 +1460,18 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) goto out; } if (!strnicmp(argv[0], MESG_STR("disable_group"))) { if (!strcasecmp(argv[0], "disable_group")) { r = bypass_pg_num(m, argv[1], 1); goto out; } else if (!strnicmp(argv[0], MESG_STR("enable_group"))) { } else if (!strcasecmp(argv[0], "enable_group")) { r = bypass_pg_num(m, argv[1], 0); goto out; } else if (!strnicmp(argv[0], MESG_STR("switch_group"))) { } else if (!strcasecmp(argv[0], "switch_group")) { r = switch_pg_num(m, argv[1]); goto out; } else if (!strnicmp(argv[0], MESG_STR("reinstate_path"))) } else if (!strcasecmp(argv[0], "reinstate_path")) action = reinstate_path; else if (!strnicmp(argv[0], MESG_STR("fail_path"))) else if (!strcasecmp(argv[0], "fail_path")) action = fail_path; else { DMWARN("Unrecognised multipath message received."); Loading drivers/md/dm-table.c +57 −0 Original line number Diff line number Diff line Loading @@ -797,6 +797,63 @@ int dm_table_add_target(struct dm_table *t, const char *type, return r; } /* * Target argument parsing helpers. */ static int validate_next_arg(struct dm_arg *arg, struct dm_arg_set *arg_set, unsigned *value, char **error, unsigned grouped) { const char *arg_str = dm_shift_arg(arg_set); if (!arg_str || (sscanf(arg_str, "%u", value) != 1) || (*value < arg->min) || (*value > arg->max) || (grouped && arg_set->argc < *value)) { *error = arg->error; return -EINVAL; } return 0; } int dm_read_arg(struct dm_arg *arg, struct dm_arg_set *arg_set, unsigned *value, char **error) { return validate_next_arg(arg, arg_set, value, error, 0); } EXPORT_SYMBOL(dm_read_arg); int dm_read_arg_group(struct dm_arg *arg, struct dm_arg_set *arg_set, unsigned *value, char **error) { return validate_next_arg(arg, arg_set, value, error, 1); } EXPORT_SYMBOL(dm_read_arg_group); const char *dm_shift_arg(struct dm_arg_set *as) { char *r; if (as->argc) { as->argc--; r = *as->argv; as->argv++; return r; } return NULL; } EXPORT_SYMBOL(dm_shift_arg); void dm_consume_args(struct dm_arg_set *as, unsigned num_args) { BUG_ON(as->argc < num_args); as->argc -= num_args; as->argv += num_args; } EXPORT_SYMBOL(dm_consume_args); static int dm_table_set_type(struct dm_table *t) { unsigned i; Loading include/linux/device-mapper.h +43 −0 Original line number Diff line number Diff line Loading @@ -208,6 +208,49 @@ struct dm_target_callbacks { int dm_register_target(struct target_type *t); void dm_unregister_target(struct target_type *t); /* * Target argument parsing. */ struct dm_arg_set { unsigned argc; char **argv; }; /* * The minimum and maximum value of a numeric argument, together with * the error message to use if the number is found to be outside that range. */ struct dm_arg { unsigned min; unsigned max; char *error; }; /* * Validate the next argument, either returning it as *value or, if invalid, * returning -EINVAL and setting *error. */ int dm_read_arg(struct dm_arg *arg, struct dm_arg_set *arg_set, unsigned *value, char **error); /* * Process the next argument as the start of a group containing between * arg->min and arg->max further arguments. Either return the size as * *num_args or, if invalid, return -EINVAL and set *error. */ int dm_read_arg_group(struct dm_arg *arg, struct dm_arg_set *arg_set, unsigned *num_args, char **error); /* * Return the current argument and shift to the next. */ const char *dm_shift_arg(struct dm_arg_set *as); /* * Move through num_args arguments. */ void dm_consume_args(struct dm_arg_set *as, unsigned num_args); /*----------------------------------------------------------------- * Functions for creating and manipulating mapped devices. * Drop the reference with dm_put when you finish with the object. Loading Loading
drivers/md/dm-crypt.c +3 −4 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ #include <linux/device-mapper.h> #define DM_MSG_PREFIX "crypt" #define MESG_STR(x) x, sizeof(x) /* * context holding the current state of a multi-part conversion Loading Loading @@ -1770,12 +1769,12 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) if (argc < 2) goto error; if (!strnicmp(argv[0], MESG_STR("key"))) { if (!strcasecmp(argv[0], "key")) { if (!test_bit(DM_CRYPT_SUSPENDED, &cc->flags)) { DMWARN("not suspended during key manipulation."); return -EINVAL; } if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) { if (argc == 3 && !strcasecmp(argv[1], "set")) { ret = crypt_set_key(cc, argv[2]); if (ret) return ret; Loading @@ -1783,7 +1782,7 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) ret = cc->iv_gen_ops->init(cc); return ret; } if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) { if (argc == 2 && !strcasecmp(argv[1], "wipe")) { if (cc->iv_gen_ops && cc->iv_gen_ops->wipe) { ret = cc->iv_gen_ops->wipe(cc); if (ret) Loading
drivers/md/dm-mpath.c +44 −108 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ #include <linux/atomic.h> #define DM_MSG_PREFIX "multipath" #define MESG_STR(x) x, sizeof(x) #define DM_PG_INIT_DELAY_MSECS 2000 #define DM_PG_INIT_DELAY_DEFAULT ((unsigned) -1) Loading Loading @@ -505,80 +504,29 @@ static void trigger_event(struct work_struct *work) * <#paths> <#per-path selector args> * [<path> [<arg>]* ]+ ]+ *---------------------------------------------------------------*/ struct param { unsigned min; unsigned max; char *error; }; static int read_param(struct param *param, char *str, unsigned *v, char **error) { if (!str || (sscanf(str, "%u", v) != 1) || (*v < param->min) || (*v > param->max)) { *error = param->error; return -EINVAL; } return 0; } struct arg_set { unsigned argc; char **argv; }; static char *shift(struct arg_set *as) { char *r; if (as->argc) { as->argc--; r = *as->argv; as->argv++; return r; } return NULL; } static void consume(struct arg_set *as, unsigned n) { BUG_ON (as->argc < n); as->argc -= n; as->argv += n; } static int parse_path_selector(struct arg_set *as, struct priority_group *pg, static int parse_path_selector(struct dm_arg_set *as, struct priority_group *pg, struct dm_target *ti) { int r; struct path_selector_type *pst; unsigned ps_argc; static struct param _params[] = { static struct dm_arg _args[] = { {0, 1024, "invalid number of path selector args"}, }; pst = dm_get_path_selector(shift(as)); pst = dm_get_path_selector(dm_shift_arg(as)); if (!pst) { ti->error = "unknown path selector type"; return -EINVAL; } r = read_param(_params, shift(as), &ps_argc, &ti->error); r = dm_read_arg_group(_args, as, &ps_argc, &ti->error); if (r) { dm_put_path_selector(pst); return -EINVAL; } if (ps_argc > as->argc) { dm_put_path_selector(pst); ti->error = "not enough arguments for path selector"; return -EINVAL; } r = pst->create(&pg->ps, ps_argc, as->argv); if (r) { dm_put_path_selector(pst); Loading @@ -587,12 +535,12 @@ static int parse_path_selector(struct arg_set *as, struct priority_group *pg, } pg->ps.type = pst; consume(as, ps_argc); dm_consume_args(as, ps_argc); return 0; } static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps, struct dm_target *ti) { int r; Loading @@ -609,7 +557,7 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, if (!p) return ERR_PTR(-ENOMEM); r = dm_get_device(ti, shift(as), dm_table_get_mode(ti->table), r = dm_get_device(ti, dm_shift_arg(as), dm_table_get_mode(ti->table), &p->path.dev); if (r) { ti->error = "error getting device"; Loading Loading @@ -660,16 +608,16 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, return ERR_PTR(r); } static struct priority_group *parse_priority_group(struct arg_set *as, static struct priority_group *parse_priority_group(struct dm_arg_set *as, struct multipath *m) { static struct param _params[] = { static struct dm_arg _args[] = { {1, 1024, "invalid number of paths"}, {0, 1024, "invalid number of selector args"} }; int r; unsigned i, nr_selector_args, nr_params; unsigned i, nr_selector_args, nr_args; struct priority_group *pg; struct dm_target *ti = m->ti; Loading @@ -693,26 +641,26 @@ static struct priority_group *parse_priority_group(struct arg_set *as, /* * read the paths */ r = read_param(_params, shift(as), &pg->nr_pgpaths, &ti->error); r = dm_read_arg(_args, as, &pg->nr_pgpaths, &ti->error); if (r) goto bad; r = read_param(_params + 1, shift(as), &nr_selector_args, &ti->error); r = dm_read_arg(_args + 1, as, &nr_selector_args, &ti->error); if (r) goto bad; nr_params = 1 + nr_selector_args; nr_args = 1 + nr_selector_args; for (i = 0; i < pg->nr_pgpaths; i++) { struct pgpath *pgpath; struct arg_set path_args; struct dm_arg_set path_args; if (as->argc < nr_params) { if (as->argc < nr_args) { ti->error = "not enough path parameters"; r = -EINVAL; goto bad; } path_args.argc = nr_params; path_args.argc = nr_args; path_args.argv = as->argv; pgpath = parse_path(&path_args, &pg->ps, ti); Loading @@ -723,7 +671,7 @@ static struct priority_group *parse_priority_group(struct arg_set *as, pgpath->pg = pg; list_add_tail(&pgpath->list, &pg->pgpaths); consume(as, nr_params); dm_consume_args(as, nr_args); } return pg; Loading @@ -733,28 +681,23 @@ static struct priority_group *parse_priority_group(struct arg_set *as, return ERR_PTR(r); } static int parse_hw_handler(struct arg_set *as, struct multipath *m) static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m) { unsigned hw_argc; int ret; struct dm_target *ti = m->ti; static struct param _params[] = { static struct dm_arg _args[] = { {0, 1024, "invalid number of hardware handler args"}, }; if (read_param(_params, shift(as), &hw_argc, &ti->error)) if (dm_read_arg_group(_args, as, &hw_argc, &ti->error)) return -EINVAL; if (!hw_argc) return 0; if (hw_argc > as->argc) { ti->error = "not enough arguments for hardware handler"; return -EINVAL; } m->hw_handler_name = kstrdup(shift(as), GFP_KERNEL); m->hw_handler_name = kstrdup(dm_shift_arg(as), GFP_KERNEL); request_module("scsi_dh_%s", m->hw_handler_name); if (scsi_dh_handler_exist(m->hw_handler_name) == 0) { ti->error = "unknown hardware handler type"; Loading @@ -778,7 +721,7 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m) for (i = 0, p+=j+1; i <= hw_argc - 2; i++, p+=j+1) j = sprintf(p, "%s", as->argv[i]); } consume(as, hw_argc - 1); dm_consume_args(as, hw_argc - 1); return 0; fail: Loading @@ -787,52 +730,45 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m) return ret; } static int parse_features(struct arg_set *as, struct multipath *m) static int parse_features(struct dm_arg_set *as, struct multipath *m) { int r; unsigned argc; struct dm_target *ti = m->ti; const char *param_name; const char *arg_name; static struct param _params[] = { static struct dm_arg _args[] = { {0, 5, "invalid number of feature args"}, {1, 50, "pg_init_retries must be between 1 and 50"}, {0, 60000, "pg_init_delay_msecs must be between 0 and 60000"}, }; r = read_param(_params, shift(as), &argc, &ti->error); r = dm_read_arg_group(_args, as, &argc, &ti->error); if (r) return -EINVAL; if (!argc) return 0; if (argc > as->argc) { ti->error = "not enough arguments for features"; return -EINVAL; } do { param_name = shift(as); arg_name = dm_shift_arg(as); argc--; if (!strnicmp(param_name, MESG_STR("queue_if_no_path"))) { if (!strcasecmp(arg_name, "queue_if_no_path")) { r = queue_if_no_path(m, 1, 0); continue; } if (!strnicmp(param_name, MESG_STR("pg_init_retries")) && if (!strcasecmp(arg_name, "pg_init_retries") && (argc >= 1)) { r = read_param(_params + 1, shift(as), &m->pg_init_retries, &ti->error); r = dm_read_arg(_args + 1, as, &m->pg_init_retries, &ti->error); argc--; continue; } if (!strnicmp(param_name, MESG_STR("pg_init_delay_msecs")) && if (!strcasecmp(arg_name, "pg_init_delay_msecs") && (argc >= 1)) { r = read_param(_params + 2, shift(as), &m->pg_init_delay_msecs, &ti->error); r = dm_read_arg(_args + 2, as, &m->pg_init_delay_msecs, &ti->error); argc--; continue; } Loading @@ -847,15 +783,15 @@ static int parse_features(struct arg_set *as, struct multipath *m) static int multipath_ctr(struct dm_target *ti, unsigned int argc, char **argv) { /* target parameters */ static struct param _params[] = { /* target arguments */ static struct dm_arg _args[] = { {0, 1024, "invalid number of priority groups"}, {0, 1024, "invalid initial priority group number"}, }; int r; struct multipath *m; struct arg_set as; struct dm_arg_set as; unsigned pg_count = 0; unsigned next_pg_num; Loading @@ -876,11 +812,11 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, if (r) goto bad; r = read_param(_params, shift(&as), &m->nr_priority_groups, &ti->error); r = dm_read_arg(_args, &as, &m->nr_priority_groups, &ti->error); if (r) goto bad; r = read_param(_params + 1, shift(&as), &next_pg_num, &ti->error); r = dm_read_arg(_args + 1, &as, &next_pg_num, &ti->error); if (r) goto bad; Loading Loading @@ -1510,10 +1446,10 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) } if (argc == 1) { if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) { if (!strcasecmp(argv[0], "queue_if_no_path")) { r = queue_if_no_path(m, 1, 0); goto out; } else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path"))) { } else if (!strcasecmp(argv[0], "fail_if_no_path")) { r = queue_if_no_path(m, 0, 0); goto out; } Loading @@ -1524,18 +1460,18 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) goto out; } if (!strnicmp(argv[0], MESG_STR("disable_group"))) { if (!strcasecmp(argv[0], "disable_group")) { r = bypass_pg_num(m, argv[1], 1); goto out; } else if (!strnicmp(argv[0], MESG_STR("enable_group"))) { } else if (!strcasecmp(argv[0], "enable_group")) { r = bypass_pg_num(m, argv[1], 0); goto out; } else if (!strnicmp(argv[0], MESG_STR("switch_group"))) { } else if (!strcasecmp(argv[0], "switch_group")) { r = switch_pg_num(m, argv[1]); goto out; } else if (!strnicmp(argv[0], MESG_STR("reinstate_path"))) } else if (!strcasecmp(argv[0], "reinstate_path")) action = reinstate_path; else if (!strnicmp(argv[0], MESG_STR("fail_path"))) else if (!strcasecmp(argv[0], "fail_path")) action = fail_path; else { DMWARN("Unrecognised multipath message received."); Loading
drivers/md/dm-table.c +57 −0 Original line number Diff line number Diff line Loading @@ -797,6 +797,63 @@ int dm_table_add_target(struct dm_table *t, const char *type, return r; } /* * Target argument parsing helpers. */ static int validate_next_arg(struct dm_arg *arg, struct dm_arg_set *arg_set, unsigned *value, char **error, unsigned grouped) { const char *arg_str = dm_shift_arg(arg_set); if (!arg_str || (sscanf(arg_str, "%u", value) != 1) || (*value < arg->min) || (*value > arg->max) || (grouped && arg_set->argc < *value)) { *error = arg->error; return -EINVAL; } return 0; } int dm_read_arg(struct dm_arg *arg, struct dm_arg_set *arg_set, unsigned *value, char **error) { return validate_next_arg(arg, arg_set, value, error, 0); } EXPORT_SYMBOL(dm_read_arg); int dm_read_arg_group(struct dm_arg *arg, struct dm_arg_set *arg_set, unsigned *value, char **error) { return validate_next_arg(arg, arg_set, value, error, 1); } EXPORT_SYMBOL(dm_read_arg_group); const char *dm_shift_arg(struct dm_arg_set *as) { char *r; if (as->argc) { as->argc--; r = *as->argv; as->argv++; return r; } return NULL; } EXPORT_SYMBOL(dm_shift_arg); void dm_consume_args(struct dm_arg_set *as, unsigned num_args) { BUG_ON(as->argc < num_args); as->argc -= num_args; as->argv += num_args; } EXPORT_SYMBOL(dm_consume_args); static int dm_table_set_type(struct dm_table *t) { unsigned i; Loading
include/linux/device-mapper.h +43 −0 Original line number Diff line number Diff line Loading @@ -208,6 +208,49 @@ struct dm_target_callbacks { int dm_register_target(struct target_type *t); void dm_unregister_target(struct target_type *t); /* * Target argument parsing. */ struct dm_arg_set { unsigned argc; char **argv; }; /* * The minimum and maximum value of a numeric argument, together with * the error message to use if the number is found to be outside that range. */ struct dm_arg { unsigned min; unsigned max; char *error; }; /* * Validate the next argument, either returning it as *value or, if invalid, * returning -EINVAL and setting *error. */ int dm_read_arg(struct dm_arg *arg, struct dm_arg_set *arg_set, unsigned *value, char **error); /* * Process the next argument as the start of a group containing between * arg->min and arg->max further arguments. Either return the size as * *num_args or, if invalid, return -EINVAL and set *error. */ int dm_read_arg_group(struct dm_arg *arg, struct dm_arg_set *arg_set, unsigned *num_args, char **error); /* * Return the current argument and shift to the next. */ const char *dm_shift_arg(struct dm_arg_set *as); /* * Move through num_args arguments. */ void dm_consume_args(struct dm_arg_set *as, unsigned num_args); /*----------------------------------------------------------------- * Functions for creating and manipulating mapped devices. * Drop the reference with dm_put when you finish with the object. Loading