Skip to content

Commit

Permalink
dm table: share target argument parsing functions
Browse files Browse the repository at this point in the history
Move multipath target argument parsing code into dm-table so other
targets can share it.

Signed-off-by: Mike Snitzer <[email protected]>
Signed-off-by: Alasdair G Kergon <[email protected]>
  • Loading branch information
snitm authored and kergon committed Aug 2, 2011
1 parent a6e50b4 commit 498f010
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 112 deletions.
7 changes: 3 additions & 4 deletions drivers/md/dm-crypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1770,20 +1769,20 @@ 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;
if (cc->iv_gen_ops && cc->iv_gen_ops->init)
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)
Expand Down
152 changes: 44 additions & 108 deletions drivers/md/dm-mpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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";
Expand Down Expand Up @@ -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;

Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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";
Expand All @@ -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:
Expand All @@ -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;
}
Expand All @@ -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;

Expand All @@ -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;

Expand Down Expand Up @@ -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;
}
Expand All @@ -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.");
Expand Down
Loading

0 comments on commit 498f010

Please sign in to comment.