aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-snap.c53
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
28static 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
1751static 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
1746static int __init dm_snapshot_init(void) 1766static 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
1804bad_pending_pool: 1830bad_pending_pool:
1805 kmem_cache_destroy(tracked_chunk_cache); 1831 kmem_cache_destroy(tracked_chunk_cache);
1806bad5: 1832bad_tracked_chunk_cache:
1807 kmem_cache_destroy(pending_cache); 1833 kmem_cache_destroy(pending_cache);
1808bad4: 1834bad_pending_cache:
1809 kmem_cache_destroy(exception_cache); 1835 kmem_cache_destroy(exception_cache);
1810bad3: 1836bad_exception_cache:
1811 exit_origin_hash(); 1837 exit_origin_hash();
1812bad2: 1838bad_origin_hash:
1839 dm_unregister_target(&merge_target);
1840bad_register_merge_target:
1813 dm_unregister_target(&origin_target); 1841 dm_unregister_target(&origin_target);
1814bad1: 1842bad_register_origin_target:
1815 dm_unregister_target(&snapshot_target); 1843 dm_unregister_target(&snapshot_target);
1816
1817bad_register_snapshot_target: 1844bad_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);