forked from Minki/linux
dm flakey: support feature args
Add the ability to specify arbitrary feature flags when creating a flakey target. This code uses the same target argument helpers that the multipath target does. Also remove the superfluous 'dm-flakey' prefixes from the error messages, as they already contain the prefix 'flakey'. Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
This commit is contained in:
parent
30e4171bfe
commit
dfd068b01f
@ -27,54 +27,99 @@ struct flakey_c {
|
|||||||
unsigned down_interval;
|
unsigned down_interval;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int parse_features(struct dm_arg_set *as, struct dm_target *ti)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
unsigned argc;
|
||||||
|
const char *arg_name;
|
||||||
|
|
||||||
|
static struct dm_arg _args[] = {
|
||||||
|
{0, 0, "Invalid number of feature args"},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* No feature arguments supplied. */
|
||||||
|
if (!as->argc)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = dm_read_arg_group(_args, as, &argc, &ti->error);
|
||||||
|
if (r)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
while (argc && !r) {
|
||||||
|
arg_name = dm_shift_arg(as);
|
||||||
|
argc--;
|
||||||
|
|
||||||
|
ti->error = "Unrecognised flakey feature requested";
|
||||||
|
r = -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct a flakey mapping: <dev_path> <offset> <up interval> <down interval>
|
* Construct a flakey mapping:
|
||||||
|
* <dev_path> <offset> <up interval> <down interval> [<#feature args> [<arg>]*]
|
||||||
*/
|
*/
|
||||||
static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct flakey_c *fc;
|
static struct dm_arg _args[] = {
|
||||||
unsigned long long tmp;
|
{0, UINT_MAX, "Invalid up interval"},
|
||||||
|
{0, UINT_MAX, "Invalid down interval"},
|
||||||
|
};
|
||||||
|
|
||||||
if (argc != 4) {
|
int r;
|
||||||
ti->error = "dm-flakey: Invalid argument count";
|
struct flakey_c *fc;
|
||||||
|
unsigned long long tmpll;
|
||||||
|
struct dm_arg_set as;
|
||||||
|
const char *devname;
|
||||||
|
|
||||||
|
as.argc = argc;
|
||||||
|
as.argv = argv;
|
||||||
|
|
||||||
|
if (argc < 4) {
|
||||||
|
ti->error = "Invalid argument count";
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fc = kmalloc(sizeof(*fc), GFP_KERNEL);
|
fc = kmalloc(sizeof(*fc), GFP_KERNEL);
|
||||||
if (!fc) {
|
if (!fc) {
|
||||||
ti->error = "dm-flakey: Cannot allocate linear context";
|
ti->error = "Cannot allocate linear context";
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
fc->start_time = jiffies;
|
fc->start_time = jiffies;
|
||||||
|
|
||||||
if (sscanf(argv[1], "%llu", &tmp) != 1) {
|
devname = dm_shift_arg(&as);
|
||||||
ti->error = "dm-flakey: Invalid device sector";
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
fc->start = tmp;
|
|
||||||
|
|
||||||
if (sscanf(argv[2], "%u", &fc->up_interval) != 1) {
|
if (sscanf(dm_shift_arg(&as), "%llu", &tmpll) != 1) {
|
||||||
ti->error = "dm-flakey: Invalid up interval";
|
ti->error = "Invalid device sector";
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
fc->start = tmpll;
|
||||||
|
|
||||||
if (sscanf(argv[3], "%u", &fc->down_interval) != 1) {
|
r = dm_read_arg(_args, &as, &fc->up_interval, &ti->error);
|
||||||
ti->error = "dm-flakey: Invalid down interval";
|
if (r)
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
r = dm_read_arg(_args, &as, &fc->down_interval, &ti->error);
|
||||||
|
if (r)
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
|
||||||
|
|
||||||
if (!(fc->up_interval + fc->down_interval)) {
|
if (!(fc->up_interval + fc->down_interval)) {
|
||||||
ti->error = "dm-flakey: Total (up + down) interval is zero";
|
ti->error = "Total (up + down) interval is zero";
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fc->up_interval + fc->down_interval < fc->up_interval) {
|
if (fc->up_interval + fc->down_interval < fc->up_interval) {
|
||||||
ti->error = "dm-flakey: Interval overflow";
|
ti->error = "Interval overflow";
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &fc->dev)) {
|
r = parse_features(&as, ti);
|
||||||
ti->error = "dm-flakey: Device lookup failed";
|
if (r)
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
if (dm_get_device(ti, devname, dm_table_get_mode(ti->table), &fc->dev)) {
|
||||||
|
ti->error = "Device lookup failed";
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +223,7 @@ static int flakey_iterate_devices(struct dm_target *ti, iterate_devices_callout_
|
|||||||
|
|
||||||
static struct target_type flakey_target = {
|
static struct target_type flakey_target = {
|
||||||
.name = "flakey",
|
.name = "flakey",
|
||||||
.version = {1, 1, 0},
|
.version = {1, 2, 0},
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
.ctr = flakey_ctr,
|
.ctr = flakey_ctr,
|
||||||
.dtr = flakey_dtr,
|
.dtr = flakey_dtr,
|
||||||
|
Loading…
Reference in New Issue
Block a user