diff options
author | Mike Snitzer <snitzer@redhat.com> | 2011-08-02 07:32:05 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2011-08-02 07:32:05 -0400 |
commit | dfd068b01f02653c6650f1c0eda443b2655d1471 (patch) | |
tree | e61e92a4a1e6b4c0170a87453219cabaf66e312a /drivers/md | |
parent | 30e4171bfe3d1c49689803338005cc0071dddaff (diff) |
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>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-flakey.c | 83 |
1 files changed, 64 insertions, 19 deletions
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index 70a69b2f93d2..dd963dc3ca08 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c | |||
@@ -27,54 +27,99 @@ struct flakey_c { | |||
27 | unsigned down_interval; | 27 | unsigned down_interval; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | static int parse_features(struct dm_arg_set *as, struct dm_target *ti) | ||
31 | { | ||
32 | int r; | ||
33 | unsigned argc; | ||
34 | const char *arg_name; | ||
35 | |||
36 | static struct dm_arg _args[] = { | ||
37 | {0, 0, "Invalid number of feature args"}, | ||
38 | }; | ||
39 | |||
40 | /* No feature arguments supplied. */ | ||
41 | if (!as->argc) | ||
42 | return 0; | ||
43 | |||
44 | r = dm_read_arg_group(_args, as, &argc, &ti->error); | ||
45 | if (r) | ||
46 | return -EINVAL; | ||
47 | |||
48 | while (argc && !r) { | ||
49 | arg_name = dm_shift_arg(as); | ||
50 | argc--; | ||
51 | |||
52 | ti->error = "Unrecognised flakey feature requested"; | ||
53 | r = -EINVAL; | ||
54 | } | ||
55 | |||
56 | return r; | ||
57 | } | ||
58 | |||
30 | /* | 59 | /* |
31 | * Construct a flakey mapping: <dev_path> <offset> <up interval> <down interval> | 60 | * Construct a flakey mapping: |
61 | * <dev_path> <offset> <up interval> <down interval> [<#feature args> [<arg>]*] | ||
32 | */ | 62 | */ |
33 | static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv) | 63 | static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv) |
34 | { | 64 | { |
65 | static struct dm_arg _args[] = { | ||
66 | {0, UINT_MAX, "Invalid up interval"}, | ||
67 | {0, UINT_MAX, "Invalid down interval"}, | ||
68 | }; | ||
69 | |||
70 | int r; | ||
35 | struct flakey_c *fc; | 71 | struct flakey_c *fc; |
36 | unsigned long long tmp; | 72 | unsigned long long tmpll; |
73 | struct dm_arg_set as; | ||
74 | const char *devname; | ||
37 | 75 | ||
38 | if (argc != 4) { | 76 | as.argc = argc; |
39 | ti->error = "dm-flakey: Invalid argument count"; | 77 | as.argv = argv; |
78 | |||
79 | if (argc < 4) { | ||
80 | ti->error = "Invalid argument count"; | ||
40 | return -EINVAL; | 81 | return -EINVAL; |
41 | } | 82 | } |
42 | 83 | ||
43 | fc = kmalloc(sizeof(*fc), GFP_KERNEL); | 84 | fc = kmalloc(sizeof(*fc), GFP_KERNEL); |
44 | if (!fc) { | 85 | if (!fc) { |
45 | ti->error = "dm-flakey: Cannot allocate linear context"; | 86 | ti->error = "Cannot allocate linear context"; |
46 | return -ENOMEM; | 87 | return -ENOMEM; |
47 | } | 88 | } |
48 | fc->start_time = jiffies; | 89 | fc->start_time = jiffies; |
49 | 90 | ||
50 | if (sscanf(argv[1], "%llu", &tmp) != 1) { | 91 | devname = dm_shift_arg(&as); |
51 | ti->error = "dm-flakey: Invalid device sector"; | 92 | |
93 | if (sscanf(dm_shift_arg(&as), "%llu", &tmpll) != 1) { | ||
94 | ti->error = "Invalid device sector"; | ||
52 | goto bad; | 95 | goto bad; |
53 | } | 96 | } |
54 | fc->start = tmp; | 97 | fc->start = tmpll; |
55 | 98 | ||
56 | if (sscanf(argv[2], "%u", &fc->up_interval) != 1) { | 99 | r = dm_read_arg(_args, &as, &fc->up_interval, &ti->error); |
57 | ti->error = "dm-flakey: Invalid up interval"; | 100 | if (r) |
58 | goto bad; | 101 | goto bad; |
59 | } | ||
60 | 102 | ||
61 | if (sscanf(argv[3], "%u", &fc->down_interval) != 1) { | 103 | r = dm_read_arg(_args, &as, &fc->down_interval, &ti->error); |
62 | ti->error = "dm-flakey: Invalid down interval"; | 104 | if (r) |
63 | goto bad; | 105 | goto bad; |
64 | } | ||
65 | 106 | ||
66 | if (!(fc->up_interval + fc->down_interval)) { | 107 | if (!(fc->up_interval + fc->down_interval)) { |
67 | ti->error = "dm-flakey: Total (up + down) interval is zero"; | 108 | ti->error = "Total (up + down) interval is zero"; |
68 | goto bad; | 109 | goto bad; |
69 | } | 110 | } |
70 | 111 | ||
71 | if (fc->up_interval + fc->down_interval < fc->up_interval) { | 112 | if (fc->up_interval + fc->down_interval < fc->up_interval) { |
72 | ti->error = "dm-flakey: Interval overflow"; | 113 | ti->error = "Interval overflow"; |
73 | goto bad; | 114 | goto bad; |
74 | } | 115 | } |
75 | 116 | ||
76 | if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &fc->dev)) { | 117 | r = parse_features(&as, ti); |
77 | ti->error = "dm-flakey: Device lookup failed"; | 118 | if (r) |
119 | goto bad; | ||
120 | |||
121 | if (dm_get_device(ti, devname, dm_table_get_mode(ti->table), &fc->dev)) { | ||
122 | ti->error = "Device lookup failed"; | ||
78 | goto bad; | 123 | goto bad; |
79 | } | 124 | } |
80 | 125 | ||
@@ -178,7 +223,7 @@ static int flakey_iterate_devices(struct dm_target *ti, iterate_devices_callout_ | |||
178 | 223 | ||
179 | static struct target_type flakey_target = { | 224 | static struct target_type flakey_target = { |
180 | .name = "flakey", | 225 | .name = "flakey", |
181 | .version = {1, 1, 0}, | 226 | .version = {1, 2, 0}, |
182 | .module = THIS_MODULE, | 227 | .module = THIS_MODULE, |
183 | .ctr = flakey_ctr, | 228 | .ctr = flakey_ctr, |
184 | .dtr = flakey_dtr, | 229 | .dtr = flakey_dtr, |