aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-snap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-snap.c')
-rw-r--r--drivers/md/dm-snap.c82
1 files changed, 11 insertions, 71 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 5974d3094d97..9ecff5f3023a 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -19,7 +19,6 @@
19#include <linux/vmalloc.h> 19#include <linux/vmalloc.h>
20#include <linux/log2.h> 20#include <linux/log2.h>
21#include <linux/dm-kcopyd.h> 21#include <linux/dm-kcopyd.h>
22#include <linux/workqueue.h>
23 22
24#include "dm-exception-store.h" 23#include "dm-exception-store.h"
25 24
@@ -41,11 +40,6 @@ static const char dm_snapshot_merge_target_name[] = "snapshot-merge";
41#define SNAPSHOT_COPY_PRIORITY 2 40#define SNAPSHOT_COPY_PRIORITY 2
42 41
43/* 42/*
44 * Reserve 1MB for each snapshot initially (with minimum of 1 page).
45 */
46#define SNAPSHOT_PAGES (((1UL << 20) >> PAGE_SHIFT) ? : 1)
47
48/*
49 * The size of the mempool used to track chunks in use. 43 * The size of the mempool used to track chunks in use.
50 */ 44 */
51#define MIN_IOS 256 45#define MIN_IOS 256
@@ -80,9 +74,6 @@ struct dm_snapshot {
80 /* Origin writes don't trigger exceptions until this is set */ 74 /* Origin writes don't trigger exceptions until this is set */
81 int active; 75 int active;
82 76
83 /* Whether or not owning mapped_device is suspended */
84 int suspended;
85
86 atomic_t pending_exceptions_count; 77 atomic_t pending_exceptions_count;
87 78
88 mempool_t *pending_pool; 79 mempool_t *pending_pool;
@@ -106,10 +97,6 @@ struct dm_snapshot {
106 97
107 struct dm_kcopyd_client *kcopyd_client; 98 struct dm_kcopyd_client *kcopyd_client;
108 99
109 /* Queue of snapshot writes for ksnapd to flush */
110 struct bio_list queued_bios;
111 struct work_struct queued_bios_work;
112
113 /* Wait for events based on state_bits */ 100 /* Wait for events based on state_bits */
114 unsigned long state_bits; 101 unsigned long state_bits;
115 102
@@ -160,9 +147,6 @@ struct dm_dev *dm_snap_cow(struct dm_snapshot *s)
160} 147}
161EXPORT_SYMBOL(dm_snap_cow); 148EXPORT_SYMBOL(dm_snap_cow);
162 149
163static struct workqueue_struct *ksnapd;
164static void flush_queued_bios(struct work_struct *work);
165
166static sector_t chunk_to_sector(struct dm_exception_store *store, 150static sector_t chunk_to_sector(struct dm_exception_store *store,
167 chunk_t chunk) 151 chunk_t chunk)
168{ 152{
@@ -706,8 +690,6 @@ static int dm_add_exception(void *context, chunk_t old, chunk_t new)
706 return 0; 690 return 0;
707} 691}
708 692
709#define min_not_zero(l, r) (((l) == 0) ? (r) : (((r) == 0) ? (l) : min(l, r)))
710
711/* 693/*
712 * Return a minimum chunk size of all snapshots that have the specified origin. 694 * Return a minimum chunk size of all snapshots that have the specified origin.
713 * Return zero if the origin has no snapshots. 695 * Return zero if the origin has no snapshots.
@@ -1093,7 +1075,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1093 argv++; 1075 argv++;
1094 argc--; 1076 argc--;
1095 1077
1096 r = dm_get_device(ti, cow_path, FMODE_READ | FMODE_WRITE, &s->cow); 1078 r = dm_get_device(ti, cow_path, dm_table_get_mode(ti->table), &s->cow);
1097 if (r) { 1079 if (r) {
1098 ti->error = "Cannot get COW device"; 1080 ti->error = "Cannot get COW device";
1099 goto bad_cow; 1081 goto bad_cow;
@@ -1112,7 +1094,6 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1112 s->ti = ti; 1094 s->ti = ti;
1113 s->valid = 1; 1095 s->valid = 1;
1114 s->active = 0; 1096 s->active = 0;
1115 s->suspended = 0;
1116 atomic_set(&s->pending_exceptions_count, 0); 1097 atomic_set(&s->pending_exceptions_count, 0);
1117 init_rwsem(&s->lock); 1098 init_rwsem(&s->lock);
1118 INIT_LIST_HEAD(&s->list); 1099 INIT_LIST_HEAD(&s->list);
@@ -1130,8 +1111,9 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1130 goto bad_hash_tables; 1111 goto bad_hash_tables;
1131 } 1112 }
1132 1113
1133 r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client); 1114 s->kcopyd_client = dm_kcopyd_client_create();
1134 if (r) { 1115 if (IS_ERR(s->kcopyd_client)) {
1116 r = PTR_ERR(s->kcopyd_client);
1135 ti->error = "Could not create kcopyd client"; 1117 ti->error = "Could not create kcopyd client";
1136 goto bad_kcopyd; 1118 goto bad_kcopyd;
1137 } 1119 }
@@ -1155,9 +1137,6 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1155 1137
1156 spin_lock_init(&s->tracked_chunk_lock); 1138 spin_lock_init(&s->tracked_chunk_lock);
1157 1139
1158 bio_list_init(&s->queued_bios);
1159 INIT_WORK(&s->queued_bios_work, flush_queued_bios);
1160
1161 ti->private = s; 1140 ti->private = s;
1162 ti->num_flush_requests = num_flush_requests; 1141 ti->num_flush_requests = num_flush_requests;
1163 1142
@@ -1281,8 +1260,6 @@ static void snapshot_dtr(struct dm_target *ti)
1281 struct dm_snapshot *s = ti->private; 1260 struct dm_snapshot *s = ti->private;
1282 struct dm_snapshot *snap_src = NULL, *snap_dest = NULL; 1261 struct dm_snapshot *snap_src = NULL, *snap_dest = NULL;
1283 1262
1284 flush_workqueue(ksnapd);
1285
1286 down_read(&_origins_lock); 1263 down_read(&_origins_lock);
1287 /* Check whether exception handover must be cancelled */ 1264 /* Check whether exception handover must be cancelled */
1288 (void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL); 1265 (void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL);
@@ -1344,20 +1321,6 @@ static void flush_bios(struct bio *bio)
1344 } 1321 }
1345} 1322}
1346 1323
1347static void flush_queued_bios(struct work_struct *work)
1348{
1349 struct dm_snapshot *s =
1350 container_of(work, struct dm_snapshot, queued_bios_work);
1351 struct bio *queued_bios;
1352 unsigned long flags;
1353
1354 spin_lock_irqsave(&s->pe_lock, flags);
1355 queued_bios = bio_list_get(&s->queued_bios);
1356 spin_unlock_irqrestore(&s->pe_lock, flags);
1357
1358 flush_bios(queued_bios);
1359}
1360
1361static int do_origin(struct dm_dev *origin, struct bio *bio); 1324static int do_origin(struct dm_dev *origin, struct bio *bio);
1362 1325
1363/* 1326/*
@@ -1587,7 +1550,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
1587 chunk_t chunk; 1550 chunk_t chunk;
1588 struct dm_snap_pending_exception *pe = NULL; 1551 struct dm_snap_pending_exception *pe = NULL;
1589 1552
1590 if (unlikely(bio_empty_barrier(bio))) { 1553 if (bio->bi_rw & REQ_FLUSH) {
1591 bio->bi_bdev = s->cow->bdev; 1554 bio->bi_bdev = s->cow->bdev;
1592 return DM_MAPIO_REMAPPED; 1555 return DM_MAPIO_REMAPPED;
1593 } 1556 }
@@ -1691,7 +1654,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio,
1691 int r = DM_MAPIO_REMAPPED; 1654 int r = DM_MAPIO_REMAPPED;
1692 chunk_t chunk; 1655 chunk_t chunk;
1693 1656
1694 if (unlikely(bio_empty_barrier(bio))) { 1657 if (bio->bi_rw & REQ_FLUSH) {
1695 if (!map_context->target_request_nr) 1658 if (!map_context->target_request_nr)
1696 bio->bi_bdev = s->origin->bdev; 1659 bio->bi_bdev = s->origin->bdev;
1697 else 1660 else
@@ -1762,15 +1725,6 @@ static void snapshot_merge_presuspend(struct dm_target *ti)
1762 stop_merge(s); 1725 stop_merge(s);
1763} 1726}
1764 1727
1765static void snapshot_postsuspend(struct dm_target *ti)
1766{
1767 struct dm_snapshot *s = ti->private;
1768
1769 down_write(&s->lock);
1770 s->suspended = 1;
1771 up_write(&s->lock);
1772}
1773
1774static int snapshot_preresume(struct dm_target *ti) 1728static int snapshot_preresume(struct dm_target *ti)
1775{ 1729{
1776 int r = 0; 1730 int r = 0;
@@ -1785,7 +1739,7 @@ static int snapshot_preresume(struct dm_target *ti)
1785 DMERR("Unable to resume snapshot source until " 1739 DMERR("Unable to resume snapshot source until "
1786 "handover completes."); 1740 "handover completes.");
1787 r = -EINVAL; 1741 r = -EINVAL;
1788 } else if (!snap_src->suspended) { 1742 } else if (!dm_suspended(snap_src->ti)) {
1789 DMERR("Unable to perform snapshot handover until " 1743 DMERR("Unable to perform snapshot handover until "
1790 "source is suspended."); 1744 "source is suspended.");
1791 r = -EINVAL; 1745 r = -EINVAL;
@@ -1818,7 +1772,6 @@ static void snapshot_resume(struct dm_target *ti)
1818 1772
1819 down_write(&s->lock); 1773 down_write(&s->lock);
1820 s->active = 1; 1774 s->active = 1;
1821 s->suspended = 0;
1822 up_write(&s->lock); 1775 up_write(&s->lock);
1823} 1776}
1824 1777
@@ -2135,7 +2088,7 @@ static int origin_map(struct dm_target *ti, struct bio *bio,
2135 struct dm_dev *dev = ti->private; 2088 struct dm_dev *dev = ti->private;
2136 bio->bi_bdev = dev->bdev; 2089 bio->bi_bdev = dev->bdev;
2137 2090
2138 if (unlikely(bio_empty_barrier(bio))) 2091 if (bio->bi_rw & REQ_FLUSH)
2139 return DM_MAPIO_REMAPPED; 2092 return DM_MAPIO_REMAPPED;
2140 2093
2141 /* Only tell snapshots if this is a write */ 2094 /* Only tell snapshots if this is a write */
@@ -2196,7 +2149,7 @@ static int origin_iterate_devices(struct dm_target *ti,
2196 2149
2197static struct target_type origin_target = { 2150static struct target_type origin_target = {
2198 .name = "snapshot-origin", 2151 .name = "snapshot-origin",
2199 .version = {1, 7, 0}, 2152 .version = {1, 7, 1},
2200 .module = THIS_MODULE, 2153 .module = THIS_MODULE,
2201 .ctr = origin_ctr, 2154 .ctr = origin_ctr,
2202 .dtr = origin_dtr, 2155 .dtr = origin_dtr,
@@ -2209,13 +2162,12 @@ static struct target_type origin_target = {
2209 2162
2210static struct target_type snapshot_target = { 2163static struct target_type snapshot_target = {
2211 .name = "snapshot", 2164 .name = "snapshot",
2212 .version = {1, 9, 0}, 2165 .version = {1, 10, 0},
2213 .module = THIS_MODULE, 2166 .module = THIS_MODULE,
2214 .ctr = snapshot_ctr, 2167 .ctr = snapshot_ctr,
2215 .dtr = snapshot_dtr, 2168 .dtr = snapshot_dtr,
2216 .map = snapshot_map, 2169 .map = snapshot_map,
2217 .end_io = snapshot_end_io, 2170 .end_io = snapshot_end_io,
2218 .postsuspend = snapshot_postsuspend,
2219 .preresume = snapshot_preresume, 2171 .preresume = snapshot_preresume,
2220 .resume = snapshot_resume, 2172 .resume = snapshot_resume,
2221 .status = snapshot_status, 2173 .status = snapshot_status,
@@ -2224,14 +2176,13 @@ static struct target_type snapshot_target = {
2224 2176
2225static struct target_type merge_target = { 2177static struct target_type merge_target = {
2226 .name = dm_snapshot_merge_target_name, 2178 .name = dm_snapshot_merge_target_name,
2227 .version = {1, 0, 0}, 2179 .version = {1, 1, 0},
2228 .module = THIS_MODULE, 2180 .module = THIS_MODULE,
2229 .ctr = snapshot_ctr, 2181 .ctr = snapshot_ctr,
2230 .dtr = snapshot_dtr, 2182 .dtr = snapshot_dtr,
2231 .map = snapshot_merge_map, 2183 .map = snapshot_merge_map,
2232 .end_io = snapshot_end_io, 2184 .end_io = snapshot_end_io,
2233 .presuspend = snapshot_merge_presuspend, 2185 .presuspend = snapshot_merge_presuspend,
2234 .postsuspend = snapshot_postsuspend,
2235 .preresume = snapshot_preresume, 2186 .preresume = snapshot_preresume,
2236 .resume = snapshot_merge_resume, 2187 .resume = snapshot_merge_resume,
2237 .status = snapshot_status, 2188 .status = snapshot_status,
@@ -2293,17 +2244,8 @@ static int __init dm_snapshot_init(void)
2293 goto bad_tracked_chunk_cache; 2244 goto bad_tracked_chunk_cache;
2294 } 2245 }
2295 2246
2296 ksnapd = create_singlethread_workqueue("ksnapd");
2297 if (!ksnapd) {
2298 DMERR("Failed to create ksnapd workqueue.");
2299 r = -ENOMEM;
2300 goto bad_pending_pool;
2301 }
2302
2303 return 0; 2247 return 0;
2304 2248
2305bad_pending_pool:
2306 kmem_cache_destroy(tracked_chunk_cache);
2307bad_tracked_chunk_cache: 2249bad_tracked_chunk_cache:
2308 kmem_cache_destroy(pending_cache); 2250 kmem_cache_destroy(pending_cache);
2309bad_pending_cache: 2251bad_pending_cache:
@@ -2324,8 +2266,6 @@ bad_register_snapshot_target:
2324 2266
2325static void __exit dm_snapshot_exit(void) 2267static void __exit dm_snapshot_exit(void)
2326{ 2268{
2327 destroy_workqueue(ksnapd);
2328
2329 dm_unregister_target(&snapshot_target); 2269 dm_unregister_target(&snapshot_target);
2330 dm_unregister_target(&origin_target); 2270 dm_unregister_target(&origin_target);
2331 dm_unregister_target(&merge_target); 2271 dm_unregister_target(&merge_target);