aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-exception-store.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-exception-store.c')
-rw-r--r--drivers/md/dm-exception-store.c30
1 files changed, 11 insertions, 19 deletions
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index 205215968ff1..2b7907b6dd09 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -172,7 +172,8 @@ int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
172 } 172 }
173 173
174 /* Validate the chunk size against the device block size */ 174 /* Validate the chunk size against the device block size */
175 if (chunk_size % (bdev_logical_block_size(store->cow->bdev) >> 9)) { 175 if (chunk_size %
176 (bdev_logical_block_size(dm_snap_cow(store->snap)->bdev) >> 9)) {
176 *error = "Chunk size is not a multiple of device blocksize"; 177 *error = "Chunk size is not a multiple of device blocksize";
177 return -EINVAL; 178 return -EINVAL;
178 } 179 }
@@ -190,6 +191,7 @@ int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
190} 191}
191 192
192int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, 193int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
194 struct dm_snapshot *snap,
193 unsigned *args_used, 195 unsigned *args_used,
194 struct dm_exception_store **store) 196 struct dm_exception_store **store)
195{ 197{
@@ -198,7 +200,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
198 struct dm_exception_store *tmp_store; 200 struct dm_exception_store *tmp_store;
199 char persistent; 201 char persistent;
200 202
201 if (argc < 3) { 203 if (argc < 2) {
202 ti->error = "Insufficient exception store arguments"; 204 ti->error = "Insufficient exception store arguments";
203 return -EINVAL; 205 return -EINVAL;
204 } 206 }
@@ -209,7 +211,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
209 return -ENOMEM; 211 return -ENOMEM;
210 } 212 }
211 213
212 persistent = toupper(*argv[1]); 214 persistent = toupper(*argv[0]);
213 if (persistent == 'P') 215 if (persistent == 'P')
214 type = get_type("P"); 216 type = get_type("P");
215 else if (persistent == 'N') 217 else if (persistent == 'N')
@@ -227,32 +229,23 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
227 } 229 }
228 230
229 tmp_store->type = type; 231 tmp_store->type = type;
230 tmp_store->ti = ti; 232 tmp_store->snap = snap;
231 233
232 r = dm_get_device(ti, argv[0], 0, 0, 234 r = set_chunk_size(tmp_store, argv[1], &ti->error);
233 FMODE_READ | FMODE_WRITE, &tmp_store->cow);
234 if (r) {
235 ti->error = "Cannot get COW device";
236 goto bad_cow;
237 }
238
239 r = set_chunk_size(tmp_store, argv[2], &ti->error);
240 if (r) 235 if (r)
241 goto bad_ctr; 236 goto bad;
242 237
243 r = type->ctr(tmp_store, 0, NULL); 238 r = type->ctr(tmp_store, 0, NULL);
244 if (r) { 239 if (r) {
245 ti->error = "Exception store type constructor failed"; 240 ti->error = "Exception store type constructor failed";
246 goto bad_ctr; 241 goto bad;
247 } 242 }
248 243
249 *args_used = 3; 244 *args_used = 2;
250 *store = tmp_store; 245 *store = tmp_store;
251 return 0; 246 return 0;
252 247
253bad_ctr: 248bad:
254 dm_put_device(ti, tmp_store->cow);
255bad_cow:
256 put_type(type); 249 put_type(type);
257bad_type: 250bad_type:
258 kfree(tmp_store); 251 kfree(tmp_store);
@@ -263,7 +256,6 @@ EXPORT_SYMBOL(dm_exception_store_create);
263void dm_exception_store_destroy(struct dm_exception_store *store) 256void dm_exception_store_destroy(struct dm_exception_store *store)
264{ 257{
265 store->type->dtr(store); 258 store->type->dtr(store);
266 dm_put_device(store->ti, store->cow);
267 put_type(store->type); 259 put_type(store->type);
268 kfree(store); 260 kfree(store);
269} 261}