diff options
Diffstat (limited to 'drivers/md/dm-table.c')
-rw-r--r-- | drivers/md/dm-table.c | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 8f56a54cf0ce..75fe9493e6af 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/mutex.h> | 17 | #include <linux/mutex.h> |
18 | #include <asm/atomic.h> | 18 | #include <asm/atomic.h> |
19 | 19 | ||
20 | #define DM_MSG_PREFIX "table" | ||
21 | |||
20 | #define MAX_DEPTH 16 | 22 | #define MAX_DEPTH 16 |
21 | #define NODE_SIZE L1_CACHE_BYTES | 23 | #define NODE_SIZE L1_CACHE_BYTES |
22 | #define KEYS_PER_NODE (NODE_SIZE / sizeof(sector_t)) | 24 | #define KEYS_PER_NODE (NODE_SIZE / sizeof(sector_t)) |
@@ -237,6 +239,44 @@ int dm_table_create(struct dm_table **result, int mode, | |||
237 | return 0; | 239 | return 0; |
238 | } | 240 | } |
239 | 241 | ||
242 | int dm_create_error_table(struct dm_table **result, struct mapped_device *md) | ||
243 | { | ||
244 | struct dm_table *t; | ||
245 | sector_t dev_size = 1; | ||
246 | int r; | ||
247 | |||
248 | /* | ||
249 | * Find current size of device. | ||
250 | * Default to 1 sector if inactive. | ||
251 | */ | ||
252 | t = dm_get_table(md); | ||
253 | if (t) { | ||
254 | dev_size = dm_table_get_size(t); | ||
255 | dm_table_put(t); | ||
256 | } | ||
257 | |||
258 | r = dm_table_create(&t, FMODE_READ, 1, md); | ||
259 | if (r) | ||
260 | return r; | ||
261 | |||
262 | r = dm_table_add_target(t, "error", 0, dev_size, NULL); | ||
263 | if (r) | ||
264 | goto out; | ||
265 | |||
266 | r = dm_table_complete(t); | ||
267 | if (r) | ||
268 | goto out; | ||
269 | |||
270 | *result = t; | ||
271 | |||
272 | out: | ||
273 | if (r) | ||
274 | dm_table_put(t); | ||
275 | |||
276 | return r; | ||
277 | } | ||
278 | EXPORT_SYMBOL_GPL(dm_create_error_table); | ||
279 | |||
240 | static void free_devices(struct list_head *devices) | 280 | static void free_devices(struct list_head *devices) |
241 | { | 281 | { |
242 | struct list_head *tmp, *next; | 282 | struct list_head *tmp, *next; |
@@ -590,6 +630,12 @@ int dm_split_args(int *argc, char ***argvp, char *input) | |||
590 | unsigned array_size = 0; | 630 | unsigned array_size = 0; |
591 | 631 | ||
592 | *argc = 0; | 632 | *argc = 0; |
633 | |||
634 | if (!input) { | ||
635 | *argvp = NULL; | ||
636 | return 0; | ||
637 | } | ||
638 | |||
593 | argv = realloc_argv(&array_size, argv); | 639 | argv = realloc_argv(&array_size, argv); |
594 | if (!argv) | 640 | if (!argv) |
595 | return -ENOMEM; | 641 | return -ENOMEM; |
@@ -671,15 +717,14 @@ int dm_table_add_target(struct dm_table *t, const char *type, | |||
671 | memset(tgt, 0, sizeof(*tgt)); | 717 | memset(tgt, 0, sizeof(*tgt)); |
672 | 718 | ||
673 | if (!len) { | 719 | if (!len) { |
674 | tgt->error = "zero-length target"; | 720 | DMERR("%s: zero-length target", dm_device_name(t->md)); |
675 | DMERR("%s", tgt->error); | ||
676 | return -EINVAL; | 721 | return -EINVAL; |
677 | } | 722 | } |
678 | 723 | ||
679 | tgt->type = dm_get_target_type(type); | 724 | tgt->type = dm_get_target_type(type); |
680 | if (!tgt->type) { | 725 | if (!tgt->type) { |
681 | tgt->error = "unknown target type"; | 726 | DMERR("%s: %s: unknown target type", dm_device_name(t->md), |
682 | DMERR("%s", tgt->error); | 727 | type); |
683 | return -EINVAL; | 728 | return -EINVAL; |
684 | } | 729 | } |
685 | 730 | ||
@@ -716,7 +761,7 @@ int dm_table_add_target(struct dm_table *t, const char *type, | |||
716 | return 0; | 761 | return 0; |
717 | 762 | ||
718 | bad: | 763 | bad: |
719 | DMERR("%s", tgt->error); | 764 | DMERR("%s: %s: %s", dm_device_name(t->md), type, tgt->error); |
720 | dm_put_target_type(tgt->type); | 765 | dm_put_target_type(tgt->type); |
721 | return r; | 766 | return r; |
722 | } | 767 | } |
@@ -802,7 +847,7 @@ sector_t dm_table_get_size(struct dm_table *t) | |||
802 | 847 | ||
803 | struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index) | 848 | struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index) |
804 | { | 849 | { |
805 | if (index > t->num_targets) | 850 | if (index >= t->num_targets) |
806 | return NULL; | 851 | return NULL; |
807 | 852 | ||
808 | return t->targets + index; | 853 | return t->targets + index; |