diff options
author | Jonathan Brassow <jbrassow@redhat.com> | 2009-04-02 14:55:31 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2009-04-02 14:55:31 -0400 |
commit | 493df71c6420b211a68ae82b889c1e8a5fe701be (patch) | |
tree | 2738295190c1b3c5f72d85059aae3c96f162afa6 /drivers/md | |
parent | 7513c2a761d69d2a93f17146b3563527d3618ba0 (diff) |
dm exception store: introduce registry
Move exception stores into a registry.
Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-exception-store.c | 162 | ||||
-rw-r--r-- | drivers/md/dm-exception-store.h | 19 | ||||
-rw-r--r-- | drivers/md/dm-snap-persistent.c | 67 | ||||
-rw-r--r-- | drivers/md/dm-snap-transient.c | 65 | ||||
-rw-r--r-- | drivers/md/dm-snap.c | 41 | ||||
-rw-r--r-- | drivers/md/dm-snap.h | 2 |
6 files changed, 307 insertions, 49 deletions
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index dccbfb0e010f..8912a3637cae 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c | |||
@@ -14,6 +14,168 @@ | |||
14 | 14 | ||
15 | #define DM_MSG_PREFIX "snapshot exception stores" | 15 | #define DM_MSG_PREFIX "snapshot exception stores" |
16 | 16 | ||
17 | static LIST_HEAD(_exception_store_types); | ||
18 | static DEFINE_SPINLOCK(_lock); | ||
19 | |||
20 | static struct dm_exception_store_type *__find_exception_store_type(const char *name) | ||
21 | { | ||
22 | struct dm_exception_store_type *type; | ||
23 | |||
24 | list_for_each_entry(type, &_exception_store_types, list) | ||
25 | if (!strcmp(name, type->name)) | ||
26 | return type; | ||
27 | |||
28 | return NULL; | ||
29 | } | ||
30 | |||
31 | static struct dm_exception_store_type *_get_exception_store_type(const char *name) | ||
32 | { | ||
33 | struct dm_exception_store_type *type; | ||
34 | |||
35 | spin_lock(&_lock); | ||
36 | |||
37 | type = __find_exception_store_type(name); | ||
38 | |||
39 | if (type && !try_module_get(type->module)) | ||
40 | type = NULL; | ||
41 | |||
42 | spin_unlock(&_lock); | ||
43 | |||
44 | return type; | ||
45 | } | ||
46 | |||
47 | /* | ||
48 | * get_type | ||
49 | * @type_name | ||
50 | * | ||
51 | * Attempt to retrieve the dm_exception_store_type by name. If not already | ||
52 | * available, attempt to load the appropriate module. | ||
53 | * | ||
54 | * Exstore modules are named "dm-exstore-" followed by the 'type_name'. | ||
55 | * Modules may contain multiple types. | ||
56 | * This function will first try the module "dm-exstore-<type_name>", | ||
57 | * then truncate 'type_name' on the last '-' and try again. | ||
58 | * | ||
59 | * For example, if type_name was "clustered-shared", it would search | ||
60 | * 'dm-exstore-clustered-shared' then 'dm-exstore-clustered'. | ||
61 | * | ||
62 | * 'dm-exception-store-<type_name>' is too long of a name in my | ||
63 | * opinion, which is why I've chosen to have the files | ||
64 | * containing exception store implementations be 'dm-exstore-<type_name>'. | ||
65 | * If you want your module to be autoloaded, you will follow this | ||
66 | * naming convention. | ||
67 | * | ||
68 | * Returns: dm_exception_store_type* on success, NULL on failure | ||
69 | */ | ||
70 | static struct dm_exception_store_type *get_type(const char *type_name) | ||
71 | { | ||
72 | char *p, *type_name_dup; | ||
73 | struct dm_exception_store_type *type; | ||
74 | |||
75 | type = _get_exception_store_type(type_name); | ||
76 | if (type) | ||
77 | return type; | ||
78 | |||
79 | type_name_dup = kstrdup(type_name, GFP_KERNEL); | ||
80 | if (!type_name_dup) { | ||
81 | DMERR("No memory left to attempt load for \"%s\"", type_name); | ||
82 | return NULL; | ||
83 | } | ||
84 | |||
85 | while (request_module("dm-exstore-%s", type_name_dup) || | ||
86 | !(type = _get_exception_store_type(type_name))) { | ||
87 | p = strrchr(type_name_dup, '-'); | ||
88 | if (!p) | ||
89 | break; | ||
90 | p[0] = '\0'; | ||
91 | } | ||
92 | |||
93 | if (!type) | ||
94 | DMWARN("Module for exstore type \"%s\" not found.", type_name); | ||
95 | |||
96 | kfree(type_name_dup); | ||
97 | |||
98 | return type; | ||
99 | } | ||
100 | |||
101 | static void put_type(struct dm_exception_store_type *type) | ||
102 | { | ||
103 | spin_lock(&_lock); | ||
104 | module_put(type->module); | ||
105 | spin_unlock(&_lock); | ||
106 | } | ||
107 | |||
108 | int dm_exception_store_type_register(struct dm_exception_store_type *type) | ||
109 | { | ||
110 | int r = 0; | ||
111 | |||
112 | spin_lock(&_lock); | ||
113 | if (!__find_exception_store_type(type->name)) | ||
114 | list_add(&type->list, &_exception_store_types); | ||
115 | else | ||
116 | r = -EEXIST; | ||
117 | spin_unlock(&_lock); | ||
118 | |||
119 | return r; | ||
120 | } | ||
121 | EXPORT_SYMBOL(dm_exception_store_type_register); | ||
122 | |||
123 | int dm_exception_store_type_unregister(struct dm_exception_store_type *type) | ||
124 | { | ||
125 | spin_lock(&_lock); | ||
126 | |||
127 | if (!__find_exception_store_type(type->name)) { | ||
128 | spin_unlock(&_lock); | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | |||
132 | list_del(&type->list); | ||
133 | |||
134 | spin_unlock(&_lock); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | EXPORT_SYMBOL(dm_exception_store_type_unregister); | ||
139 | |||
140 | int dm_exception_store_create(const char *type_name, | ||
141 | struct dm_exception_store **store) | ||
142 | { | ||
143 | int r = 0; | ||
144 | struct dm_exception_store_type *type; | ||
145 | struct dm_exception_store *tmp_store; | ||
146 | |||
147 | tmp_store = kmalloc(sizeof(*tmp_store), GFP_KERNEL); | ||
148 | if (!tmp_store) | ||
149 | return -ENOMEM; | ||
150 | |||
151 | type = get_type(type_name); | ||
152 | if (!type) { | ||
153 | kfree(tmp_store); | ||
154 | return -EINVAL; | ||
155 | } | ||
156 | |||
157 | tmp_store->type = type; | ||
158 | |||
159 | r = type->ctr(tmp_store, 0, NULL); | ||
160 | if (r) { | ||
161 | put_type(type); | ||
162 | kfree(tmp_store); | ||
163 | return r; | ||
164 | } | ||
165 | |||
166 | *store = tmp_store; | ||
167 | return 0; | ||
168 | } | ||
169 | EXPORT_SYMBOL(dm_exception_store_create); | ||
170 | |||
171 | void dm_exception_store_destroy(struct dm_exception_store *store) | ||
172 | { | ||
173 | store->type->dtr(store); | ||
174 | put_type(store->type); | ||
175 | kfree(store); | ||
176 | } | ||
177 | EXPORT_SYMBOL(dm_exception_store_destroy); | ||
178 | |||
17 | int dm_exception_store_init(void) | 179 | int dm_exception_store_init(void) |
18 | { | 180 | { |
19 | int r; | 181 | int r; |
diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h index aed1f1172f9e..31377150080e 100644 --- a/drivers/md/dm-exception-store.h +++ b/drivers/md/dm-exception-store.h | |||
@@ -39,6 +39,9 @@ struct dm_snap_exception { | |||
39 | */ | 39 | */ |
40 | struct dm_exception_store; | 40 | struct dm_exception_store; |
41 | struct dm_exception_store_type { | 41 | struct dm_exception_store_type { |
42 | const char *name; | ||
43 | struct module *module; | ||
44 | |||
42 | int (*ctr) (struct dm_exception_store *store, | 45 | int (*ctr) (struct dm_exception_store *store, |
43 | unsigned argc, char **argv); | 46 | unsigned argc, char **argv); |
44 | 47 | ||
@@ -85,10 +88,13 @@ struct dm_exception_store_type { | |||
85 | void (*fraction_full) (struct dm_exception_store *store, | 88 | void (*fraction_full) (struct dm_exception_store *store, |
86 | sector_t *numerator, | 89 | sector_t *numerator, |
87 | sector_t *denominator); | 90 | sector_t *denominator); |
91 | |||
92 | /* For internal device-mapper use only. */ | ||
93 | struct list_head list; | ||
88 | }; | 94 | }; |
89 | 95 | ||
90 | struct dm_exception_store { | 96 | struct dm_exception_store { |
91 | struct dm_exception_store_type type; | 97 | struct dm_exception_store_type *type; |
92 | 98 | ||
93 | struct dm_snapshot *snap; | 99 | struct dm_snapshot *snap; |
94 | 100 | ||
@@ -138,6 +144,13 @@ static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e) | |||
138 | 144 | ||
139 | # endif | 145 | # endif |
140 | 146 | ||
147 | int dm_exception_store_type_register(struct dm_exception_store_type *type); | ||
148 | int dm_exception_store_type_unregister(struct dm_exception_store_type *type); | ||
149 | |||
150 | int dm_exception_store_create(const char *type_name, | ||
151 | struct dm_exception_store **store); | ||
152 | void dm_exception_store_destroy(struct dm_exception_store *store); | ||
153 | |||
141 | int dm_exception_store_init(void); | 154 | int dm_exception_store_init(void); |
142 | void dm_exception_store_exit(void); | 155 | void dm_exception_store_exit(void); |
143 | 156 | ||
@@ -150,8 +163,4 @@ void dm_persistent_snapshot_exit(void); | |||
150 | int dm_transient_snapshot_init(void); | 163 | int dm_transient_snapshot_init(void); |
151 | void dm_transient_snapshot_exit(void); | 164 | void dm_transient_snapshot_exit(void); |
152 | 165 | ||
153 | int dm_create_persistent(struct dm_exception_store *store); | ||
154 | |||
155 | int dm_create_transient(struct dm_exception_store *store); | ||
156 | |||
157 | #endif /* _LINUX_DM_EXCEPTION_STORE */ | 166 | #endif /* _LINUX_DM_EXCEPTION_STORE */ |
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 0bbbe3b7431e..e85b7a186a13 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c | |||
@@ -478,7 +478,7 @@ static void persistent_fraction_full(struct dm_exception_store *store, | |||
478 | *denominator = get_dev_size(store->snap->cow->bdev); | 478 | *denominator = get_dev_size(store->snap->cow->bdev); |
479 | } | 479 | } |
480 | 480 | ||
481 | static void persistent_destroy(struct dm_exception_store *store) | 481 | static void persistent_dtr(struct dm_exception_store *store) |
482 | { | 482 | { |
483 | struct pstore *ps = get_info(store); | 483 | struct pstore *ps = get_info(store); |
484 | 484 | ||
@@ -656,7 +656,8 @@ static void persistent_drop_snapshot(struct dm_exception_store *store) | |||
656 | DMWARN("write header failed"); | 656 | DMWARN("write header failed"); |
657 | } | 657 | } |
658 | 658 | ||
659 | int dm_create_persistent(struct dm_exception_store *store) | 659 | static int persistent_ctr(struct dm_exception_store *store, |
660 | unsigned argc, char **argv) | ||
660 | { | 661 | { |
661 | struct pstore *ps; | 662 | struct pstore *ps; |
662 | 663 | ||
@@ -683,23 +684,69 @@ int dm_create_persistent(struct dm_exception_store *store) | |||
683 | return -ENOMEM; | 684 | return -ENOMEM; |
684 | } | 685 | } |
685 | 686 | ||
686 | store->type.dtr = persistent_destroy; | ||
687 | store->type.read_metadata = persistent_read_metadata; | ||
688 | store->type.prepare_exception = persistent_prepare_exception; | ||
689 | store->type.commit_exception = persistent_commit_exception; | ||
690 | store->type.drop_snapshot = persistent_drop_snapshot; | ||
691 | store->type.fraction_full = persistent_fraction_full; | ||
692 | |||
693 | store->context = ps; | 687 | store->context = ps; |
694 | 688 | ||
695 | return 0; | 689 | return 0; |
696 | } | 690 | } |
697 | 691 | ||
692 | static int persistent_status(struct dm_exception_store *store, | ||
693 | status_type_t status, char *result, | ||
694 | unsigned int maxlen) | ||
695 | { | ||
696 | int sz = 0; | ||
697 | |||
698 | return sz; | ||
699 | } | ||
700 | |||
701 | static struct dm_exception_store_type _persistent_type = { | ||
702 | .name = "persistent", | ||
703 | .module = THIS_MODULE, | ||
704 | .ctr = persistent_ctr, | ||
705 | .dtr = persistent_dtr, | ||
706 | .read_metadata = persistent_read_metadata, | ||
707 | .prepare_exception = persistent_prepare_exception, | ||
708 | .commit_exception = persistent_commit_exception, | ||
709 | .drop_snapshot = persistent_drop_snapshot, | ||
710 | .fraction_full = persistent_fraction_full, | ||
711 | .status = persistent_status, | ||
712 | }; | ||
713 | |||
714 | static struct dm_exception_store_type _persistent_compat_type = { | ||
715 | .name = "P", | ||
716 | .module = THIS_MODULE, | ||
717 | .ctr = persistent_ctr, | ||
718 | .dtr = persistent_dtr, | ||
719 | .read_metadata = persistent_read_metadata, | ||
720 | .prepare_exception = persistent_prepare_exception, | ||
721 | .commit_exception = persistent_commit_exception, | ||
722 | .drop_snapshot = persistent_drop_snapshot, | ||
723 | .fraction_full = persistent_fraction_full, | ||
724 | .status = persistent_status, | ||
725 | }; | ||
726 | |||
698 | int dm_persistent_snapshot_init(void) | 727 | int dm_persistent_snapshot_init(void) |
699 | { | 728 | { |
700 | return 0; | 729 | int r; |
730 | |||
731 | r = dm_exception_store_type_register(&_persistent_type); | ||
732 | if (r) { | ||
733 | DMERR("Unable to register persistent exception store type"); | ||
734 | return r; | ||
735 | } | ||
736 | |||
737 | r = dm_exception_store_type_register(&_persistent_compat_type); | ||
738 | if (r) { | ||
739 | DMERR("Unable to register old-style persistent exception " | ||
740 | "store type"); | ||
741 | dm_exception_store_type_unregister(&_persistent_type); | ||
742 | return r; | ||
743 | } | ||
744 | |||
745 | return r; | ||
701 | } | 746 | } |
702 | 747 | ||
703 | void dm_persistent_snapshot_exit(void) | 748 | void dm_persistent_snapshot_exit(void) |
704 | { | 749 | { |
750 | dm_exception_store_type_unregister(&_persistent_type); | ||
751 | dm_exception_store_type_unregister(&_persistent_compat_type); | ||
705 | } | 752 | } |
diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c index b558176ff020..51bc4a78ce9a 100644 --- a/drivers/md/dm-snap-transient.c +++ b/drivers/md/dm-snap-transient.c | |||
@@ -23,7 +23,7 @@ struct transient_c { | |||
23 | sector_t next_free; | 23 | sector_t next_free; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | static void transient_destroy(struct dm_exception_store *store) | 26 | static void transient_dtr(struct dm_exception_store *store) |
27 | { | 27 | { |
28 | kfree(store->context); | 28 | kfree(store->context); |
29 | } | 29 | } |
@@ -67,17 +67,11 @@ static void transient_fraction_full(struct dm_exception_store *store, | |||
67 | *denominator = get_dev_size(store->snap->cow->bdev); | 67 | *denominator = get_dev_size(store->snap->cow->bdev); |
68 | } | 68 | } |
69 | 69 | ||
70 | int dm_create_transient(struct dm_exception_store *store) | 70 | static int transient_ctr(struct dm_exception_store *store, |
71 | unsigned argc, char **argv) | ||
71 | { | 72 | { |
72 | struct transient_c *tc; | 73 | struct transient_c *tc; |
73 | 74 | ||
74 | store->type.dtr = transient_destroy; | ||
75 | store->type.read_metadata = transient_read_metadata; | ||
76 | store->type.prepare_exception = transient_prepare_exception; | ||
77 | store->type.commit_exception = transient_commit_exception; | ||
78 | store->type.drop_snapshot = NULL; | ||
79 | store->type.fraction_full = transient_fraction_full; | ||
80 | |||
81 | tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL); | 75 | tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL); |
82 | if (!tc) | 76 | if (!tc) |
83 | return -ENOMEM; | 77 | return -ENOMEM; |
@@ -88,11 +82,62 @@ int dm_create_transient(struct dm_exception_store *store) | |||
88 | return 0; | 82 | return 0; |
89 | } | 83 | } |
90 | 84 | ||
85 | static int transient_status(struct dm_exception_store *store, | ||
86 | status_type_t status, char *result, | ||
87 | unsigned maxlen) | ||
88 | { | ||
89 | int sz = 0; | ||
90 | |||
91 | return sz; | ||
92 | } | ||
93 | |||
94 | static struct dm_exception_store_type _transient_type = { | ||
95 | .name = "transient", | ||
96 | .module = THIS_MODULE, | ||
97 | .ctr = transient_ctr, | ||
98 | .dtr = transient_dtr, | ||
99 | .read_metadata = transient_read_metadata, | ||
100 | .prepare_exception = transient_prepare_exception, | ||
101 | .commit_exception = transient_commit_exception, | ||
102 | .fraction_full = transient_fraction_full, | ||
103 | .status = transient_status, | ||
104 | }; | ||
105 | |||
106 | static struct dm_exception_store_type _transient_compat_type = { | ||
107 | .name = "N", | ||
108 | .module = THIS_MODULE, | ||
109 | .ctr = transient_ctr, | ||
110 | .dtr = transient_dtr, | ||
111 | .read_metadata = transient_read_metadata, | ||
112 | .prepare_exception = transient_prepare_exception, | ||
113 | .commit_exception = transient_commit_exception, | ||
114 | .fraction_full = transient_fraction_full, | ||
115 | .status = transient_status, | ||
116 | }; | ||
117 | |||
91 | int dm_transient_snapshot_init(void) | 118 | int dm_transient_snapshot_init(void) |
92 | { | 119 | { |
93 | return 0; | 120 | int r; |
121 | |||
122 | r = dm_exception_store_type_register(&_transient_type); | ||
123 | if (r) { | ||
124 | DMWARN("Unable to register transient exception store type"); | ||
125 | return r; | ||
126 | } | ||
127 | |||
128 | r = dm_exception_store_type_register(&_transient_compat_type); | ||
129 | if (r) { | ||
130 | DMWARN("Unable to register old-style transient " | ||
131 | "exception store type"); | ||
132 | dm_exception_store_type_unregister(&_transient_type); | ||
133 | return r; | ||
134 | } | ||
135 | |||
136 | return r; | ||
94 | } | 137 | } |
95 | 138 | ||
96 | void dm_transient_snapshot_exit(void) | 139 | void dm_transient_snapshot_exit(void) |
97 | { | 140 | { |
141 | dm_exception_store_type_unregister(&_transient_type); | ||
142 | dm_exception_store_type_unregister(&_transient_compat_type); | ||
98 | } | 143 | } |
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index dabd58e9aafc..be698f3a4ae4 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -610,8 +610,6 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
610 | if (r) | 610 | if (r) |
611 | goto bad3; | 611 | goto bad3; |
612 | 612 | ||
613 | s->type = persistent; | ||
614 | |||
615 | s->valid = 1; | 613 | s->valid = 1; |
616 | s->active = 0; | 614 | s->active = 0; |
617 | atomic_set(&s->pending_exceptions_count, 0); | 615 | atomic_set(&s->pending_exceptions_count, 0); |
@@ -626,19 +624,15 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
626 | goto bad3; | 624 | goto bad3; |
627 | } | 625 | } |
628 | 626 | ||
629 | s->store.snap = s; | 627 | r = dm_exception_store_create(argv[2], &s->store); |
630 | |||
631 | if (persistent == 'P') | ||
632 | r = dm_create_persistent(&s->store); | ||
633 | else | ||
634 | r = dm_create_transient(&s->store); | ||
635 | |||
636 | if (r) { | 628 | if (r) { |
637 | ti->error = "Couldn't create exception store"; | 629 | ti->error = "Couldn't create exception store"; |
638 | r = -EINVAL; | 630 | r = -EINVAL; |
639 | goto bad4; | 631 | goto bad4; |
640 | } | 632 | } |
641 | 633 | ||
634 | s->store->snap = s; | ||
635 | |||
642 | r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client); | 636 | r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client); |
643 | if (r) { | 637 | if (r) { |
644 | ti->error = "Could not create kcopyd client"; | 638 | ti->error = "Could not create kcopyd client"; |
@@ -665,7 +659,8 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
665 | spin_lock_init(&s->tracked_chunk_lock); | 659 | spin_lock_init(&s->tracked_chunk_lock); |
666 | 660 | ||
667 | /* Metadata must only be loaded into one table at once */ | 661 | /* Metadata must only be loaded into one table at once */ |
668 | r = s->store.type.read_metadata(&s->store, dm_add_exception, (void *)s); | 662 | r = s->store->type->read_metadata(s->store, dm_add_exception, |
663 | (void *)s); | ||
669 | if (r < 0) { | 664 | if (r < 0) { |
670 | ti->error = "Failed to read snapshot metadata"; | 665 | ti->error = "Failed to read snapshot metadata"; |
671 | goto bad_load_and_register; | 666 | goto bad_load_and_register; |
@@ -700,7 +695,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
700 | dm_kcopyd_client_destroy(s->kcopyd_client); | 695 | dm_kcopyd_client_destroy(s->kcopyd_client); |
701 | 696 | ||
702 | bad5: | 697 | bad5: |
703 | s->store.type.dtr(&s->store); | 698 | s->store->type->dtr(s->store); |
704 | 699 | ||
705 | bad4: | 700 | bad4: |
706 | exit_exception_table(&s->pending, pending_cache); | 701 | exit_exception_table(&s->pending, pending_cache); |
@@ -725,7 +720,7 @@ static void __free_exceptions(struct dm_snapshot *s) | |||
725 | exit_exception_table(&s->pending, pending_cache); | 720 | exit_exception_table(&s->pending, pending_cache); |
726 | exit_exception_table(&s->complete, exception_cache); | 721 | exit_exception_table(&s->complete, exception_cache); |
727 | 722 | ||
728 | s->store.type.dtr(&s->store); | 723 | s->store->type->dtr(s->store); |
729 | } | 724 | } |
730 | 725 | ||
731 | static void snapshot_dtr(struct dm_target *ti) | 726 | static void snapshot_dtr(struct dm_target *ti) |
@@ -820,8 +815,8 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err) | |||
820 | else if (err == -ENOMEM) | 815 | else if (err == -ENOMEM) |
821 | DMERR("Invalidating snapshot: Unable to allocate exception."); | 816 | DMERR("Invalidating snapshot: Unable to allocate exception."); |
822 | 817 | ||
823 | if (s->store.type.drop_snapshot) | 818 | if (s->store->type->drop_snapshot) |
824 | s->store.type.drop_snapshot(&s->store); | 819 | s->store->type->drop_snapshot(s->store); |
825 | 820 | ||
826 | s->valid = 0; | 821 | s->valid = 0; |
827 | 822 | ||
@@ -943,8 +938,8 @@ static void copy_callback(int read_err, unsigned long write_err, void *context) | |||
943 | 938 | ||
944 | else | 939 | else |
945 | /* Update the metadata if we are persistent */ | 940 | /* Update the metadata if we are persistent */ |
946 | s->store.type.commit_exception(&s->store, &pe->e, | 941 | s->store->type->commit_exception(s->store, &pe->e, |
947 | commit_callback, pe); | 942 | commit_callback, pe); |
948 | } | 943 | } |
949 | 944 | ||
950 | /* | 945 | /* |
@@ -1010,7 +1005,7 @@ __find_pending_exception(struct dm_snapshot *s, | |||
1010 | atomic_set(&pe->ref_count, 0); | 1005 | atomic_set(&pe->ref_count, 0); |
1011 | pe->started = 0; | 1006 | pe->started = 0; |
1012 | 1007 | ||
1013 | if (s->store.type.prepare_exception(&s->store, &pe->e)) { | 1008 | if (s->store->type->prepare_exception(s->store, &pe->e)) { |
1014 | free_pending_exception(pe); | 1009 | free_pending_exception(pe); |
1015 | return NULL; | 1010 | return NULL; |
1016 | } | 1011 | } |
@@ -1149,11 +1144,11 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, | |||
1149 | if (!snap->valid) | 1144 | if (!snap->valid) |
1150 | snprintf(result, maxlen, "Invalid"); | 1145 | snprintf(result, maxlen, "Invalid"); |
1151 | else { | 1146 | else { |
1152 | if (snap->store.type.fraction_full) { | 1147 | if (snap->store->type->fraction_full) { |
1153 | sector_t numerator, denominator; | 1148 | sector_t numerator, denominator; |
1154 | snap->store.type.fraction_full(&snap->store, | 1149 | snap->store->type->fraction_full(snap->store, |
1155 | &numerator, | 1150 | &numerator, |
1156 | &denominator); | 1151 | &denominator); |
1157 | snprintf(result, maxlen, "%llu/%llu", | 1152 | snprintf(result, maxlen, "%llu/%llu", |
1158 | (unsigned long long)numerator, | 1153 | (unsigned long long)numerator, |
1159 | (unsigned long long)denominator); | 1154 | (unsigned long long)denominator); |
@@ -1169,9 +1164,9 @@ static int snapshot_status(struct dm_target *ti, status_type_t type, | |||
1169 | * to make private copies if the output is to | 1164 | * to make private copies if the output is to |
1170 | * make sense. | 1165 | * make sense. |
1171 | */ | 1166 | */ |
1172 | snprintf(result, maxlen, "%s %s %c %llu", | 1167 | snprintf(result, maxlen, "%s %s %s %llu", |
1173 | snap->origin->name, snap->cow->name, | 1168 | snap->origin->name, snap->cow->name, |
1174 | snap->type, | 1169 | snap->store->type->name, |
1175 | (unsigned long long)snap->chunk_size); | 1170 | (unsigned long long)snap->chunk_size); |
1176 | break; | 1171 | break; |
1177 | } | 1172 | } |
diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h index d9e62b43cf85..627be0f52c32 100644 --- a/drivers/md/dm-snap.h +++ b/drivers/md/dm-snap.h | |||
@@ -61,7 +61,7 @@ struct dm_snapshot { | |||
61 | spinlock_t pe_lock; | 61 | spinlock_t pe_lock; |
62 | 62 | ||
63 | /* The on disk metadata handler */ | 63 | /* The on disk metadata handler */ |
64 | struct dm_exception_store store; | 64 | struct dm_exception_store *store; |
65 | 65 | ||
66 | struct dm_kcopyd_client *kcopyd_client; | 66 | struct dm_kcopyd_client *kcopyd_client; |
67 | 67 | ||