diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2009-12-10 18:52:30 -0500 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2009-12-10 18:52:30 -0500 |
commit | d698aa4500aa3ca9559142060caf0f79da998744 (patch) | |
tree | 175577ce2c8ae0918e6f38a2a27ad2b124bb2466 /drivers | |
parent | 4454a6216f75a9ef8c4bd0a65e34b101f725ef1e (diff) |
dm snapshot: add merge target
The snapshot-merge target allows a snapshot to be merged back into the
snapshot's origin device.
One anticipated use of snapshot merging is the rollback of filesystems
to back out problematic system upgrades.
This patch adds snapshot-merge target management to both
dm_snapshot_init() and dm_snapshot_exit(). As an initial place-holder,
snapshot-merge is identical to the snapshot target. Documentation is
provided.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers')
-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); |