diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-snap.c | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 288994ee7142..446827f98236 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -25,6 +25,11 @@ | |||
25 | 25 | ||
26 | #define DM_MSG_PREFIX "snapshots" | 26 | #define DM_MSG_PREFIX "snapshots" |
27 | 27 | ||
28 | static const char dm_snapshot_merge_target_name[] = "snapshot-merge"; | ||
29 | |||
30 | #define dm_target_is_snapshot_merge(ti) \ | ||
31 | ((ti)->type->name == dm_snapshot_merge_target_name) | ||
32 | |||
28 | /* | 33 | /* |
29 | * The percentage increment we will wake up users at | 34 | * The percentage increment we will wake up users at |
30 | */ | 35 | */ |
@@ -1743,6 +1748,21 @@ static struct target_type snapshot_target = { | |||
1743 | .iterate_devices = snapshot_iterate_devices, | 1748 | .iterate_devices = snapshot_iterate_devices, |
1744 | }; | 1749 | }; |
1745 | 1750 | ||
1751 | static struct target_type merge_target = { | ||
1752 | .name = dm_snapshot_merge_target_name, | ||
1753 | .version = {1, 0, 0}, | ||
1754 | .module = THIS_MODULE, | ||
1755 | .ctr = snapshot_ctr, | ||
1756 | .dtr = snapshot_dtr, | ||
1757 | .map = snapshot_map, | ||
1758 | .end_io = snapshot_end_io, | ||
1759 | .postsuspend = snapshot_postsuspend, | ||
1760 | .preresume = snapshot_preresume, | ||
1761 | .resume = snapshot_resume, | ||
1762 | .status = snapshot_status, | ||
1763 | .iterate_devices = snapshot_iterate_devices, | ||
1764 | }; | ||
1765 | |||
1746 | static int __init dm_snapshot_init(void) | 1766 | static int __init dm_snapshot_init(void) |
1747 | { | 1767 | { |
1748 | int r; | 1768 | int r; |
@@ -1754,7 +1774,7 @@ static int __init dm_snapshot_init(void) | |||
1754 | } | 1774 | } |
1755 | 1775 | ||
1756 | r = dm_register_target(&snapshot_target); | 1776 | r = dm_register_target(&snapshot_target); |
1757 | if (r) { | 1777 | if (r < 0) { |
1758 | DMERR("snapshot target register failed %d", r); | 1778 | DMERR("snapshot target register failed %d", r); |
1759 | goto bad_register_snapshot_target; | 1779 | goto bad_register_snapshot_target; |
1760 | } | 1780 | } |
@@ -1762,34 +1782,40 @@ static int __init dm_snapshot_init(void) | |||
1762 | r = dm_register_target(&origin_target); | 1782 | r = dm_register_target(&origin_target); |
1763 | if (r < 0) { | 1783 | if (r < 0) { |
1764 | DMERR("Origin target register failed %d", r); | 1784 | DMERR("Origin target register failed %d", r); |
1765 | goto bad1; | 1785 | goto bad_register_origin_target; |
1786 | } | ||
1787 | |||
1788 | r = dm_register_target(&merge_target); | ||
1789 | if (r < 0) { | ||
1790 | DMERR("Merge target register failed %d", r); | ||
1791 | goto bad_register_merge_target; | ||
1766 | } | 1792 | } |
1767 | 1793 | ||
1768 | r = init_origin_hash(); | 1794 | r = init_origin_hash(); |
1769 | if (r) { | 1795 | if (r) { |
1770 | DMERR("init_origin_hash failed."); | 1796 | DMERR("init_origin_hash failed."); |
1771 | goto bad2; | 1797 | goto bad_origin_hash; |
1772 | } | 1798 | } |
1773 | 1799 | ||
1774 | exception_cache = KMEM_CACHE(dm_exception, 0); | 1800 | exception_cache = KMEM_CACHE(dm_exception, 0); |
1775 | if (!exception_cache) { | 1801 | if (!exception_cache) { |
1776 | DMERR("Couldn't create exception cache."); | 1802 | DMERR("Couldn't create exception cache."); |
1777 | r = -ENOMEM; | 1803 | r = -ENOMEM; |
1778 | goto bad3; | 1804 | goto bad_exception_cache; |
1779 | } | 1805 | } |
1780 | 1806 | ||
1781 | pending_cache = KMEM_CACHE(dm_snap_pending_exception, 0); | 1807 | pending_cache = KMEM_CACHE(dm_snap_pending_exception, 0); |
1782 | if (!pending_cache) { | 1808 | if (!pending_cache) { |
1783 | DMERR("Couldn't create pending cache."); | 1809 | DMERR("Couldn't create pending cache."); |
1784 | r = -ENOMEM; | 1810 | r = -ENOMEM; |
1785 | goto bad4; | 1811 | goto bad_pending_cache; |
1786 | } | 1812 | } |
1787 | 1813 | ||
1788 | tracked_chunk_cache = KMEM_CACHE(dm_snap_tracked_chunk, 0); | 1814 | tracked_chunk_cache = KMEM_CACHE(dm_snap_tracked_chunk, 0); |
1789 | if (!tracked_chunk_cache) { | 1815 | if (!tracked_chunk_cache) { |
1790 | DMERR("Couldn't create cache to track chunks in use."); | 1816 | DMERR("Couldn't create cache to track chunks in use."); |
1791 | r = -ENOMEM; | 1817 | r = -ENOMEM; |
1792 | goto bad5; | 1818 | goto bad_tracked_chunk_cache; |
1793 | } | 1819 | } |
1794 | 1820 | ||
1795 | ksnapd = create_singlethread_workqueue("ksnapd"); | 1821 | ksnapd = create_singlethread_workqueue("ksnapd"); |
@@ -1803,19 +1829,21 @@ static int __init dm_snapshot_init(void) | |||
1803 | 1829 | ||
1804 | bad_pending_pool: | 1830 | bad_pending_pool: |
1805 | kmem_cache_destroy(tracked_chunk_cache); | 1831 | kmem_cache_destroy(tracked_chunk_cache); |
1806 | bad5: | 1832 | bad_tracked_chunk_cache: |
1807 | kmem_cache_destroy(pending_cache); | 1833 | kmem_cache_destroy(pending_cache); |
1808 | bad4: | 1834 | bad_pending_cache: |
1809 | kmem_cache_destroy(exception_cache); | 1835 | kmem_cache_destroy(exception_cache); |
1810 | bad3: | 1836 | bad_exception_cache: |
1811 | exit_origin_hash(); | 1837 | exit_origin_hash(); |
1812 | bad2: | 1838 | bad_origin_hash: |
1839 | dm_unregister_target(&merge_target); | ||
1840 | bad_register_merge_target: | ||
1813 | dm_unregister_target(&origin_target); | 1841 | dm_unregister_target(&origin_target); |
1814 | bad1: | 1842 | bad_register_origin_target: |
1815 | dm_unregister_target(&snapshot_target); | 1843 | dm_unregister_target(&snapshot_target); |
1816 | |||
1817 | bad_register_snapshot_target: | 1844 | bad_register_snapshot_target: |
1818 | dm_exception_store_exit(); | 1845 | dm_exception_store_exit(); |
1846 | |||
1819 | return r; | 1847 | return r; |
1820 | } | 1848 | } |
1821 | 1849 | ||
@@ -1825,6 +1853,7 @@ static void __exit dm_snapshot_exit(void) | |||
1825 | 1853 | ||
1826 | dm_unregister_target(&snapshot_target); | 1854 | dm_unregister_target(&snapshot_target); |
1827 | dm_unregister_target(&origin_target); | 1855 | dm_unregister_target(&origin_target); |
1856 | dm_unregister_target(&merge_target); | ||
1828 | 1857 | ||
1829 | exit_origin_hash(); | 1858 | exit_origin_hash(); |
1830 | kmem_cache_destroy(pending_cache); | 1859 | kmem_cache_destroy(pending_cache); |