aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-log.c58
-rw-r--r--include/linux/dm-dirty-log.h3
2 files changed, 17 insertions, 44 deletions
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 094c8f0e0097..be233bc4d917 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -16,34 +16,28 @@
16 16
17#define DM_MSG_PREFIX "dirty region log" 17#define DM_MSG_PREFIX "dirty region log"
18 18
19struct dm_dirty_log_internal {
20 struct dm_dirty_log_type *type;
21
22 struct list_head list;
23};
24
25static LIST_HEAD(_log_types); 19static LIST_HEAD(_log_types);
26static DEFINE_SPINLOCK(_lock); 20static DEFINE_SPINLOCK(_lock);
27 21
28static struct dm_dirty_log_internal *__find_dirty_log_type(const char *name) 22static struct dm_dirty_log_type *__find_dirty_log_type(const char *name)
29{ 23{
30 struct dm_dirty_log_internal *log_type; 24 struct dm_dirty_log_type *log_type;
31 25
32 list_for_each_entry(log_type, &_log_types, list) 26 list_for_each_entry(log_type, &_log_types, list)
33 if (!strcmp(name, log_type->type->name)) 27 if (!strcmp(name, log_type->name))
34 return log_type; 28 return log_type;
35 29
36 return NULL; 30 return NULL;
37} 31}
38 32
39static struct dm_dirty_log_internal *_get_dirty_log_type(const char *name) 33static struct dm_dirty_log_type *_get_dirty_log_type(const char *name)
40{ 34{
41 struct dm_dirty_log_internal *log_type; 35 struct dm_dirty_log_type *log_type;
42 36
43 spin_lock(&_lock); 37 spin_lock(&_lock);
44 38
45 log_type = __find_dirty_log_type(name); 39 log_type = __find_dirty_log_type(name);
46 if (log_type && !try_module_get(log_type->type->module)) 40 if (log_type && !try_module_get(log_type->module))
47 log_type = NULL; 41 log_type = NULL;
48 42
49 spin_unlock(&_lock); 43 spin_unlock(&_lock);
@@ -71,14 +65,14 @@ static struct dm_dirty_log_internal *_get_dirty_log_type(const char *name)
71static struct dm_dirty_log_type *get_type(const char *type_name) 65static struct dm_dirty_log_type *get_type(const char *type_name)
72{ 66{
73 char *p, *type_name_dup; 67 char *p, *type_name_dup;
74 struct dm_dirty_log_internal *log_type; 68 struct dm_dirty_log_type *log_type;
75 69
76 if (!type_name) 70 if (!type_name)
77 return NULL; 71 return NULL;
78 72
79 log_type = _get_dirty_log_type(type_name); 73 log_type = _get_dirty_log_type(type_name);
80 if (log_type) 74 if (log_type)
81 return log_type->type; 75 return log_type;
82 76
83 type_name_dup = kstrdup(type_name, GFP_KERNEL); 77 type_name_dup = kstrdup(type_name, GFP_KERNEL);
84 if (!type_name_dup) { 78 if (!type_name_dup) {
@@ -100,19 +94,16 @@ static struct dm_dirty_log_type *get_type(const char *type_name)
100 94
101 kfree(type_name_dup); 95 kfree(type_name_dup);
102 96
103 return log_type ? log_type->type : NULL; 97 return log_type;
104} 98}
105 99
106static void put_type(struct dm_dirty_log_type *type) 100static void put_type(struct dm_dirty_log_type *type)
107{ 101{
108 struct dm_dirty_log_internal *log_type;
109
110 if (!type) 102 if (!type)
111 return; 103 return;
112 104
113 spin_lock(&_lock); 105 spin_lock(&_lock);
114 log_type = __find_dirty_log_type(type->name); 106 if (!__find_dirty_log_type(type->name))
115 if (!log_type)
116 goto out; 107 goto out;
117 108
118 module_put(type->module); 109 module_put(type->module);
@@ -121,32 +112,15 @@ out:
121 spin_unlock(&_lock); 112 spin_unlock(&_lock);
122} 113}
123 114
124static struct dm_dirty_log_internal *_alloc_dirty_log_type(struct dm_dirty_log_type *type)
125{
126 struct dm_dirty_log_internal *log_type = kzalloc(sizeof(*log_type),
127 GFP_KERNEL);
128
129 if (log_type)
130 log_type->type = type;
131
132 return log_type;
133}
134
135int dm_dirty_log_type_register(struct dm_dirty_log_type *type) 115int dm_dirty_log_type_register(struct dm_dirty_log_type *type)
136{ 116{
137 struct dm_dirty_log_internal *log_type = _alloc_dirty_log_type(type);
138 int r = 0; 117 int r = 0;
139 118
140 if (!log_type)
141 return -ENOMEM;
142
143 spin_lock(&_lock); 119 spin_lock(&_lock);
144 if (!__find_dirty_log_type(type->name)) 120 if (!__find_dirty_log_type(type->name))
145 list_add(&log_type->list, &_log_types); 121 list_add(&type->list, &_log_types);
146 else { 122 else
147 kfree(log_type);
148 r = -EEXIST; 123 r = -EEXIST;
149 }
150 spin_unlock(&_lock); 124 spin_unlock(&_lock);
151 125
152 return r; 126 return r;
@@ -155,20 +129,16 @@ EXPORT_SYMBOL(dm_dirty_log_type_register);
155 129
156int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type) 130int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type)
157{ 131{
158 struct dm_dirty_log_internal *log_type;
159
160 spin_lock(&_lock); 132 spin_lock(&_lock);
161 133
162 log_type = __find_dirty_log_type(type->name); 134 if (!__find_dirty_log_type(type->name)) {
163 if (!log_type) {
164 spin_unlock(&_lock); 135 spin_unlock(&_lock);
165 return -EINVAL; 136 return -EINVAL;
166 } 137 }
167 138
168 list_del(&log_type->list); 139 list_del(&type->list);
169 140
170 spin_unlock(&_lock); 141 spin_unlock(&_lock);
171 kfree(log_type);
172 142
173 return 0; 143 return 0;
174} 144}
diff --git a/include/linux/dm-dirty-log.h b/include/linux/dm-dirty-log.h
index 600c5fb2daad..727602b686d4 100644
--- a/include/linux/dm-dirty-log.h
+++ b/include/linux/dm-dirty-log.h
@@ -28,6 +28,9 @@ struct dm_dirty_log_type {
28 const char *name; 28 const char *name;
29 struct module *module; 29 struct module *module;
30 30
31 /* For internal device-mapper use */
32 struct list_head list;
33
31 int (*ctr)(struct dm_dirty_log *log, struct dm_target *ti, 34 int (*ctr)(struct dm_dirty_log *log, struct dm_target *ti,
32 unsigned argc, char **argv); 35 unsigned argc, char **argv);
33 void (*dtr)(struct dm_dirty_log *log); 36 void (*dtr)(struct dm_dirty_log *log);