diff options
Diffstat (limited to 'drivers/md/dm-snap.c')
-rw-r--r-- | drivers/md/dm-snap.c | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 6c96db26b87c..65ff82ff124e 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/blkdev.h> | 9 | #include <linux/blkdev.h> |
10 | #include <linux/ctype.h> | 10 | #include <linux/ctype.h> |
11 | #include <linux/device-mapper.h> | 11 | #include <linux/device-mapper.h> |
12 | #include <linux/delay.h> | ||
12 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
13 | #include <linux/init.h> | 14 | #include <linux/init.h> |
14 | #include <linux/kdev_t.h> | 15 | #include <linux/kdev_t.h> |
@@ -20,6 +21,7 @@ | |||
20 | #include <linux/log2.h> | 21 | #include <linux/log2.h> |
21 | #include <linux/dm-kcopyd.h> | 22 | #include <linux/dm-kcopyd.h> |
22 | 23 | ||
24 | #include "dm-exception-store.h" | ||
23 | #include "dm-snap.h" | 25 | #include "dm-snap.h" |
24 | #include "dm-bio-list.h" | 26 | #include "dm-bio-list.h" |
25 | 27 | ||
@@ -428,8 +430,13 @@ out: | |||
428 | list_add(&new_e->hash_list, e ? &e->hash_list : l); | 430 | list_add(&new_e->hash_list, e ? &e->hash_list : l); |
429 | } | 431 | } |
430 | 432 | ||
431 | int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new) | 433 | /* |
434 | * Callback used by the exception stores to load exceptions when | ||
435 | * initialising. | ||
436 | */ | ||
437 | static int dm_add_exception(void *context, chunk_t old, chunk_t new) | ||
432 | { | 438 | { |
439 | struct dm_snapshot *s = context; | ||
433 | struct dm_snap_exception *e; | 440 | struct dm_snap_exception *e; |
434 | 441 | ||
435 | e = alloc_exception(); | 442 | e = alloc_exception(); |
@@ -658,7 +665,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
658 | spin_lock_init(&s->tracked_chunk_lock); | 665 | spin_lock_init(&s->tracked_chunk_lock); |
659 | 666 | ||
660 | /* Metadata must only be loaded into one table at once */ | 667 | /* Metadata must only be loaded into one table at once */ |
661 | r = s->store.read_metadata(&s->store); | 668 | r = s->store.read_metadata(&s->store, dm_add_exception, (void *)s); |
662 | if (r < 0) { | 669 | if (r < 0) { |
663 | ti->error = "Failed to read snapshot metadata"; | 670 | ti->error = "Failed to read snapshot metadata"; |
664 | goto bad_load_and_register; | 671 | goto bad_load_and_register; |
@@ -735,7 +742,7 @@ static void snapshot_dtr(struct dm_target *ti) | |||
735 | unregister_snapshot(s); | 742 | unregister_snapshot(s); |
736 | 743 | ||
737 | while (atomic_read(&s->pending_exceptions_count)) | 744 | while (atomic_read(&s->pending_exceptions_count)) |
738 | yield(); | 745 | msleep(1); |
739 | /* | 746 | /* |
740 | * Ensure instructions in mempool_destroy aren't reordered | 747 | * Ensure instructions in mempool_destroy aren't reordered |
741 | * before atomic_read. | 748 | * before atomic_read. |
@@ -888,10 +895,10 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) | |||
888 | 895 | ||
889 | /* | 896 | /* |
890 | * Check for conflicting reads. This is extremely improbable, | 897 | * Check for conflicting reads. This is extremely improbable, |
891 | * so yield() is sufficient and there is no need for a wait queue. | 898 | * so msleep(1) is sufficient and there is no need for a wait queue. |
892 | */ | 899 | */ |
893 | while (__chunk_is_tracked(s, pe->e.old_chunk)) | 900 | while (__chunk_is_tracked(s, pe->e.old_chunk)) |
894 | yield(); | 901 | msleep(1); |
895 | 902 | ||
896 | /* | 903 | /* |
897 | * Add a proper exception, and remove the | 904 | * Add a proper exception, and remove the |
@@ -1404,6 +1411,12 @@ static int __init dm_snapshot_init(void) | |||
1404 | { | 1411 | { |
1405 | int r; | 1412 | int r; |
1406 | 1413 | ||
1414 | r = dm_exception_store_init(); | ||
1415 | if (r) { | ||
1416 | DMERR("Failed to initialize exception stores"); | ||
1417 | return r; | ||
1418 | } | ||
1419 | |||
1407 | r = dm_register_target(&snapshot_target); | 1420 | r = dm_register_target(&snapshot_target); |
1408 | if (r) { | 1421 | if (r) { |
1409 | DMERR("snapshot target register failed %d", r); | 1422 | DMERR("snapshot target register failed %d", r); |
@@ -1452,39 +1465,34 @@ static int __init dm_snapshot_init(void) | |||
1452 | 1465 | ||
1453 | return 0; | 1466 | return 0; |
1454 | 1467 | ||
1455 | bad_pending_pool: | 1468 | bad_pending_pool: |
1456 | kmem_cache_destroy(tracked_chunk_cache); | 1469 | kmem_cache_destroy(tracked_chunk_cache); |
1457 | bad5: | 1470 | bad5: |
1458 | kmem_cache_destroy(pending_cache); | 1471 | kmem_cache_destroy(pending_cache); |
1459 | bad4: | 1472 | bad4: |
1460 | kmem_cache_destroy(exception_cache); | 1473 | kmem_cache_destroy(exception_cache); |
1461 | bad3: | 1474 | bad3: |
1462 | exit_origin_hash(); | 1475 | exit_origin_hash(); |
1463 | bad2: | 1476 | bad2: |
1464 | dm_unregister_target(&origin_target); | 1477 | dm_unregister_target(&origin_target); |
1465 | bad1: | 1478 | bad1: |
1466 | dm_unregister_target(&snapshot_target); | 1479 | dm_unregister_target(&snapshot_target); |
1467 | return r; | 1480 | return r; |
1468 | } | 1481 | } |
1469 | 1482 | ||
1470 | static void __exit dm_snapshot_exit(void) | 1483 | static void __exit dm_snapshot_exit(void) |
1471 | { | 1484 | { |
1472 | int r; | ||
1473 | |||
1474 | destroy_workqueue(ksnapd); | 1485 | destroy_workqueue(ksnapd); |
1475 | 1486 | ||
1476 | r = dm_unregister_target(&snapshot_target); | 1487 | dm_unregister_target(&snapshot_target); |
1477 | if (r) | 1488 | dm_unregister_target(&origin_target); |
1478 | DMERR("snapshot unregister failed %d", r); | ||
1479 | |||
1480 | r = dm_unregister_target(&origin_target); | ||
1481 | if (r) | ||
1482 | DMERR("origin unregister failed %d", r); | ||
1483 | 1489 | ||
1484 | exit_origin_hash(); | 1490 | exit_origin_hash(); |
1485 | kmem_cache_destroy(pending_cache); | 1491 | kmem_cache_destroy(pending_cache); |
1486 | kmem_cache_destroy(exception_cache); | 1492 | kmem_cache_destroy(exception_cache); |
1487 | kmem_cache_destroy(tracked_chunk_cache); | 1493 | kmem_cache_destroy(tracked_chunk_cache); |
1494 | |||
1495 | dm_exception_store_exit(); | ||
1488 | } | 1496 | } |
1489 | 1497 | ||
1490 | /* Module hooks */ | 1498 | /* Module hooks */ |