0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/ctype.h>
0011 #include <linux/device.h>
0012 #include <linux/device-mapper.h>
0013 #include <linux/init.h>
0014 #include <linux/list.h>
0015 #include <linux/moduleparam.h>
0016
0017 #define DM_MSG_PREFIX "init"
0018 #define DM_MAX_DEVICES 256
0019 #define DM_MAX_TARGETS 256
0020 #define DM_MAX_STR_SIZE 4096
0021
0022 static char *create;
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 struct dm_device {
0033 struct dm_ioctl dmi;
0034 struct dm_target_spec *table[DM_MAX_TARGETS];
0035 char *target_args_array[DM_MAX_TARGETS];
0036 struct list_head list;
0037 };
0038
0039 static const char * const dm_allowed_targets[] __initconst = {
0040 "crypt",
0041 "delay",
0042 "linear",
0043 "snapshot-origin",
0044 "striped",
0045 "verity",
0046 };
0047
0048 static int __init dm_verify_target_type(const char *target)
0049 {
0050 unsigned int i;
0051
0052 for (i = 0; i < ARRAY_SIZE(dm_allowed_targets); i++) {
0053 if (!strcmp(dm_allowed_targets[i], target))
0054 return 0;
0055 }
0056 return -EINVAL;
0057 }
0058
0059 static void __init dm_setup_cleanup(struct list_head *devices)
0060 {
0061 struct dm_device *dev, *tmp;
0062 unsigned int i;
0063
0064 list_for_each_entry_safe(dev, tmp, devices, list) {
0065 list_del(&dev->list);
0066 for (i = 0; i < dev->dmi.target_count; i++) {
0067 kfree(dev->table[i]);
0068 kfree(dev->target_args_array[i]);
0069 }
0070 kfree(dev);
0071 }
0072 }
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 static char __init *str_field_delimit(char **str, char separator)
0084 {
0085 char *s;
0086
0087
0088 *str = skip_spaces(*str);
0089 s = strchr(*str, separator);
0090
0091 if (s)
0092 *s = '\0';
0093 *str = strim(*str);
0094 return s ? ++s : NULL;
0095 }
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 static char __init *dm_parse_table_entry(struct dm_device *dev, char *str)
0107 {
0108 const unsigned int n = dev->dmi.target_count - 1;
0109 struct dm_target_spec *sp;
0110 unsigned int i;
0111
0112 char *field[4];
0113 char *next;
0114
0115 field[0] = str;
0116
0117 for (i = 0; i < ARRAY_SIZE(field) - 1; i++) {
0118 field[i + 1] = str_field_delimit(&field[i], ' ');
0119 if (!field[i + 1])
0120 return ERR_PTR(-EINVAL);
0121 }
0122
0123 next = str_field_delimit(&field[i], ',');
0124
0125 sp = kzalloc(sizeof(*sp), GFP_KERNEL);
0126 if (!sp)
0127 return ERR_PTR(-ENOMEM);
0128 dev->table[n] = sp;
0129
0130
0131 if (kstrtoull(field[0], 0, &sp->sector_start))
0132 return ERR_PTR(-EINVAL);
0133
0134 if (kstrtoull(field[1], 0, &sp->length))
0135 return ERR_PTR(-EINVAL);
0136
0137 strscpy(sp->target_type, field[2], sizeof(sp->target_type));
0138 if (dm_verify_target_type(sp->target_type)) {
0139 DMERR("invalid type \"%s\"", sp->target_type);
0140 return ERR_PTR(-EINVAL);
0141 }
0142
0143 dev->target_args_array[n] = kstrndup(field[3], DM_MAX_STR_SIZE,
0144 GFP_KERNEL);
0145 if (!dev->target_args_array[n])
0146 return ERR_PTR(-ENOMEM);
0147
0148 return next;
0149 }
0150
0151
0152
0153
0154
0155
0156
0157 static int __init dm_parse_table(struct dm_device *dev, char *str)
0158 {
0159 char *table_entry = str;
0160
0161 while (table_entry) {
0162 DMDEBUG("parsing table \"%s\"", str);
0163 if (++dev->dmi.target_count > DM_MAX_TARGETS) {
0164 DMERR("too many targets %u > %d",
0165 dev->dmi.target_count, DM_MAX_TARGETS);
0166 return -EINVAL;
0167 }
0168 table_entry = dm_parse_table_entry(dev, table_entry);
0169 if (IS_ERR(table_entry)) {
0170 DMERR("couldn't parse table");
0171 return PTR_ERR(table_entry);
0172 }
0173 }
0174
0175 return 0;
0176 }
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187 static char __init *dm_parse_device_entry(struct dm_device *dev, char *str)
0188 {
0189
0190 char *field[5];
0191 unsigned int i;
0192 char *next;
0193
0194 field[0] = str;
0195
0196 for (i = 0; i < ARRAY_SIZE(field) - 1; i++) {
0197 field[i+1] = str_field_delimit(&field[i], ',');
0198 if (!field[i+1])
0199 return ERR_PTR(-EINVAL);
0200 }
0201
0202 next = str_field_delimit(&field[i], ';');
0203
0204
0205 strscpy(dev->dmi.name, field[0], sizeof(dev->dmi.name));
0206
0207 strscpy(dev->dmi.uuid, field[1], sizeof(dev->dmi.uuid));
0208
0209 if (strlen(field[2])) {
0210 if (kstrtoull(field[2], 0, &dev->dmi.dev))
0211 return ERR_PTR(-EINVAL);
0212 dev->dmi.flags |= DM_PERSISTENT_DEV_FLAG;
0213 }
0214
0215 if (!strcmp(field[3], "ro"))
0216 dev->dmi.flags |= DM_READONLY_FLAG;
0217 else if (strcmp(field[3], "rw"))
0218 return ERR_PTR(-EINVAL);
0219
0220 if (dm_parse_table(dev, field[4]))
0221 return ERR_PTR(-EINVAL);
0222
0223 return next;
0224 }
0225
0226
0227
0228
0229
0230
0231
0232 static int __init dm_parse_devices(struct list_head *devices, char *str)
0233 {
0234 unsigned long ndev = 0;
0235 struct dm_device *dev;
0236 char *device = str;
0237
0238 DMDEBUG("parsing \"%s\"", str);
0239 while (device) {
0240 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
0241 if (!dev)
0242 return -ENOMEM;
0243 list_add_tail(&dev->list, devices);
0244
0245 if (++ndev > DM_MAX_DEVICES) {
0246 DMERR("too many devices %lu > %d",
0247 ndev, DM_MAX_DEVICES);
0248 return -EINVAL;
0249 }
0250
0251 device = dm_parse_device_entry(dev, device);
0252 if (IS_ERR(device)) {
0253 DMERR("couldn't parse device");
0254 return PTR_ERR(device);
0255 }
0256 }
0257
0258 return 0;
0259 }
0260
0261
0262
0263
0264 static int __init dm_init_init(void)
0265 {
0266 struct dm_device *dev;
0267 LIST_HEAD(devices);
0268 char *str;
0269 int r;
0270
0271 if (!create)
0272 return 0;
0273
0274 if (strlen(create) >= DM_MAX_STR_SIZE) {
0275 DMERR("Argument is too big. Limit is %d", DM_MAX_STR_SIZE);
0276 return -EINVAL;
0277 }
0278 str = kstrndup(create, DM_MAX_STR_SIZE, GFP_KERNEL);
0279 if (!str)
0280 return -ENOMEM;
0281
0282 r = dm_parse_devices(&devices, str);
0283 if (r)
0284 goto out;
0285
0286 DMINFO("waiting for all devices to be available before creating mapped devices");
0287 wait_for_device_probe();
0288
0289 list_for_each_entry(dev, &devices, list) {
0290 if (dm_early_create(&dev->dmi, dev->table,
0291 dev->target_args_array))
0292 break;
0293 }
0294 out:
0295 kfree(str);
0296 dm_setup_cleanup(&devices);
0297 return r;
0298 }
0299
0300 late_initcall(dm_init_init);
0301
0302 module_param(create, charp, 0);
0303 MODULE_PARM_DESC(create, "Create a mapped device in early boot");