Blame view

drivers/md/dm-snap.c 58.1 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
  /*
   * dm-snapshot.c
   *
   * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
   *
   * This file is released under the GPL.
   */
  
  #include <linux/blkdev.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
  #include <linux/device-mapper.h>
90fa1527b   Mikulas Patocka   dm snapshot: chan...
11
  #include <linux/delay.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
14
15
16
17
18
19
  #include <linux/fs.h>
  #include <linux/init.h>
  #include <linux/kdev_t.h>
  #include <linux/list.h>
  #include <linux/mempool.h>
  #include <linux/module.h>
  #include <linux/slab.h>
  #include <linux/vmalloc.h>
6f3c3f0af   vignesh babu   dm: use is_power_...
20
  #include <linux/log2.h>
a765e20ee   Alasdair G Kergon   dm: move include ...
21
  #include <linux/dm-kcopyd.h>
8189ee479   Nikos Tsironis   dm snapshot: Fix ...
22
  #include <linux/semaphore.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23

b735fede8   Mikulas Patocka   dm snapshot: susp...
24
  #include "dm.h"
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
25
  #include "dm-exception-store.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26

72d948616   Alasdair G Kergon   [PATCH] dm: impro...
27
  #define DM_MSG_PREFIX "snapshots"
d698aa450   Mikulas Patocka   dm snapshot: add ...
28
29
30
31
  static const char dm_snapshot_merge_target_name[] = "snapshot-merge";
  
  #define dm_target_is_snapshot_merge(ti) \
  	((ti)->type->name == dm_snapshot_merge_target_name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
  /*
cd45daffd   Mikulas Patocka   dm snapshot: trac...
33
34
35
   * The size of the mempool used to track chunks in use.
   */
  #define MIN_IOS 256
ccc45ea8a   Jonathan Brassow   dm snapshot: remo...
36
37
38
  #define DM_TRACKED_CHUNK_HASH_SIZE	16
  #define DM_TRACKED_CHUNK_HASH(x)	((unsigned long)(x) & \
  					 (DM_TRACKED_CHUNK_HASH_SIZE - 1))
191437a53   Jon Brassow   dm snapshot: rena...
39
  struct dm_exception_table {
ccc45ea8a   Jonathan Brassow   dm snapshot: remo...
40
41
42
43
44
45
46
47
48
  	uint32_t hash_mask;
  	unsigned hash_shift;
  	struct list_head *table;
  };
  
  struct dm_snapshot {
  	struct rw_semaphore lock;
  
  	struct dm_dev *origin;
fc56f6fbc   Mike Snitzer   dm snapshot: move...
49
50
51
  	struct dm_dev *cow;
  
  	struct dm_target *ti;
ccc45ea8a   Jonathan Brassow   dm snapshot: remo...
52
53
54
  
  	/* List of snapshots per Origin */
  	struct list_head list;
d8ddb1cff   Mike Snitzer   dm snapshot: repo...
55
56
57
58
  	/*
  	 * You can't use a snapshot if this is 0 (e.g. if full).
  	 * A snapshot-merge target never clears this.
  	 */
ccc45ea8a   Jonathan Brassow   dm snapshot: remo...
59
  	int valid;
76c44f6d8   Mikulas Patocka   dm snapshot: don'...
60
61
62
63
64
65
  	/*
  	 * The snapshot overflowed because of a write to the snapshot device.
  	 * We don't have to invalidate the snapshot in this case, but we need
  	 * to prevent further writes.
  	 */
  	int snapshot_overflowed;
ccc45ea8a   Jonathan Brassow   dm snapshot: remo...
66
67
  	/* Origin writes don't trigger exceptions until this is set */
  	int active;
ccc45ea8a   Jonathan Brassow   dm snapshot: remo...
68
  	atomic_t pending_exceptions_count;
230c83afd   Mikulas Patocka   dm snapshot: avoi...
69
70
71
72
73
74
75
76
77
78
79
  	/* Protected by "lock" */
  	sector_t exception_start_sequence;
  
  	/* Protected by kcopyd single-threaded callback */
  	sector_t exception_complete_sequence;
  
  	/*
  	 * A list of pending exceptions that completed out of order.
  	 * Protected by kcopyd single-threaded callback.
  	 */
  	struct list_head out_of_order_list;
924e600d4   Mike Snitzer   dm: eliminate som...
80
  	mempool_t *pending_pool;
191437a53   Jon Brassow   dm snapshot: rena...
81
82
  	struct dm_exception_table pending;
  	struct dm_exception_table complete;
ccc45ea8a   Jonathan Brassow   dm snapshot: remo...
83
84
85
86
87
88
  
  	/*
  	 * pe_lock protects all pending_exception operations and access
  	 * as well as the snapshot_bios list.
  	 */
  	spinlock_t pe_lock;
924e600d4   Mike Snitzer   dm: eliminate som...
89
90
  	/* Chunks with outstanding reads */
  	spinlock_t tracked_chunk_lock;
924e600d4   Mike Snitzer   dm: eliminate som...
91
  	struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
ccc45ea8a   Jonathan Brassow   dm snapshot: remo...
92
93
  	/* The on disk metadata handler */
  	struct dm_exception_store *store;
8189ee479   Nikos Tsironis   dm snapshot: Fix ...
94
95
  	/* Maximum number of in-flight COW jobs. */
  	struct semaphore cow_count;
ccc45ea8a   Jonathan Brassow   dm snapshot: remo...
96
  	struct dm_kcopyd_client *kcopyd_client;
924e600d4   Mike Snitzer   dm: eliminate som...
97
98
99
100
101
102
  	/* Wait for events based on state_bits */
  	unsigned long state_bits;
  
  	/* Range of chunks currently being merged. */
  	chunk_t first_merging_chunk;
  	int num_merging_chunks;
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
103

d8ddb1cff   Mike Snitzer   dm snapshot: repo...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
  	/*
  	 * The merge operation failed if this flag is set.
  	 * Failure modes are handled as follows:
  	 * - I/O error reading the header
  	 *   	=> don't load the target; abort.
  	 * - Header does not have "valid" flag set
  	 *   	=> use the origin; forget about the snapshot.
  	 * - I/O error when reading exceptions
  	 *   	=> don't load the target; abort.
  	 *         (We can't use the intermediate origin state.)
  	 * - I/O error while merging
  	 *	=> stop merging; set merge_failed; process I/O normally.
  	 */
  	int merge_failed;
9fe862548   Mikulas Patocka   dm snapshot: queu...
118
119
120
121
122
  	/*
  	 * Incoming bios that overlap with chunks being merged must wait
  	 * for them to be committed.
  	 */
  	struct bio_list bios_queued_during_merge;
ccc45ea8a   Jonathan Brassow   dm snapshot: remo...
123
  };
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
124
125
126
127
128
129
130
131
  /*
   * state_bits:
   *   RUNNING_MERGE  - Merge operation is in progress.
   *   SHUTDOWN_MERGE - Set to signal that merge needs to be stopped;
   *                    cleared afterwards.
   */
  #define RUNNING_MERGE          0
  #define SHUTDOWN_MERGE         1
8189ee479   Nikos Tsironis   dm snapshot: Fix ...
132
133
134
135
136
137
138
139
140
141
142
143
  /*
   * Maximum number of chunks being copied on write.
   *
   * The value was decided experimentally as a trade-off between memory
   * consumption, stalling the kernel's workqueues and maintaining a high enough
   * throughput.
   */
  #define DEFAULT_COW_THRESHOLD 2048
  
  static int cow_threshold = DEFAULT_COW_THRESHOLD;
  module_param_named(snapshot_cow_threshold, cow_threshold, int, 0644);
  MODULE_PARM_DESC(snapshot_cow_threshold, "Maximum number of chunks being copied on write");
df5d2e908   Mikulas Patocka   dm kcopyd: introd...
144
145
  DECLARE_DM_KCOPYD_THROTTLE_WITH_MODULE_PARM(snapshot_copy_throttle,
  		"A percentage of time allocated for copy on write");
c24110450   Mikulas Patocka   dm snapshot: test...
146
147
148
149
150
  struct dm_dev *dm_snap_origin(struct dm_snapshot *s)
  {
  	return s->origin;
  }
  EXPORT_SYMBOL(dm_snap_origin);
fc56f6fbc   Mike Snitzer   dm snapshot: move...
151
152
153
154
155
  struct dm_dev *dm_snap_cow(struct dm_snapshot *s)
  {
  	return s->cow;
  }
  EXPORT_SYMBOL(dm_snap_cow);
ccc45ea8a   Jonathan Brassow   dm snapshot: remo...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
  static sector_t chunk_to_sector(struct dm_exception_store *store,
  				chunk_t chunk)
  {
  	return chunk << store->chunk_shift;
  }
  
  static int bdev_equal(struct block_device *lhs, struct block_device *rhs)
  {
  	/*
  	 * There is only ever one instance of a particular block
  	 * device so we can compare pointers safely.
  	 */
  	return lhs == rhs;
  }
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
170
  struct dm_snap_pending_exception {
1d4989c85   Jon Brassow   dm snapshot: rena...
171
  	struct dm_exception e;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
174
175
176
177
178
  
  	/*
  	 * Origin buffers waiting for this to complete are held
  	 * in a bio list
  	 */
  	struct bio_list origin_bios;
  	struct bio_list snapshot_bios;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
180
181
182
183
184
185
186
  	/* Pointer back to snapshot context */
  	struct dm_snapshot *snap;
  
  	/*
  	 * 1 indicates the exception has already been sent to
  	 * kcopyd.
  	 */
  	int started;
a6e50b409   Mikulas Patocka   dm snapshot: skip...
187

230c83afd   Mikulas Patocka   dm snapshot: avoi...
188
189
190
191
192
193
194
  	/* There was copying error. */
  	int copy_error;
  
  	/* A sequence number, it is used for in-order completion. */
  	sector_t exception_sequence;
  
  	struct list_head out_of_order_entry;
a6e50b409   Mikulas Patocka   dm snapshot: skip...
195
196
197
198
199
  	/*
  	 * For writing a complete chunk, bypassing the copy.
  	 */
  	struct bio *full_bio;
  	bio_end_io_t *full_bio_end_io;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
201
202
203
204
205
  };
  
  /*
   * Hash table mapping origin volumes to lists of snapshots and
   * a lock to protect it
   */
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
206
207
  static struct kmem_cache *exception_cache;
  static struct kmem_cache *pending_cache;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208

cd45daffd   Mikulas Patocka   dm snapshot: trac...
209
210
211
212
  struct dm_snap_tracked_chunk {
  	struct hlist_node node;
  	chunk_t chunk;
  };
ee18026ac   Mikulas Patocka   dm snapshot: do n...
213
214
215
216
217
218
219
220
221
222
223
224
225
  static void init_tracked_chunk(struct bio *bio)
  {
  	struct dm_snap_tracked_chunk *c = dm_per_bio_data(bio, sizeof(struct dm_snap_tracked_chunk));
  	INIT_HLIST_NODE(&c->node);
  }
  
  static bool is_bio_tracked(struct bio *bio)
  {
  	struct dm_snap_tracked_chunk *c = dm_per_bio_data(bio, sizeof(struct dm_snap_tracked_chunk));
  	return !hlist_unhashed(&c->node);
  }
  
  static void track_chunk(struct dm_snapshot *s, struct bio *bio, chunk_t chunk)
cd45daffd   Mikulas Patocka   dm snapshot: trac...
226
  {
42bc954f2   Mikulas Patocka   dm snapshot: use ...
227
  	struct dm_snap_tracked_chunk *c = dm_per_bio_data(bio, sizeof(struct dm_snap_tracked_chunk));
cd45daffd   Mikulas Patocka   dm snapshot: trac...
228
229
  
  	c->chunk = chunk;
9aa0c0e60   Mikulas Patocka   dm snapshot: opti...
230
  	spin_lock_irq(&s->tracked_chunk_lock);
cd45daffd   Mikulas Patocka   dm snapshot: trac...
231
232
  	hlist_add_head(&c->node,
  		       &s->tracked_chunk_hash[DM_TRACKED_CHUNK_HASH(chunk)]);
9aa0c0e60   Mikulas Patocka   dm snapshot: opti...
233
  	spin_unlock_irq(&s->tracked_chunk_lock);
cd45daffd   Mikulas Patocka   dm snapshot: trac...
234
  }
ee18026ac   Mikulas Patocka   dm snapshot: do n...
235
  static void stop_tracking_chunk(struct dm_snapshot *s, struct bio *bio)
cd45daffd   Mikulas Patocka   dm snapshot: trac...
236
  {
ee18026ac   Mikulas Patocka   dm snapshot: do n...
237
  	struct dm_snap_tracked_chunk *c = dm_per_bio_data(bio, sizeof(struct dm_snap_tracked_chunk));
cd45daffd   Mikulas Patocka   dm snapshot: trac...
238
239
240
241
242
  	unsigned long flags;
  
  	spin_lock_irqsave(&s->tracked_chunk_lock, flags);
  	hlist_del(&c->node);
  	spin_unlock_irqrestore(&s->tracked_chunk_lock, flags);
cd45daffd   Mikulas Patocka   dm snapshot: trac...
243
  }
a8d41b59f   Mikulas Patocka   dm snapshot: fix ...
244
245
246
  static int __chunk_is_tracked(struct dm_snapshot *s, chunk_t chunk)
  {
  	struct dm_snap_tracked_chunk *c;
a8d41b59f   Mikulas Patocka   dm snapshot: fix ...
247
248
249
  	int found = 0;
  
  	spin_lock_irq(&s->tracked_chunk_lock);
b67bfe0d4   Sasha Levin   hlist: drop the n...
250
  	hlist_for_each_entry(c,
a8d41b59f   Mikulas Patocka   dm snapshot: fix ...
251
252
253
254
255
256
257
258
259
260
261
  	    &s->tracked_chunk_hash[DM_TRACKED_CHUNK_HASH(chunk)], node) {
  		if (c->chunk == chunk) {
  			found = 1;
  			break;
  		}
  	}
  
  	spin_unlock_irq(&s->tracked_chunk_lock);
  
  	return found;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
  /*
615d1eb9c   Mike Snitzer   dm snapshot: crea...
263
264
265
266
267
268
269
270
271
272
   * This conflicting I/O is extremely improbable in the caller,
   * so msleep(1) is sufficient and there is no need for a wait queue.
   */
  static void __check_for_conflicting_io(struct dm_snapshot *s, chunk_t chunk)
  {
  	while (__chunk_is_tracked(s, chunk))
  		msleep(1);
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
273
274
275
276
277
278
279
280
281
282
283
284
285
   * One of these per registered origin, held in the snapshot_origins hash
   */
  struct origin {
  	/* The origin device */
  	struct block_device *bdev;
  
  	struct list_head hash_list;
  
  	/* List of snapshots for this origin */
  	struct list_head snapshots;
  };
  
  /*
b735fede8   Mikulas Patocka   dm snapshot: susp...
286
287
288
289
290
291
292
293
294
295
   * This structure is allocated for each origin target
   */
  struct dm_origin {
  	struct dm_dev *dev;
  	struct dm_target *ti;
  	unsigned split_boundary;
  	struct list_head hash_list;
  };
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296
297
298
299
300
301
   * Size of the hash table for origin volumes. If we make this
   * the size of the minors list then it should be nearly perfect
   */
  #define ORIGIN_HASH_SIZE 256
  #define ORIGIN_MASK      0xFF
  static struct list_head *_origins;
b735fede8   Mikulas Patocka   dm snapshot: susp...
302
  static struct list_head *_dm_origins;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
  static struct rw_semaphore _origins_lock;
73dfd078c   Mikulas Patocka   dm snapshot: trig...
304
305
306
  static DECLARE_WAIT_QUEUE_HEAD(_pending_exceptions_done);
  static DEFINE_SPINLOCK(_pending_exceptions_done_spinlock);
  static uint64_t _pending_exceptions_done_count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
308
309
310
311
312
313
  static int init_origin_hash(void)
  {
  	int i;
  
  	_origins = kmalloc(ORIGIN_HASH_SIZE * sizeof(struct list_head),
  			   GFP_KERNEL);
  	if (!_origins) {
b735fede8   Mikulas Patocka   dm snapshot: susp...
314
  		DMERR("unable to allocate memory for _origins");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
316
  		return -ENOMEM;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
318
  	for (i = 0; i < ORIGIN_HASH_SIZE; i++)
  		INIT_LIST_HEAD(_origins + i);
b735fede8   Mikulas Patocka   dm snapshot: susp...
319
320
321
322
323
324
325
326
327
328
  
  	_dm_origins = kmalloc(ORIGIN_HASH_SIZE * sizeof(struct list_head),
  			      GFP_KERNEL);
  	if (!_dm_origins) {
  		DMERR("unable to allocate memory for _dm_origins");
  		kfree(_origins);
  		return -ENOMEM;
  	}
  	for (i = 0; i < ORIGIN_HASH_SIZE; i++)
  		INIT_LIST_HEAD(_dm_origins + i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
330
331
332
333
334
335
336
  	init_rwsem(&_origins_lock);
  
  	return 0;
  }
  
  static void exit_origin_hash(void)
  {
  	kfree(_origins);
b735fede8   Mikulas Patocka   dm snapshot: susp...
337
  	kfree(_dm_origins);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
  }
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
339
  static unsigned origin_hash(struct block_device *bdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  {
  	return bdev->bd_dev & ORIGIN_MASK;
  }
  
  static struct origin *__lookup_origin(struct block_device *origin)
  {
  	struct list_head *ol;
  	struct origin *o;
  
  	ol = &_origins[origin_hash(origin)];
  	list_for_each_entry (o, ol, hash_list)
  		if (bdev_equal(o->bdev, origin))
  			return o;
  
  	return NULL;
  }
  
  static void __insert_origin(struct origin *o)
  {
  	struct list_head *sl = &_origins[origin_hash(o->bdev)];
  	list_add_tail(&o->hash_list, sl);
  }
b735fede8   Mikulas Patocka   dm snapshot: susp...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
  static struct dm_origin *__lookup_dm_origin(struct block_device *origin)
  {
  	struct list_head *ol;
  	struct dm_origin *o;
  
  	ol = &_dm_origins[origin_hash(origin)];
  	list_for_each_entry (o, ol, hash_list)
  		if (bdev_equal(o->dev->bdev, origin))
  			return o;
  
  	return NULL;
  }
  
  static void __insert_dm_origin(struct dm_origin *o)
  {
  	struct list_head *sl = &_dm_origins[origin_hash(o->dev->bdev)];
  	list_add_tail(&o->hash_list, sl);
  }
  
  static void __remove_dm_origin(struct dm_origin *o)
  {
  	list_del(&o->hash_list);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385
  /*
c1f0c183f   Mike Snitzer   dm snapshot: allo...
386
387
388
389
   * _origins_lock must be held when calling this function.
   * Returns number of snapshots registered using the supplied cow device, plus:
   * snap_src - a snapshot suitable for use as a source of exception handover
   * snap_dest - a snapshot capable of receiving exception handover.
9d3b15c4c   Mikulas Patocka   dm snapshot: perm...
390
391
   * snap_merge - an existing snapshot-merge target linked to the same origin.
   *   There can be at most one snapshot-merge target. The parameter is optional.
c1f0c183f   Mike Snitzer   dm snapshot: allo...
392
   *
9d3b15c4c   Mikulas Patocka   dm snapshot: perm...
393
   * Possible return values and states of snap_src and snap_dest.
c1f0c183f   Mike Snitzer   dm snapshot: allo...
394
395
396
397
398
399
400
401
   *   0: NULL, NULL  - first new snapshot
   *   1: snap_src, NULL - normal snapshot
   *   2: snap_src, snap_dest  - waiting for handover
   *   2: snap_src, NULL - handed over, waiting for old to be deleted
   *   1: NULL, snap_dest - source got destroyed without handover
   */
  static int __find_snapshots_sharing_cow(struct dm_snapshot *snap,
  					struct dm_snapshot **snap_src,
9d3b15c4c   Mikulas Patocka   dm snapshot: perm...
402
403
  					struct dm_snapshot **snap_dest,
  					struct dm_snapshot **snap_merge)
c1f0c183f   Mike Snitzer   dm snapshot: allo...
404
405
406
407
408
409
410
411
412
413
414
  {
  	struct dm_snapshot *s;
  	struct origin *o;
  	int count = 0;
  	int active;
  
  	o = __lookup_origin(snap->origin->bdev);
  	if (!o)
  		goto out;
  
  	list_for_each_entry(s, &o->snapshots, list) {
9d3b15c4c   Mikulas Patocka   dm snapshot: perm...
415
416
  		if (dm_target_is_snapshot_merge(s->ti) && snap_merge)
  			*snap_merge = s;
c1f0c183f   Mike Snitzer   dm snapshot: allo...
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
  		if (!bdev_equal(s->cow->bdev, snap->cow->bdev))
  			continue;
  
  		down_read(&s->lock);
  		active = s->active;
  		up_read(&s->lock);
  
  		if (active) {
  			if (snap_src)
  				*snap_src = s;
  		} else if (snap_dest)
  			*snap_dest = s;
  
  		count++;
  	}
  
  out:
  	return count;
  }
  
  /*
   * On success, returns 1 if this snapshot is a handover destination,
   * otherwise returns 0.
   */
  static int __validate_exception_handover(struct dm_snapshot *snap)
  {
  	struct dm_snapshot *snap_src = NULL, *snap_dest = NULL;
9d3b15c4c   Mikulas Patocka   dm snapshot: perm...
444
  	struct dm_snapshot *snap_merge = NULL;
c1f0c183f   Mike Snitzer   dm snapshot: allo...
445
446
  
  	/* Does snapshot need exceptions handed over to it? */
9d3b15c4c   Mikulas Patocka   dm snapshot: perm...
447
448
  	if ((__find_snapshots_sharing_cow(snap, &snap_src, &snap_dest,
  					  &snap_merge) == 2) ||
c1f0c183f   Mike Snitzer   dm snapshot: allo...
449
450
451
452
453
454
455
456
457
458
459
460
  	    snap_dest) {
  		snap->ti->error = "Snapshot cow pairing for exception "
  				  "table handover failed";
  		return -EINVAL;
  	}
  
  	/*
  	 * If no snap_src was found, snap cannot become a handover
  	 * destination.
  	 */
  	if (!snap_src)
  		return 0;
9d3b15c4c   Mikulas Patocka   dm snapshot: perm...
461
462
463
464
465
466
467
468
469
470
471
472
473
  	/*
  	 * Non-snapshot-merge handover?
  	 */
  	if (!dm_target_is_snapshot_merge(snap->ti))
  		return 1;
  
  	/*
  	 * Do not allow more than one merging snapshot.
  	 */
  	if (snap_merge) {
  		snap->ti->error = "A snapshot is already merging.";
  		return -EINVAL;
  	}
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
474
475
476
477
478
479
  	if (!snap_src->store->type->prepare_merge ||
  	    !snap_src->store->type->commit_merge) {
  		snap->ti->error = "Snapshot exception store does not "
  				  "support snapshot-merge.";
  		return -EINVAL;
  	}
c1f0c183f   Mike Snitzer   dm snapshot: allo...
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  	return 1;
  }
  
  static void __insert_snapshot(struct origin *o, struct dm_snapshot *s)
  {
  	struct dm_snapshot *l;
  
  	/* Sort the list according to chunk size, largest-first smallest-last */
  	list_for_each_entry(l, &o->snapshots, list)
  		if (l->store->chunk_size < s->store->chunk_size)
  			break;
  	list_add_tail(&s->list, &l->list);
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
495
496
   * Make a note of the snapshot and its origin so we can look it
   * up when the origin has a write on it.
c1f0c183f   Mike Snitzer   dm snapshot: allo...
497
498
499
500
   *
   * Also validate snapshot exception store handovers.
   * On success, returns 1 if this registration is a handover destination,
   * otherwise returns 0.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
502
503
   */
  static int register_snapshot(struct dm_snapshot *snap)
  {
c1f0c183f   Mike Snitzer   dm snapshot: allo...
504
  	struct origin *o, *new_o = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
505
  	struct block_device *bdev = snap->origin->bdev;
c1f0c183f   Mike Snitzer   dm snapshot: allo...
506
  	int r = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507

60c856c8e   Mikulas Patocka   dm snapshot: fix ...
508
509
510
  	new_o = kmalloc(sizeof(*new_o), GFP_KERNEL);
  	if (!new_o)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511
  	down_write(&_origins_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
512

c1f0c183f   Mike Snitzer   dm snapshot: allo...
513
514
515
516
517
518
519
  	r = __validate_exception_handover(snap);
  	if (r < 0) {
  		kfree(new_o);
  		goto out;
  	}
  
  	o = __lookup_origin(bdev);
60c856c8e   Mikulas Patocka   dm snapshot: fix ...
520
521
522
  	if (o)
  		kfree(new_o);
  	else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523
  		/* New origin */
60c856c8e   Mikulas Patocka   dm snapshot: fix ...
524
  		o = new_o;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
525
526
527
528
529
530
531
  
  		/* Initialise the struct */
  		INIT_LIST_HEAD(&o->snapshots);
  		o->bdev = bdev;
  
  		__insert_origin(o);
  	}
c1f0c183f   Mike Snitzer   dm snapshot: allo...
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
  	__insert_snapshot(o, snap);
  
  out:
  	up_write(&_origins_lock);
  
  	return r;
  }
  
  /*
   * Move snapshot to correct place in list according to chunk size.
   */
  static void reregister_snapshot(struct dm_snapshot *s)
  {
  	struct block_device *bdev = s->origin->bdev;
  
  	down_write(&_origins_lock);
  
  	list_del(&s->list);
  	__insert_snapshot(__lookup_origin(bdev), s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
551
552
  
  	up_write(&_origins_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
553
554
555
556
557
558
559
560
561
562
  }
  
  static void unregister_snapshot(struct dm_snapshot *s)
  {
  	struct origin *o;
  
  	down_write(&_origins_lock);
  	o = __lookup_origin(s->origin->bdev);
  
  	list_del(&s->list);
c1f0c183f   Mike Snitzer   dm snapshot: allo...
563
  	if (o && list_empty(&o->snapshots)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
564
565
566
567
568
569
570
571
572
  		list_del(&o->hash_list);
  		kfree(o);
  	}
  
  	up_write(&_origins_lock);
  }
  
  /*
   * Implementation of the exception hash tables.
d74f81f8a   Milan Broz   dm snapshot: comb...
573
574
   * The lowest hash_shift bits of the chunk number are ignored, allowing
   * some consecutive chunks to be grouped together.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
575
   */
3510cb94f   Jon Brassow   dm snapshot: rena...
576
577
  static int dm_exception_table_init(struct dm_exception_table *et,
  				   uint32_t size, unsigned hash_shift)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
578
579
  {
  	unsigned int i;
d74f81f8a   Milan Broz   dm snapshot: comb...
580
  	et->hash_shift = hash_shift;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581
582
583
584
585
586
587
588
589
590
  	et->hash_mask = size - 1;
  	et->table = dm_vcalloc(size, sizeof(struct list_head));
  	if (!et->table)
  		return -ENOMEM;
  
  	for (i = 0; i < size; i++)
  		INIT_LIST_HEAD(et->table + i);
  
  	return 0;
  }
3510cb94f   Jon Brassow   dm snapshot: rena...
591
592
  static void dm_exception_table_exit(struct dm_exception_table *et,
  				    struct kmem_cache *mem)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
593
594
  {
  	struct list_head *slot;
1d4989c85   Jon Brassow   dm snapshot: rena...
595
  	struct dm_exception *ex, *next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
596
597
598
599
600
601
602
603
604
605
606
607
  	int i, size;
  
  	size = et->hash_mask + 1;
  	for (i = 0; i < size; i++) {
  		slot = et->table + i;
  
  		list_for_each_entry_safe (ex, next, slot, hash_list)
  			kmem_cache_free(mem, ex);
  	}
  
  	vfree(et->table);
  }
191437a53   Jon Brassow   dm snapshot: rena...
608
  static uint32_t exception_hash(struct dm_exception_table *et, chunk_t chunk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
  {
d74f81f8a   Milan Broz   dm snapshot: comb...
610
  	return (chunk >> et->hash_shift) & et->hash_mask;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611
  }
3510cb94f   Jon Brassow   dm snapshot: rena...
612
  static void dm_remove_exception(struct dm_exception *e)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
613
614
615
616
617
618
619
620
  {
  	list_del(&e->hash_list);
  }
  
  /*
   * Return the exception data for a sector, or NULL if not
   * remapped.
   */
3510cb94f   Jon Brassow   dm snapshot: rena...
621
622
  static struct dm_exception *dm_lookup_exception(struct dm_exception_table *et,
  						chunk_t chunk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623
624
  {
  	struct list_head *slot;
1d4989c85   Jon Brassow   dm snapshot: rena...
625
  	struct dm_exception *e;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
627
628
  
  	slot = &et->table[exception_hash(et, chunk)];
  	list_for_each_entry (e, slot, hash_list)
d74f81f8a   Milan Broz   dm snapshot: comb...
629
630
  		if (chunk >= e->old_chunk &&
  		    chunk <= e->old_chunk + dm_consecutive_chunk_count(e))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
631
632
633
634
  			return e;
  
  	return NULL;
  }
119bc5473   Mikulas Patocka   dm snapshot: use ...
635
  static struct dm_exception *alloc_completed_exception(gfp_t gfp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
636
  {
1d4989c85   Jon Brassow   dm snapshot: rena...
637
  	struct dm_exception *e;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638

119bc5473   Mikulas Patocka   dm snapshot: use ...
639
640
  	e = kmem_cache_alloc(exception_cache, gfp);
  	if (!e && gfp == GFP_NOIO)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
641
642
643
644
  		e = kmem_cache_alloc(exception_cache, GFP_ATOMIC);
  
  	return e;
  }
3510cb94f   Jon Brassow   dm snapshot: rena...
645
  static void free_completed_exception(struct dm_exception *e)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
647
648
  {
  	kmem_cache_free(exception_cache, e);
  }
92e868122   Mikulas Patocka   dm snapshot: use ...
649
  static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snapshot *s)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650
  {
92e868122   Mikulas Patocka   dm snapshot: use ...
651
652
  	struct dm_snap_pending_exception *pe = mempool_alloc(s->pending_pool,
  							     GFP_NOIO);
879129d20   Mikulas Patocka   dm snapshot: wait...
653
  	atomic_inc(&s->pending_exceptions_count);
92e868122   Mikulas Patocka   dm snapshot: use ...
654
655
656
  	pe->snap = s;
  
  	return pe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
657
  }
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
658
  static void free_pending_exception(struct dm_snap_pending_exception *pe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
659
  {
879129d20   Mikulas Patocka   dm snapshot: wait...
660
661
662
  	struct dm_snapshot *s = pe->snap;
  
  	mempool_free(pe, s->pending_pool);
4e857c58e   Peter Zijlstra   arch: Mass conver...
663
  	smp_mb__before_atomic();
879129d20   Mikulas Patocka   dm snapshot: wait...
664
  	atomic_dec(&s->pending_exceptions_count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
665
  }
3510cb94f   Jon Brassow   dm snapshot: rena...
666
667
  static void dm_insert_exception(struct dm_exception_table *eh,
  				struct dm_exception *new_e)
d74f81f8a   Milan Broz   dm snapshot: comb...
668
  {
d74f81f8a   Milan Broz   dm snapshot: comb...
669
  	struct list_head *l;
1d4989c85   Jon Brassow   dm snapshot: rena...
670
  	struct dm_exception *e = NULL;
d74f81f8a   Milan Broz   dm snapshot: comb...
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
  
  	l = &eh->table[exception_hash(eh, new_e->old_chunk)];
  
  	/* Add immediately if this table doesn't support consecutive chunks */
  	if (!eh->hash_shift)
  		goto out;
  
  	/* List is ordered by old_chunk */
  	list_for_each_entry_reverse(e, l, hash_list) {
  		/* Insert after an existing chunk? */
  		if (new_e->old_chunk == (e->old_chunk +
  					 dm_consecutive_chunk_count(e) + 1) &&
  		    new_e->new_chunk == (dm_chunk_number(e->new_chunk) +
  					 dm_consecutive_chunk_count(e) + 1)) {
  			dm_consecutive_chunk_count_inc(e);
3510cb94f   Jon Brassow   dm snapshot: rena...
686
  			free_completed_exception(new_e);
d74f81f8a   Milan Broz   dm snapshot: comb...
687
688
689
690
691
692
693
694
695
  			return;
  		}
  
  		/* Insert before an existing chunk? */
  		if (new_e->old_chunk == (e->old_chunk - 1) &&
  		    new_e->new_chunk == (dm_chunk_number(e->new_chunk) - 1)) {
  			dm_consecutive_chunk_count_inc(e);
  			e->old_chunk--;
  			e->new_chunk--;
3510cb94f   Jon Brassow   dm snapshot: rena...
696
  			free_completed_exception(new_e);
d74f81f8a   Milan Broz   dm snapshot: comb...
697
698
699
700
701
702
703
704
705
706
  			return;
  		}
  
  		if (new_e->old_chunk > e->old_chunk)
  			break;
  	}
  
  out:
  	list_add(&new_e->hash_list, e ? &e->hash_list : l);
  }
a159c1ac5   Jonathan Brassow   dm snapshot: exte...
707
708
709
710
711
  /*
   * Callback used by the exception stores to load exceptions when
   * initialising.
   */
  static int dm_add_exception(void *context, chunk_t old, chunk_t new)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
712
  {
a159c1ac5   Jonathan Brassow   dm snapshot: exte...
713
  	struct dm_snapshot *s = context;
1d4989c85   Jon Brassow   dm snapshot: rena...
714
  	struct dm_exception *e;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
715

119bc5473   Mikulas Patocka   dm snapshot: use ...
716
  	e = alloc_completed_exception(GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
717
718
719
720
  	if (!e)
  		return -ENOMEM;
  
  	e->old_chunk = old;
d74f81f8a   Milan Broz   dm snapshot: comb...
721
722
  
  	/* Consecutive_count is implicitly initialised to zero */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
723
  	e->new_chunk = new;
d74f81f8a   Milan Broz   dm snapshot: comb...
724

3510cb94f   Jon Brassow   dm snapshot: rena...
725
  	dm_insert_exception(&s->complete, e);
d74f81f8a   Milan Broz   dm snapshot: comb...
726

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
727
728
  	return 0;
  }
7e201b351   Mikulas Patocka   dm snapshot: abst...
729
730
731
732
  /*
   * Return a minimum chunk size of all snapshots that have the specified origin.
   * Return zero if the origin has no snapshots.
   */
542f90381   Mike Snitzer   dm: support non p...
733
  static uint32_t __minimum_chunk_size(struct origin *o)
7e201b351   Mikulas Patocka   dm snapshot: abst...
734
735
736
737
738
739
740
741
  {
  	struct dm_snapshot *snap;
  	unsigned chunk_size = 0;
  
  	if (o)
  		list_for_each_entry(snap, &o->snapshots, list)
  			chunk_size = min_not_zero(chunk_size,
  						  snap->store->chunk_size);
542f90381   Mike Snitzer   dm: support non p...
742
  	return (uint32_t) chunk_size;
7e201b351   Mikulas Patocka   dm snapshot: abst...
743
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
744
745
746
747
748
749
750
751
752
753
754
755
756
  /*
   * Hard coded magic.
   */
  static int calc_max_buckets(void)
  {
  	/* use a fixed size of 2MB */
  	unsigned long mem = 2 * 1024 * 1024;
  	mem /= sizeof(struct list_head);
  
  	return mem;
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
757
758
   * Allocate room for a suitable hash table.
   */
fee1998e9   Jonathan Brassow   dm snapshot: move...
759
  static int init_hash_tables(struct dm_snapshot *s)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
760
  {
60e356f38   Mikulas Patocka   dm-snapshot: fix ...
761
  	sector_t hash_size, cow_dev_size, max_buckets;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
762
763
764
765
766
  
  	/*
  	 * Calculate based on the size of the original volume or
  	 * the COW volume...
  	 */
fc56f6fbc   Mike Snitzer   dm snapshot: move...
767
  	cow_dev_size = get_dev_size(s->cow->bdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
768
  	max_buckets = calc_max_buckets();
60e356f38   Mikulas Patocka   dm-snapshot: fix ...
769
  	hash_size = cow_dev_size >> s->store->chunk_shift;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
770
  	hash_size = min(hash_size, max_buckets);
8e87b9b81   Mikulas Patocka   dm snapshot: cope...
771
772
  	if (hash_size < 64)
  		hash_size = 64;
8defd8308   Robert P. J. Day   dm snapshot: use ...
773
  	hash_size = rounddown_pow_of_two(hash_size);
3510cb94f   Jon Brassow   dm snapshot: rena...
774
775
  	if (dm_exception_table_init(&s->complete, hash_size,
  				    DM_CHUNK_CONSECUTIVE_BITS))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
776
777
778
779
780
781
782
783
784
  		return -ENOMEM;
  
  	/*
  	 * Allocate hash table for in-flight exceptions
  	 * Make this smaller than the real hash table
  	 */
  	hash_size >>= 3;
  	if (hash_size < 64)
  		hash_size = 64;
3510cb94f   Jon Brassow   dm snapshot: rena...
785
786
  	if (dm_exception_table_init(&s->pending, hash_size, 0)) {
  		dm_exception_table_exit(&s->complete, exception_cache);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
787
788
789
790
791
  		return -ENOMEM;
  	}
  
  	return 0;
  }
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
792
793
794
  static void merge_shutdown(struct dm_snapshot *s)
  {
  	clear_bit_unlock(RUNNING_MERGE, &s->state_bits);
4e857c58e   Peter Zijlstra   arch: Mass conver...
795
  	smp_mb__after_atomic();
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
796
797
  	wake_up_bit(&s->state_bits, RUNNING_MERGE);
  }
9fe862548   Mikulas Patocka   dm snapshot: queu...
798
799
800
801
802
803
804
  static struct bio *__release_queued_bios_after_merge(struct dm_snapshot *s)
  {
  	s->first_merging_chunk = 0;
  	s->num_merging_chunks = 0;
  
  	return bio_list_get(&s->bios_queued_during_merge);
  }
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
805
806
807
808
809
810
811
  /*
   * Remove one chunk from the index of completed exceptions.
   */
  static int __remove_single_exception_chunk(struct dm_snapshot *s,
  					   chunk_t old_chunk)
  {
  	struct dm_exception *e;
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
  	e = dm_lookup_exception(&s->complete, old_chunk);
  	if (!e) {
  		DMERR("Corruption detected: exception for block %llu is "
  		      "on disk but not in memory",
  		      (unsigned long long)old_chunk);
  		return -EINVAL;
  	}
  
  	/*
  	 * If this is the only chunk using this exception, remove exception.
  	 */
  	if (!dm_consecutive_chunk_count(e)) {
  		dm_remove_exception(e);
  		free_completed_exception(e);
  		return 0;
  	}
  
  	/*
  	 * The chunk may be either at the beginning or the end of a
  	 * group of consecutive chunks - never in the middle.  We are
  	 * removing chunks in the opposite order to that in which they
  	 * were added, so this should always be true.
  	 * Decrement the consecutive chunk counter and adjust the
  	 * starting point if necessary.
  	 */
  	if (old_chunk == e->old_chunk) {
  		e->old_chunk++;
  		e->new_chunk++;
  	} else if (old_chunk != e->old_chunk +
  		   dm_consecutive_chunk_count(e)) {
  		DMERR("Attempt to merge block %llu from the "
  		      "middle of a chunk range [%llu - %llu]",
  		      (unsigned long long)old_chunk,
  		      (unsigned long long)e->old_chunk,
  		      (unsigned long long)
  		      e->old_chunk + dm_consecutive_chunk_count(e));
  		return -EINVAL;
  	}
  
  	dm_consecutive_chunk_count_dec(e);
  
  	return 0;
  }
9fe862548   Mikulas Patocka   dm snapshot: queu...
855
856
857
  static void flush_bios(struct bio *bio);
  
  static int remove_single_exception_chunk(struct dm_snapshot *s)
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
858
  {
9fe862548   Mikulas Patocka   dm snapshot: queu...
859
860
861
  	struct bio *b = NULL;
  	int r;
  	chunk_t old_chunk = s->first_merging_chunk + s->num_merging_chunks - 1;
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
862
863
  
  	down_write(&s->lock);
9fe862548   Mikulas Patocka   dm snapshot: queu...
864
865
866
867
868
869
870
871
872
873
874
875
876
877
  
  	/*
  	 * Process chunks (and associated exceptions) in reverse order
  	 * so that dm_consecutive_chunk_count_dec() accounting works.
  	 */
  	do {
  		r = __remove_single_exception_chunk(s, old_chunk);
  		if (r)
  			goto out;
  	} while (old_chunk-- > s->first_merging_chunk);
  
  	b = __release_queued_bios_after_merge(s);
  
  out:
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
878
  	up_write(&s->lock);
9fe862548   Mikulas Patocka   dm snapshot: queu...
879
880
  	if (b)
  		flush_bios(b);
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
881
882
883
  
  	return r;
  }
73dfd078c   Mikulas Patocka   dm snapshot: trig...
884
885
  static int origin_write_extent(struct dm_snapshot *merging_snap,
  			       sector_t sector, unsigned chunk_size);
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
886
887
  static void merge_callback(int read_err, unsigned long write_err,
  			   void *context);
73dfd078c   Mikulas Patocka   dm snapshot: trig...
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
  static uint64_t read_pending_exceptions_done_count(void)
  {
  	uint64_t pending_exceptions_done;
  
  	spin_lock(&_pending_exceptions_done_spinlock);
  	pending_exceptions_done = _pending_exceptions_done_count;
  	spin_unlock(&_pending_exceptions_done_spinlock);
  
  	return pending_exceptions_done;
  }
  
  static void increment_pending_exceptions_done_count(void)
  {
  	spin_lock(&_pending_exceptions_done_spinlock);
  	_pending_exceptions_done_count++;
  	spin_unlock(&_pending_exceptions_done_spinlock);
  
  	wake_up_all(&_pending_exceptions_done);
  }
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
907
908
  static void snapshot_merge_next_chunks(struct dm_snapshot *s)
  {
8a2d52862   Mike Snitzer   dm snapshot: merg...
909
  	int i, linear_chunks;
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
910
911
  	chunk_t old_chunk, new_chunk;
  	struct dm_io_region src, dest;
8a2d52862   Mike Snitzer   dm snapshot: merg...
912
  	sector_t io_size;
73dfd078c   Mikulas Patocka   dm snapshot: trig...
913
  	uint64_t previous_count;
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
914
915
916
917
918
919
920
921
922
923
924
925
  
  	BUG_ON(!test_bit(RUNNING_MERGE, &s->state_bits));
  	if (unlikely(test_bit(SHUTDOWN_MERGE, &s->state_bits)))
  		goto shut;
  
  	/*
  	 * valid flag never changes during merge, so no lock required.
  	 */
  	if (!s->valid) {
  		DMERR("Snapshot is invalid: can't merge");
  		goto shut;
  	}
8a2d52862   Mike Snitzer   dm snapshot: merg...
926
927
928
  	linear_chunks = s->store->type->prepare_merge(s->store, &old_chunk,
  						      &new_chunk);
  	if (linear_chunks <= 0) {
d8ddb1cff   Mike Snitzer   dm snapshot: repo...
929
  		if (linear_chunks < 0) {
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
930
931
  			DMERR("Read error in exception store: "
  			      "shutting down merge");
d8ddb1cff   Mike Snitzer   dm snapshot: repo...
932
933
934
935
  			down_write(&s->lock);
  			s->merge_failed = 1;
  			up_write(&s->lock);
  		}
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
936
937
  		goto shut;
  	}
8a2d52862   Mike Snitzer   dm snapshot: merg...
938
939
940
941
942
943
944
945
946
  	/* Adjust old_chunk and new_chunk to reflect start of linear region */
  	old_chunk = old_chunk + 1 - linear_chunks;
  	new_chunk = new_chunk + 1 - linear_chunks;
  
  	/*
  	 * Use one (potentially large) I/O to copy all 'linear_chunks'
  	 * from the exception store to the origin
  	 */
  	io_size = linear_chunks * s->store->chunk_size;
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
947

1e03f97e4   Mikulas Patocka   dm snapshot: add ...
948
949
  	dest.bdev = s->origin->bdev;
  	dest.sector = chunk_to_sector(s->store, old_chunk);
8a2d52862   Mike Snitzer   dm snapshot: merg...
950
  	dest.count = min(io_size, get_dev_size(dest.bdev) - dest.sector);
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
951
952
953
954
  
  	src.bdev = s->cow->bdev;
  	src.sector = chunk_to_sector(s->store, new_chunk);
  	src.count = dest.count;
73dfd078c   Mikulas Patocka   dm snapshot: trig...
955
956
957
958
959
960
961
962
963
964
  	/*
  	 * Reallocate any exceptions needed in other snapshots then
  	 * wait for the pending exceptions to complete.
  	 * Each time any pending exception (globally on the system)
  	 * completes we are woken and repeat the process to find out
  	 * if we can proceed.  While this may not seem a particularly
  	 * efficient algorithm, it is not expected to have any
  	 * significant impact on performance.
  	 */
  	previous_count = read_pending_exceptions_done_count();
8a2d52862   Mike Snitzer   dm snapshot: merg...
965
  	while (origin_write_extent(s, dest.sector, io_size)) {
73dfd078c   Mikulas Patocka   dm snapshot: trig...
966
967
968
969
970
971
  		wait_event(_pending_exceptions_done,
  			   (read_pending_exceptions_done_count() !=
  			    previous_count));
  		/* Retry after the wait, until all exceptions are done. */
  		previous_count = read_pending_exceptions_done_count();
  	}
9fe862548   Mikulas Patocka   dm snapshot: queu...
972
973
  	down_write(&s->lock);
  	s->first_merging_chunk = old_chunk;
8a2d52862   Mike Snitzer   dm snapshot: merg...
974
  	s->num_merging_chunks = linear_chunks;
9fe862548   Mikulas Patocka   dm snapshot: queu...
975
  	up_write(&s->lock);
8a2d52862   Mike Snitzer   dm snapshot: merg...
976
977
978
  	/* Wait until writes to all 'linear_chunks' drain */
  	for (i = 0; i < linear_chunks; i++)
  		__check_for_conflicting_io(s, old_chunk + i);
9fe862548   Mikulas Patocka   dm snapshot: queu...
979

1e03f97e4   Mikulas Patocka   dm snapshot: add ...
980
981
982
983
984
985
  	dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, merge_callback, s);
  	return;
  
  shut:
  	merge_shutdown(s);
  }
9fe862548   Mikulas Patocka   dm snapshot: queu...
986
  static void error_bios(struct bio *bio);
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
987
988
989
  static void merge_callback(int read_err, unsigned long write_err, void *context)
  {
  	struct dm_snapshot *s = context;
9fe862548   Mikulas Patocka   dm snapshot: queu...
990
  	struct bio *b = NULL;
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
991
992
993
994
995
996
997
998
  
  	if (read_err || write_err) {
  		if (read_err)
  			DMERR("Read error: shutting down merge.");
  		else
  			DMERR("Write error: shutting down merge.");
  		goto shut;
  	}
9fe862548   Mikulas Patocka   dm snapshot: queu...
999
1000
  	if (s->store->type->commit_merge(s->store,
  					 s->num_merging_chunks) < 0) {
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
1001
1002
1003
  		DMERR("Write error in exception store: shutting down merge");
  		goto shut;
  	}
9fe862548   Mikulas Patocka   dm snapshot: queu...
1004
1005
  	if (remove_single_exception_chunk(s) < 0)
  		goto shut;
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
1006
1007
1008
1009
1010
  	snapshot_merge_next_chunks(s);
  
  	return;
  
  shut:
9fe862548   Mikulas Patocka   dm snapshot: queu...
1011
  	down_write(&s->lock);
d8ddb1cff   Mike Snitzer   dm snapshot: repo...
1012
  	s->merge_failed = 1;
9fe862548   Mikulas Patocka   dm snapshot: queu...
1013
1014
1015
  	b = __release_queued_bios_after_merge(s);
  	up_write(&s->lock);
  	error_bios(b);
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
1016
1017
1018
1019
1020
1021
1022
1023
  	merge_shutdown(s);
  }
  
  static void start_merge(struct dm_snapshot *s)
  {
  	if (!test_and_set_bit(RUNNING_MERGE, &s->state_bits))
  		snapshot_merge_next_chunks(s);
  }
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
1024
1025
1026
1027
1028
1029
  /*
   * Stop the merging process and wait until it finishes.
   */
  static void stop_merge(struct dm_snapshot *s)
  {
  	set_bit(SHUTDOWN_MERGE, &s->state_bits);
743162013   NeilBrown   sched: Remove pro...
1030
  	wait_on_bit(&s->state_bits, RUNNING_MERGE, TASK_UNINTERRUPTIBLE);
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
1031
1032
  	clear_bit(SHUTDOWN_MERGE, &s->state_bits);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
  /*
b0d3cc011   Mike Snitzer   dm snapshot: add ...
1034
   * Construct a snapshot mapping: <origin_dev> <COW-dev> <p|po|n> <chunk-size>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1035
1036
1037
1038
   */
  static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
  {
  	struct dm_snapshot *s;
cd45daffd   Mikulas Patocka   dm snapshot: trac...
1039
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1040
  	int r = -EINVAL;
fc56f6fbc   Mike Snitzer   dm snapshot: move...
1041
  	char *origin_path, *cow_path;
4df2bf466   DingXiang   dm snapshot: disa...
1042
  	dev_t origin_dev, cow_dev;
55a62eef8   Alasdair G Kergon   dm: rename reques...
1043
  	unsigned args_used, num_flush_bios = 1;
10b8106a7   Mike Snitzer   dm snapshot: supp...
1044
  	fmode_t origin_mode = FMODE_READ;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1045

4c7e3bf44   Mark McLoughlin   [PATCH] dm snapsh...
1046
  	if (argc != 4) {
72d948616   Alasdair G Kergon   [PATCH] dm: impro...
1047
  		ti->error = "requires exactly 4 arguments";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1048
  		r = -EINVAL;
fc56f6fbc   Mike Snitzer   dm snapshot: move...
1049
  		goto bad;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1050
  	}
10b8106a7   Mike Snitzer   dm snapshot: supp...
1051
  	if (dm_target_is_snapshot_merge(ti)) {
55a62eef8   Alasdair G Kergon   dm: rename reques...
1052
  		num_flush_bios = 2;
10b8106a7   Mike Snitzer   dm snapshot: supp...
1053
1054
  		origin_mode = FMODE_WRITE;
  	}
fc56f6fbc   Mike Snitzer   dm snapshot: move...
1055
1056
  	s = kmalloc(sizeof(*s), GFP_KERNEL);
  	if (!s) {
a2d2b0345   Jonathan Brassow   dm snapshot: styl...
1057
  		ti->error = "Cannot allocate private snapshot structure";
fc56f6fbc   Mike Snitzer   dm snapshot: move...
1058
1059
1060
  		r = -ENOMEM;
  		goto bad;
  	}
c24110450   Mikulas Patocka   dm snapshot: test...
1061
1062
1063
1064
1065
1066
1067
1068
1069
  	origin_path = argv[0];
  	argv++;
  	argc--;
  
  	r = dm_get_device(ti, origin_path, origin_mode, &s->origin);
  	if (r) {
  		ti->error = "Cannot get origin device";
  		goto bad_origin;
  	}
4df2bf466   DingXiang   dm snapshot: disa...
1070
  	origin_dev = s->origin->bdev->bd_dev;
c24110450   Mikulas Patocka   dm snapshot: test...
1071

fc56f6fbc   Mike Snitzer   dm snapshot: move...
1072
1073
1074
  	cow_path = argv[0];
  	argv++;
  	argc--;
4df2bf466   DingXiang   dm snapshot: disa...
1075
1076
1077
1078
1079
1080
  	cow_dev = dm_get_dev_t(cow_path);
  	if (cow_dev && cow_dev == origin_dev) {
  		ti->error = "COW device cannot be the same as origin device";
  		r = -EINVAL;
  		goto bad_cow;
  	}
024d37e95   Milan Broz   dm: fix opening l...
1081
  	r = dm_get_device(ti, cow_path, dm_table_get_mode(ti->table), &s->cow);
fc56f6fbc   Mike Snitzer   dm snapshot: move...
1082
1083
1084
1085
1086
1087
  	if (r) {
  		ti->error = "Cannot get COW device";
  		goto bad_cow;
  	}
  
  	r = dm_exception_store_create(ti, argc, argv, s, &args_used, &s->store);
fee1998e9   Jonathan Brassow   dm snapshot: move...
1088
1089
  	if (r) {
  		ti->error = "Couldn't create exception store";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1090
  		r = -EINVAL;
fc56f6fbc   Mike Snitzer   dm snapshot: move...
1091
  		goto bad_store;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1092
  	}
fee1998e9   Jonathan Brassow   dm snapshot: move...
1093
1094
  	argv += args_used;
  	argc -= args_used;
fc56f6fbc   Mike Snitzer   dm snapshot: move...
1095
  	s->ti = ti;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1096
  	s->valid = 1;
76c44f6d8   Mikulas Patocka   dm snapshot: don'...
1097
  	s->snapshot_overflowed = 0;
aa14edeb9   Alasdair G Kergon   [PATCH] device-ma...
1098
  	s->active = 0;
879129d20   Mikulas Patocka   dm snapshot: wait...
1099
  	atomic_set(&s->pending_exceptions_count, 0);
230c83afd   Mikulas Patocka   dm snapshot: avoi...
1100
1101
1102
  	s->exception_start_sequence = 0;
  	s->exception_complete_sequence = 0;
  	INIT_LIST_HEAD(&s->out_of_order_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1103
  	init_rwsem(&s->lock);
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1104
  	INIT_LIST_HEAD(&s->list);
ca3a931fd   Alasdair G Kergon   [PATCH] dm snapsh...
1105
  	spin_lock_init(&s->pe_lock);
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
1106
  	s->state_bits = 0;
d8ddb1cff   Mike Snitzer   dm snapshot: repo...
1107
  	s->merge_failed = 0;
9fe862548   Mikulas Patocka   dm snapshot: queu...
1108
1109
1110
  	s->first_merging_chunk = 0;
  	s->num_merging_chunks = 0;
  	bio_list_init(&s->bios_queued_during_merge);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1111
1112
  
  	/* Allocate hash table for COW data */
fee1998e9   Jonathan Brassow   dm snapshot: move...
1113
  	if (init_hash_tables(s)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1114
1115
  		ti->error = "Unable to allocate hash table space";
  		r = -ENOMEM;
fee1998e9   Jonathan Brassow   dm snapshot: move...
1116
  		goto bad_hash_tables;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1117
  	}
8189ee479   Nikos Tsironis   dm snapshot: Fix ...
1118
  	sema_init(&s->cow_count, (cow_threshold > 0) ? cow_threshold : INT_MAX);
df5d2e908   Mikulas Patocka   dm kcopyd: introd...
1119
  	s->kcopyd_client = dm_kcopyd_client_create(&dm_kcopyd_throttle);
fa34ce730   Mikulas Patocka   dm kcopyd: return...
1120
1121
  	if (IS_ERR(s->kcopyd_client)) {
  		r = PTR_ERR(s->kcopyd_client);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1122
  		ti->error = "Could not create kcopyd client";
fee1998e9   Jonathan Brassow   dm snapshot: move...
1123
  		goto bad_kcopyd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1124
  	}
92e868122   Mikulas Patocka   dm snapshot: use ...
1125
1126
1127
  	s->pending_pool = mempool_create_slab_pool(MIN_IOS, pending_cache);
  	if (!s->pending_pool) {
  		ti->error = "Could not allocate mempool for pending exceptions";
09e8b8138   Wei Yongjun   dm snapshot: fix ...
1128
  		r = -ENOMEM;
fee1998e9   Jonathan Brassow   dm snapshot: move...
1129
  		goto bad_pending_pool;
92e868122   Mikulas Patocka   dm snapshot: use ...
1130
  	}
cd45daffd   Mikulas Patocka   dm snapshot: trac...
1131
1132
1133
1134
  	for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++)
  		INIT_HLIST_HEAD(&s->tracked_chunk_hash[i]);
  
  	spin_lock_init(&s->tracked_chunk_lock);
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1135
  	ti->private = s;
55a62eef8   Alasdair G Kergon   dm: rename reques...
1136
  	ti->num_flush_bios = num_flush_bios;
30187e1d4   Mike Snitzer   dm: rename target...
1137
  	ti->per_io_data_size = sizeof(struct dm_snap_tracked_chunk);
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
  
  	/* Add snapshot to the list of snapshots for this origin */
  	/* Exceptions aren't triggered till snapshot_resume() is called */
  	r = register_snapshot(s);
  	if (r == -ENOMEM) {
  		ti->error = "Snapshot origin struct allocation failed";
  		goto bad_load_and_register;
  	} else if (r < 0) {
  		/* invalid handover, register_snapshot has set ti->error */
  		goto bad_load_and_register;
  	}
  
  	/*
  	 * Metadata must only be loaded into one table at once, so skip this
  	 * if metadata will be handed over during resume.
  	 * Chunk size will be set during the handover - set it to zero to
  	 * ensure it's ignored.
  	 */
  	if (r > 0) {
  		s->store->chunk_size = 0;
  		return 0;
  	}
493df71c6   Jonathan Brassow   dm exception stor...
1160
1161
  	r = s->store->type->read_metadata(s->store, dm_add_exception,
  					  (void *)s);
0764147b1   Milan Broz   dm snapshot: perm...
1162
  	if (r < 0) {
f9cea4f70   Mark McLoughlin   [PATCH] dm snapsh...
1163
  		ti->error = "Failed to read snapshot metadata";
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1164
  		goto bad_read_metadata;
0764147b1   Milan Broz   dm snapshot: perm...
1165
1166
1167
  	} else if (r > 0) {
  		s->valid = 0;
  		DMWARN("Snapshot is marked invalid.");
f9cea4f70   Mark McLoughlin   [PATCH] dm snapsh...
1168
  	}
aa14edeb9   Alasdair G Kergon   [PATCH] device-ma...
1169

3f2412dc8   Mikulas Patocka   dm snapshot: requ...
1170
1171
  	if (!s->store->chunk_size) {
  		ti->error = "Chunk size not set";
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1172
  		goto bad_read_metadata;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1173
  	}
542f90381   Mike Snitzer   dm: support non p...
1174
1175
1176
1177
  
  	r = dm_set_target_max_io_len(ti, s->store->chunk_size);
  	if (r)
  		goto bad_read_metadata;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1178
1179
  
  	return 0;
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1180
1181
  bad_read_metadata:
  	unregister_snapshot(s);
fee1998e9   Jonathan Brassow   dm snapshot: move...
1182
  bad_load_and_register:
92e868122   Mikulas Patocka   dm snapshot: use ...
1183
  	mempool_destroy(s->pending_pool);
fee1998e9   Jonathan Brassow   dm snapshot: move...
1184
  bad_pending_pool:
eb69aca5d   Heinz Mauelshagen   dm kcopyd: clean ...
1185
  	dm_kcopyd_client_destroy(s->kcopyd_client);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1186

fee1998e9   Jonathan Brassow   dm snapshot: move...
1187
  bad_kcopyd:
3510cb94f   Jon Brassow   dm snapshot: rena...
1188
1189
  	dm_exception_table_exit(&s->pending, pending_cache);
  	dm_exception_table_exit(&s->complete, exception_cache);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1190

fee1998e9   Jonathan Brassow   dm snapshot: move...
1191
  bad_hash_tables:
fc56f6fbc   Mike Snitzer   dm snapshot: move...
1192
  	dm_exception_store_destroy(s->store);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1193

fc56f6fbc   Mike Snitzer   dm snapshot: move...
1194
1195
  bad_store:
  	dm_put_device(ti, s->cow);
fee1998e9   Jonathan Brassow   dm snapshot: move...
1196

fc56f6fbc   Mike Snitzer   dm snapshot: move...
1197
  bad_cow:
c24110450   Mikulas Patocka   dm snapshot: test...
1198
1199
1200
  	dm_put_device(ti, s->origin);
  
  bad_origin:
fc56f6fbc   Mike Snitzer   dm snapshot: move...
1201
1202
1203
  	kfree(s);
  
  bad:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1204
1205
  	return r;
  }
31c93a0c2   Milan Broz   [PATCH] dm: snaps...
1206
1207
  static void __free_exceptions(struct dm_snapshot *s)
  {
eb69aca5d   Heinz Mauelshagen   dm kcopyd: clean ...
1208
  	dm_kcopyd_client_destroy(s->kcopyd_client);
31c93a0c2   Milan Broz   [PATCH] dm: snaps...
1209
  	s->kcopyd_client = NULL;
3510cb94f   Jon Brassow   dm snapshot: rena...
1210
1211
  	dm_exception_table_exit(&s->pending, pending_cache);
  	dm_exception_table_exit(&s->complete, exception_cache);
31c93a0c2   Milan Broz   [PATCH] dm: snaps...
1212
  }
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
  static void __handover_exceptions(struct dm_snapshot *snap_src,
  				  struct dm_snapshot *snap_dest)
  {
  	union {
  		struct dm_exception_table table_swap;
  		struct dm_exception_store *store_swap;
  	} u;
  
  	/*
  	 * Swap all snapshot context information between the two instances.
  	 */
  	u.table_swap = snap_dest->complete;
  	snap_dest->complete = snap_src->complete;
  	snap_src->complete = u.table_swap;
  
  	u.store_swap = snap_dest->store;
  	snap_dest->store = snap_src->store;
b0d3cc011   Mike Snitzer   dm snapshot: add ...
1230
  	snap_dest->store->userspace_supports_overflow = u.store_swap->userspace_supports_overflow;
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1231
1232
1233
1234
  	snap_src->store = u.store_swap;
  
  	snap_dest->store->snap = snap_dest;
  	snap_src->store->snap = snap_src;
542f90381   Mike Snitzer   dm: support non p...
1235
  	snap_dest->ti->max_io_len = snap_dest->store->chunk_size;
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1236
  	snap_dest->valid = snap_src->valid;
76c44f6d8   Mikulas Patocka   dm snapshot: don'...
1237
  	snap_dest->snapshot_overflowed = snap_src->snapshot_overflowed;
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1238
1239
1240
1241
1242
1243
  
  	/*
  	 * Set source invalid to ensure it receives no further I/O.
  	 */
  	snap_src->valid = 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1244
1245
  static void snapshot_dtr(struct dm_target *ti)
  {
cd45daffd   Mikulas Patocka   dm snapshot: trac...
1246
1247
1248
  #ifdef CONFIG_DM_DEBUG
  	int i;
  #endif
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
1249
  	struct dm_snapshot *s = ti->private;
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1250
  	struct dm_snapshot *snap_src = NULL, *snap_dest = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1251

c1f0c183f   Mike Snitzer   dm snapshot: allo...
1252
1253
  	down_read(&_origins_lock);
  	/* Check whether exception handover must be cancelled */
9d3b15c4c   Mikulas Patocka   dm snapshot: perm...
1254
  	(void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL);
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1255
1256
1257
1258
1259
1260
1261
  	if (snap_src && snap_dest && (s == snap_src)) {
  		down_write(&snap_dest->lock);
  		snap_dest->valid = 0;
  		up_write(&snap_dest->lock);
  		DMERR("Cancelling snapshot handover.");
  	}
  	up_read(&_origins_lock);
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
1262
1263
  	if (dm_target_is_snapshot_merge(ti))
  		stop_merge(s);
138728dc9   Alasdair G Kergon   [PATCH] dm snapsh...
1264
1265
  	/* Prevent further origin writes from using this snapshot. */
  	/* After this returns there can be no new kcopyd jobs. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1266
  	unregister_snapshot(s);
879129d20   Mikulas Patocka   dm snapshot: wait...
1267
  	while (atomic_read(&s->pending_exceptions_count))
90fa1527b   Mikulas Patocka   dm snapshot: chan...
1268
  		msleep(1);
879129d20   Mikulas Patocka   dm snapshot: wait...
1269
1270
1271
1272
1273
  	/*
  	 * Ensure instructions in mempool_destroy aren't reordered
  	 * before atomic_read.
  	 */
  	smp_mb();
cd45daffd   Mikulas Patocka   dm snapshot: trac...
1274
1275
1276
1277
  #ifdef CONFIG_DM_DEBUG
  	for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++)
  		BUG_ON(!hlist_empty(&s->tracked_chunk_hash[i]));
  #endif
31c93a0c2   Milan Broz   [PATCH] dm: snaps...
1278
  	__free_exceptions(s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1279

92e868122   Mikulas Patocka   dm snapshot: use ...
1280
  	mempool_destroy(s->pending_pool);
fee1998e9   Jonathan Brassow   dm snapshot: move...
1281
  	dm_exception_store_destroy(s->store);
138728dc9   Alasdair G Kergon   [PATCH] dm snapsh...
1282

fc56f6fbc   Mike Snitzer   dm snapshot: move...
1283
  	dm_put_device(ti, s->cow);
c24110450   Mikulas Patocka   dm snapshot: test...
1284
  	dm_put_device(ti, s->origin);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
  	kfree(s);
  }
  
  /*
   * Flush a list of buffers.
   */
  static void flush_bios(struct bio *bio)
  {
  	struct bio *n;
  
  	while (bio) {
  		n = bio->bi_next;
  		bio->bi_next = NULL;
  		generic_make_request(bio);
  		bio = n;
  	}
  }
515ad66cc   Mikulas Patocka   dm snapshot: rewo...
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
  static int do_origin(struct dm_dev *origin, struct bio *bio);
  
  /*
   * Flush a list of buffers.
   */
  static void retry_origin_bios(struct dm_snapshot *s, struct bio *bio)
  {
  	struct bio *n;
  	int r;
  
  	while (bio) {
  		n = bio->bi_next;
  		bio->bi_next = NULL;
  		r = do_origin(s->origin, bio);
  		if (r == DM_MAPIO_REMAPPED)
  			generic_make_request(bio);
  		bio = n;
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
  /*
   * Error a list of buffers.
   */
  static void error_bios(struct bio *bio)
  {
  	struct bio *n;
  
  	while (bio) {
  		n = bio->bi_next;
  		bio->bi_next = NULL;
6712ecf8f   NeilBrown   Drop 'size' argum...
1331
  		bio_io_error(bio);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1332
1333
1334
  		bio = n;
  	}
  }
695368ac3   Alasdair G Kergon   [PATCH] dm snapsh...
1335
  static void __invalidate_snapshot(struct dm_snapshot *s, int err)
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1336
1337
1338
1339
1340
1341
1342
1343
  {
  	if (!s->valid)
  		return;
  
  	if (err == -EIO)
  		DMERR("Invalidating snapshot: Error reading/writing.");
  	else if (err == -ENOMEM)
  		DMERR("Invalidating snapshot: Unable to allocate exception.");
493df71c6   Jonathan Brassow   dm exception stor...
1344
1345
  	if (s->store->type->drop_snapshot)
  		s->store->type->drop_snapshot(s->store);
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1346
1347
  
  	s->valid = 0;
fc56f6fbc   Mike Snitzer   dm snapshot: move...
1348
  	dm_table_event(s->ti->table);
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1349
  }
385277bfb   Mikulas Patocka   dm snapshot: fix ...
1350
  static void pending_complete(void *context, int success)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1351
  {
385277bfb   Mikulas Patocka   dm snapshot: fix ...
1352
  	struct dm_snap_pending_exception *pe = context;
1d4989c85   Jon Brassow   dm snapshot: rena...
1353
  	struct dm_exception *e;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1354
  	struct dm_snapshot *s = pe->snap;
9d493fa8c   Alasdair G Kergon   [PATCH] dm snapsh...
1355
1356
  	struct bio *origin_bios = NULL;
  	struct bio *snapshot_bios = NULL;
a6e50b409   Mikulas Patocka   dm snapshot: skip...
1357
  	struct bio *full_bio = NULL;
9d493fa8c   Alasdair G Kergon   [PATCH] dm snapsh...
1358
  	int error = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1359

76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1360
1361
  	if (!success) {
  		/* Read/write error - snapshot is unusable */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1362
  		down_write(&s->lock);
695368ac3   Alasdair G Kergon   [PATCH] dm snapsh...
1363
  		__invalidate_snapshot(s, -EIO);
9d493fa8c   Alasdair G Kergon   [PATCH] dm snapsh...
1364
  		error = 1;
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1365
1366
  		goto out;
  	}
119bc5473   Mikulas Patocka   dm snapshot: use ...
1367
  	e = alloc_completed_exception(GFP_NOIO);
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1368
  	if (!e) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1369
  		down_write(&s->lock);
695368ac3   Alasdair G Kergon   [PATCH] dm snapsh...
1370
  		__invalidate_snapshot(s, -ENOMEM);
9d493fa8c   Alasdair G Kergon   [PATCH] dm snapsh...
1371
  		error = 1;
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1372
1373
1374
  		goto out;
  	}
  	*e = pe->e;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1375

76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1376
1377
  	down_write(&s->lock);
  	if (!s->valid) {
3510cb94f   Jon Brassow   dm snapshot: rena...
1378
  		free_completed_exception(e);
9d493fa8c   Alasdair G Kergon   [PATCH] dm snapsh...
1379
  		error = 1;
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1380
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1381
  	}
615d1eb9c   Mike Snitzer   dm snapshot: crea...
1382
1383
  	/* Check for conflicting reads */
  	__check_for_conflicting_io(s, pe->e.old_chunk);
a8d41b59f   Mikulas Patocka   dm snapshot: fix ...
1384
1385
  
  	/*
9d493fa8c   Alasdair G Kergon   [PATCH] dm snapsh...
1386
1387
1388
  	 * Add a proper exception, and remove the
  	 * in-flight exception from the list.
  	 */
3510cb94f   Jon Brassow   dm snapshot: rena...
1389
  	dm_insert_exception(&s->complete, e);
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1390

a2d2b0345   Jonathan Brassow   dm snapshot: styl...
1391
  out:
3510cb94f   Jon Brassow   dm snapshot: rena...
1392
  	dm_remove_exception(&pe->e);
9d493fa8c   Alasdair G Kergon   [PATCH] dm snapsh...
1393
  	snapshot_bios = bio_list_get(&pe->snapshot_bios);
515ad66cc   Mikulas Patocka   dm snapshot: rewo...
1394
  	origin_bios = bio_list_get(&pe->origin_bios);
a6e50b409   Mikulas Patocka   dm snapshot: skip...
1395
  	full_bio = pe->full_bio;
fe3265b18   Mikulas Patocka   dm: don't save an...
1396
  	if (full_bio)
a6e50b409   Mikulas Patocka   dm snapshot: skip...
1397
  		full_bio->bi_end_io = pe->full_bio_end_io;
73dfd078c   Mikulas Patocka   dm snapshot: trig...
1398
  	increment_pending_exceptions_done_count();
9d493fa8c   Alasdair G Kergon   [PATCH] dm snapsh...
1399
1400
1401
  	up_write(&s->lock);
  
  	/* Submit any pending write bios */
a6e50b409   Mikulas Patocka   dm snapshot: skip...
1402
1403
1404
  	if (error) {
  		if (full_bio)
  			bio_io_error(full_bio);
9d493fa8c   Alasdair G Kergon   [PATCH] dm snapsh...
1405
  		error_bios(snapshot_bios);
a6e50b409   Mikulas Patocka   dm snapshot: skip...
1406
1407
  	} else {
  		if (full_bio)
4246a0b63   Christoph Hellwig   block: add a bi_e...
1408
  			bio_endio(full_bio);
9d493fa8c   Alasdair G Kergon   [PATCH] dm snapsh...
1409
  		flush_bios(snapshot_bios);
a6e50b409   Mikulas Patocka   dm snapshot: skip...
1410
  	}
9d493fa8c   Alasdair G Kergon   [PATCH] dm snapsh...
1411

515ad66cc   Mikulas Patocka   dm snapshot: rewo...
1412
  	retry_origin_bios(s, origin_bios);
22aa66a3e   Mikulas Patocka   dm snapshot: fix ...
1413
1414
  
  	free_pending_exception(pe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1415
  }
230c83afd   Mikulas Patocka   dm snapshot: avoi...
1416
1417
1418
  static void complete_exception(struct dm_snap_pending_exception *pe)
  {
  	struct dm_snapshot *s = pe->snap;
385277bfb   Mikulas Patocka   dm snapshot: fix ...
1419
1420
1421
  	/* Update the metadata if we are persistent */
  	s->store->type->commit_exception(s->store, &pe->e, !pe->copy_error,
  					 pending_complete, pe);
230c83afd   Mikulas Patocka   dm snapshot: avoi...
1422
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1423
1424
1425
1426
  /*
   * Called when the copy I/O has finished.  kcopyd actually runs
   * this code so don't block.
   */
4cdc1d1fa   Alasdair G Kergon   dm io: write erro...
1427
  static void copy_callback(int read_err, unsigned long write_err, void *context)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1428
  {
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
1429
  	struct dm_snap_pending_exception *pe = context;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1430
  	struct dm_snapshot *s = pe->snap;
230c83afd   Mikulas Patocka   dm snapshot: avoi...
1431
  	pe->copy_error = read_err || write_err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1432

230c83afd   Mikulas Patocka   dm snapshot: avoi...
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
  	if (pe->exception_sequence == s->exception_complete_sequence) {
  		s->exception_complete_sequence++;
  		complete_exception(pe);
  
  		while (!list_empty(&s->out_of_order_list)) {
  			pe = list_entry(s->out_of_order_list.next,
  					struct dm_snap_pending_exception, out_of_order_entry);
  			if (pe->exception_sequence != s->exception_complete_sequence)
  				break;
  			s->exception_complete_sequence++;
  			list_del(&pe->out_of_order_entry);
  			complete_exception(pe);
  		}
  	} else {
  		struct list_head *lh;
  		struct dm_snap_pending_exception *pe2;
  
  		list_for_each_prev(lh, &s->out_of_order_list) {
  			pe2 = list_entry(lh, struct dm_snap_pending_exception, out_of_order_entry);
  			if (pe2->exception_sequence < pe->exception_sequence)
  				break;
  		}
  		list_add(&pe->out_of_order_entry, lh);
  	}
8189ee479   Nikos Tsironis   dm snapshot: Fix ...
1457
  	up(&s->cow_count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1458
1459
1460
1461
1462
  }
  
  /*
   * Dispatches the copy operation to kcopyd.
   */
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
1463
  static void start_copy(struct dm_snap_pending_exception *pe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1464
1465
  {
  	struct dm_snapshot *s = pe->snap;
22a1ceb1e   Heinz Mauelshagen   dm io: clean inte...
1466
  	struct dm_io_region src, dest;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1467
1468
1469
1470
1471
1472
  	struct block_device *bdev = s->origin->bdev;
  	sector_t dev_size;
  
  	dev_size = get_dev_size(bdev);
  
  	src.bdev = bdev;
71fab00a6   Jonathan Brassow   dm snapshot: remo...
1473
  	src.sector = chunk_to_sector(s->store, pe->e.old_chunk);
df96eee67   Mikulas Patocka   dm snapshot: use ...
1474
  	src.count = min((sector_t)s->store->chunk_size, dev_size - src.sector);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1475

fc56f6fbc   Mike Snitzer   dm snapshot: move...
1476
  	dest.bdev = s->cow->bdev;
71fab00a6   Jonathan Brassow   dm snapshot: remo...
1477
  	dest.sector = chunk_to_sector(s->store, pe->e.new_chunk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1478
1479
1480
  	dest.count = src.count;
  
  	/* Hand over to kcopyd */
8189ee479   Nikos Tsironis   dm snapshot: Fix ...
1481
  	down(&s->cow_count);
a2d2b0345   Jonathan Brassow   dm snapshot: styl...
1482
  	dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, copy_callback, pe);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1483
  }
4246a0b63   Christoph Hellwig   block: add a bi_e...
1484
  static void full_bio_end_io(struct bio *bio)
a6e50b409   Mikulas Patocka   dm snapshot: skip...
1485
1486
  {
  	void *callback_data = bio->bi_private;
4e4cbee93   Christoph Hellwig   block: switch bio...
1487
  	dm_kcopyd_do_callback(callback_data, 0, bio->bi_status ? 1 : 0);
a6e50b409   Mikulas Patocka   dm snapshot: skip...
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
  }
  
  static void start_full_bio(struct dm_snap_pending_exception *pe,
  			   struct bio *bio)
  {
  	struct dm_snapshot *s = pe->snap;
  	void *callback_data;
  
  	pe->full_bio = bio;
  	pe->full_bio_end_io = bio->bi_end_io;
a6e50b409   Mikulas Patocka   dm snapshot: skip...
1498

8189ee479   Nikos Tsironis   dm snapshot: Fix ...
1499
  	down(&s->cow_count);
a6e50b409   Mikulas Patocka   dm snapshot: skip...
1500
1501
1502
1503
1504
1505
1506
1507
  	callback_data = dm_kcopyd_prepare_callback(s->kcopyd_client,
  						   copy_callback, pe);
  
  	bio->bi_end_io = full_bio_end_io;
  	bio->bi_private = callback_data;
  
  	generic_make_request(bio);
  }
2913808eb   Mikulas Patocka   dm snapshot: refa...
1508
1509
1510
  static struct dm_snap_pending_exception *
  __lookup_pending_exception(struct dm_snapshot *s, chunk_t chunk)
  {
3510cb94f   Jon Brassow   dm snapshot: rena...
1511
  	struct dm_exception *e = dm_lookup_exception(&s->pending, chunk);
2913808eb   Mikulas Patocka   dm snapshot: refa...
1512
1513
1514
1515
1516
1517
  
  	if (!e)
  		return NULL;
  
  	return container_of(e, struct dm_snap_pending_exception, e);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1518
1519
1520
1521
1522
1523
1524
1525
  /*
   * Looks to see if this snapshot already has a pending exception
   * for this chunk, otherwise it allocates a new one and inserts
   * it into the pending table.
   *
   * NOTE: a write lock must be held on snap->lock before calling
   * this.
   */
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
1526
  static struct dm_snap_pending_exception *
c66213921   Mikulas Patocka   dm snapshot: avoi...
1527
1528
  __find_pending_exception(struct dm_snapshot *s,
  			 struct dm_snap_pending_exception *pe, chunk_t chunk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1529
  {
c66213921   Mikulas Patocka   dm snapshot: avoi...
1530
  	struct dm_snap_pending_exception *pe2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1531

2913808eb   Mikulas Patocka   dm snapshot: refa...
1532
1533
  	pe2 = __lookup_pending_exception(s, chunk);
  	if (pe2) {
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1534
  		free_pending_exception(pe);
2913808eb   Mikulas Patocka   dm snapshot: refa...
1535
  		return pe2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1536
  	}
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1537
1538
1539
  	pe->e.old_chunk = chunk;
  	bio_list_init(&pe->origin_bios);
  	bio_list_init(&pe->snapshot_bios);
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1540
  	pe->started = 0;
a6e50b409   Mikulas Patocka   dm snapshot: skip...
1541
  	pe->full_bio = NULL;
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1542

493df71c6   Jonathan Brassow   dm exception stor...
1543
  	if (s->store->type->prepare_exception(s->store, &pe->e)) {
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1544
1545
1546
  		free_pending_exception(pe);
  		return NULL;
  	}
230c83afd   Mikulas Patocka   dm snapshot: avoi...
1547
  	pe->exception_sequence = s->exception_start_sequence++;
3510cb94f   Jon Brassow   dm snapshot: rena...
1548
  	dm_insert_exception(&s->pending, &pe->e);
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1549

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1550
1551
  	return pe;
  }
1d4989c85   Jon Brassow   dm snapshot: rena...
1552
  static void remap_exception(struct dm_snapshot *s, struct dm_exception *e,
d74f81f8a   Milan Broz   dm snapshot: comb...
1553
  			    struct bio *bio, chunk_t chunk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1554
  {
74d46992e   Christoph Hellwig   block: replace bi...
1555
  	bio_set_dev(bio, s->cow->bdev);
4f024f379   Kent Overstreet   block: Abstract o...
1556
1557
1558
1559
  	bio->bi_iter.bi_sector =
  		chunk_to_sector(s->store, dm_chunk_number(e->new_chunk) +
  				(chunk - e->old_chunk)) +
  		(bio->bi_iter.bi_sector & s->store->chunk_mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1560
  }
7de3ee57d   Mikulas Patocka   dm: remove map_info
1561
  static int snapshot_map(struct dm_target *ti, struct bio *bio)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1562
  {
1d4989c85   Jon Brassow   dm snapshot: rena...
1563
  	struct dm_exception *e;
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
1564
  	struct dm_snapshot *s = ti->private;
d2a7ad29a   Kiyoshi Ueda   [PATCH] dm: map a...
1565
  	int r = DM_MAPIO_REMAPPED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1566
  	chunk_t chunk;
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
1567
  	struct dm_snap_pending_exception *pe = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1568

ee18026ac   Mikulas Patocka   dm snapshot: do n...
1569
  	init_tracked_chunk(bio);
1eff9d322   Jens Axboe   block: rename bio...
1570
  	if (bio->bi_opf & REQ_PREFLUSH) {
74d46992e   Christoph Hellwig   block: replace bi...
1571
  		bio_set_dev(bio, s->cow->bdev);
494b3ee7d   Mikulas Patocka   dm snapshot: supp...
1572
1573
  		return DM_MAPIO_REMAPPED;
  	}
4f024f379   Kent Overstreet   block: Abstract o...
1574
  	chunk = sector_to_chunk(s->store, bio->bi_iter.bi_sector);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1575
1576
  
  	/* Full snapshots are not usable */
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1577
  	/* To get here the table must be live so s->active is always set. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1578
  	if (!s->valid)
846785e6a   Christoph Hellwig   dm: don't return ...
1579
  		return DM_MAPIO_KILL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1580

ba40a2aa6   Alasdair G Kergon   [PATCH] dm snapsh...
1581
1582
1583
  	/* FIXME: should only take write lock if we need
  	 * to copy an exception */
  	down_write(&s->lock);
70246286e   Christoph Hellwig   block: get rid of...
1584
1585
  	if (!s->valid || (unlikely(s->snapshot_overflowed) &&
  	    bio_data_dir(bio) == WRITE)) {
846785e6a   Christoph Hellwig   dm: don't return ...
1586
  		r = DM_MAPIO_KILL;
ba40a2aa6   Alasdair G Kergon   [PATCH] dm snapsh...
1587
1588
1589
1590
  		goto out_unlock;
  	}
  
  	/* If the block is already remapped - use that, else remap it */
3510cb94f   Jon Brassow   dm snapshot: rena...
1591
  	e = dm_lookup_exception(&s->complete, chunk);
ba40a2aa6   Alasdair G Kergon   [PATCH] dm snapsh...
1592
  	if (e) {
d74f81f8a   Milan Broz   dm snapshot: comb...
1593
  		remap_exception(s, e, bio, chunk);
ba40a2aa6   Alasdair G Kergon   [PATCH] dm snapsh...
1594
1595
  		goto out_unlock;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1596
1597
1598
1599
1600
  	/*
  	 * Write to snapshot - higher level takes care of RW/RO
  	 * flags so we should only get this if we are
  	 * writeable.
  	 */
70246286e   Christoph Hellwig   block: get rid of...
1601
  	if (bio_data_dir(bio) == WRITE) {
2913808eb   Mikulas Patocka   dm snapshot: refa...
1602
  		pe = __lookup_pending_exception(s, chunk);
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1603
  		if (!pe) {
c66213921   Mikulas Patocka   dm snapshot: avoi...
1604
1605
1606
  			up_write(&s->lock);
  			pe = alloc_pending_exception(s);
  			down_write(&s->lock);
76c44f6d8   Mikulas Patocka   dm snapshot: don'...
1607
  			if (!s->valid || s->snapshot_overflowed) {
c66213921   Mikulas Patocka   dm snapshot: avoi...
1608
  				free_pending_exception(pe);
846785e6a   Christoph Hellwig   dm: don't return ...
1609
  				r = DM_MAPIO_KILL;
c66213921   Mikulas Patocka   dm snapshot: avoi...
1610
1611
  				goto out_unlock;
  			}
3510cb94f   Jon Brassow   dm snapshot: rena...
1612
  			e = dm_lookup_exception(&s->complete, chunk);
35bf659b0   Mikulas Patocka   dm snapshot: avoi...
1613
1614
1615
1616
1617
  			if (e) {
  				free_pending_exception(pe);
  				remap_exception(s, e, bio, chunk);
  				goto out_unlock;
  			}
c66213921   Mikulas Patocka   dm snapshot: avoi...
1618
  			pe = __find_pending_exception(s, pe, chunk);
2913808eb   Mikulas Patocka   dm snapshot: refa...
1619
  			if (!pe) {
b0d3cc011   Mike Snitzer   dm snapshot: add ...
1620
1621
1622
1623
1624
  				if (s->store->userspace_supports_overflow) {
  					s->snapshot_overflowed = 1;
  					DMERR("Snapshot overflowed: Unable to allocate exception.");
  				} else
  					__invalidate_snapshot(s, -ENOMEM);
846785e6a   Christoph Hellwig   dm: don't return ...
1625
  				r = DM_MAPIO_KILL;
2913808eb   Mikulas Patocka   dm snapshot: refa...
1626
1627
  				goto out_unlock;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1628
  		}
d74f81f8a   Milan Broz   dm snapshot: comb...
1629
  		remap_exception(s, &pe->e, bio, chunk);
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1630

d2a7ad29a   Kiyoshi Ueda   [PATCH] dm: map a...
1631
  		r = DM_MAPIO_SUBMITTED;
ba40a2aa6   Alasdair G Kergon   [PATCH] dm snapsh...
1632

a6e50b409   Mikulas Patocka   dm snapshot: skip...
1633
  		if (!pe->started &&
4f024f379   Kent Overstreet   block: Abstract o...
1634
1635
  		    bio->bi_iter.bi_size ==
  		    (s->store->chunk_size << SECTOR_SHIFT)) {
a6e50b409   Mikulas Patocka   dm snapshot: skip...
1636
1637
1638
1639
1640
1641
1642
  			pe->started = 1;
  			up_write(&s->lock);
  			start_full_bio(pe, bio);
  			goto out;
  		}
  
  		bio_list_add(&pe->snapshot_bios, bio);
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1643
1644
1645
  		if (!pe->started) {
  			/* this is protected by snap->lock */
  			pe->started = 1;
ba40a2aa6   Alasdair G Kergon   [PATCH] dm snapsh...
1646
  			up_write(&s->lock);
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1647
  			start_copy(pe);
ba40a2aa6   Alasdair G Kergon   [PATCH] dm snapsh...
1648
1649
  			goto out;
  		}
cd45daffd   Mikulas Patocka   dm snapshot: trac...
1650
  	} else {
74d46992e   Christoph Hellwig   block: replace bi...
1651
  		bio_set_dev(bio, s->origin->bdev);
ee18026ac   Mikulas Patocka   dm snapshot: do n...
1652
  		track_chunk(s, bio, chunk);
cd45daffd   Mikulas Patocka   dm snapshot: trac...
1653
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1654

a2d2b0345   Jonathan Brassow   dm snapshot: styl...
1655
  out_unlock:
ba40a2aa6   Alasdair G Kergon   [PATCH] dm snapsh...
1656
  	up_write(&s->lock);
a2d2b0345   Jonathan Brassow   dm snapshot: styl...
1657
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1658
1659
  	return r;
  }
3452c2a1e   Mikulas Patocka   dm snapshot: avoi...
1660
1661
1662
1663
1664
1665
1666
1667
1668
  /*
   * A snapshot-merge target behaves like a combination of a snapshot
   * target and a snapshot-origin target.  It only generates new
   * exceptions in other snapshots and not in the one that is being
   * merged.
   *
   * For each chunk, if there is an existing exception, it is used to
   * redirect I/O to the cow device.  Otherwise I/O is sent to the origin,
   * which in turn might generate exceptions in other snapshots.
9fe862548   Mikulas Patocka   dm snapshot: queu...
1669
1670
   * If merging is currently taking place on the chunk in question, the
   * I/O is deferred by adding it to s->bios_queued_during_merge.
3452c2a1e   Mikulas Patocka   dm snapshot: avoi...
1671
   */
7de3ee57d   Mikulas Patocka   dm: remove map_info
1672
  static int snapshot_merge_map(struct dm_target *ti, struct bio *bio)
3452c2a1e   Mikulas Patocka   dm snapshot: avoi...
1673
1674
1675
1676
1677
  {
  	struct dm_exception *e;
  	struct dm_snapshot *s = ti->private;
  	int r = DM_MAPIO_REMAPPED;
  	chunk_t chunk;
ee18026ac   Mikulas Patocka   dm snapshot: do n...
1678
  	init_tracked_chunk(bio);
1eff9d322   Jens Axboe   block: rename bio...
1679
  	if (bio->bi_opf & REQ_PREFLUSH) {
55a62eef8   Alasdair G Kergon   dm: rename reques...
1680
  		if (!dm_bio_get_target_bio_nr(bio))
74d46992e   Christoph Hellwig   block: replace bi...
1681
  			bio_set_dev(bio, s->origin->bdev);
10b8106a7   Mike Snitzer   dm snapshot: supp...
1682
  		else
74d46992e   Christoph Hellwig   block: replace bi...
1683
  			bio_set_dev(bio, s->cow->bdev);
10b8106a7   Mike Snitzer   dm snapshot: supp...
1684
1685
  		return DM_MAPIO_REMAPPED;
  	}
4f024f379   Kent Overstreet   block: Abstract o...
1686
  	chunk = sector_to_chunk(s->store, bio->bi_iter.bi_sector);
3452c2a1e   Mikulas Patocka   dm snapshot: avoi...
1687

9fe862548   Mikulas Patocka   dm snapshot: queu...
1688
  	down_write(&s->lock);
3452c2a1e   Mikulas Patocka   dm snapshot: avoi...
1689

d2fdb776e   Mikulas Patocka   dm snapshot: use ...
1690
1691
1692
  	/* Full merging snapshots are redirected to the origin */
  	if (!s->valid)
  		goto redirect_to_origin;
3452c2a1e   Mikulas Patocka   dm snapshot: avoi...
1693
1694
1695
1696
  
  	/* If the block is already remapped - use that */
  	e = dm_lookup_exception(&s->complete, chunk);
  	if (e) {
9fe862548   Mikulas Patocka   dm snapshot: queu...
1697
  		/* Queue writes overlapping with chunks being merged */
70246286e   Christoph Hellwig   block: get rid of...
1698
  		if (bio_data_dir(bio) == WRITE &&
9fe862548   Mikulas Patocka   dm snapshot: queu...
1699
1700
1701
  		    chunk >= s->first_merging_chunk &&
  		    chunk < (s->first_merging_chunk +
  			     s->num_merging_chunks)) {
74d46992e   Christoph Hellwig   block: replace bi...
1702
  			bio_set_dev(bio, s->origin->bdev);
9fe862548   Mikulas Patocka   dm snapshot: queu...
1703
1704
1705
1706
  			bio_list_add(&s->bios_queued_during_merge, bio);
  			r = DM_MAPIO_SUBMITTED;
  			goto out_unlock;
  		}
17aa03326   Mikulas Patocka   dm snapshot: dela...
1707

3452c2a1e   Mikulas Patocka   dm snapshot: avoi...
1708
  		remap_exception(s, e, bio, chunk);
17aa03326   Mikulas Patocka   dm snapshot: dela...
1709

70246286e   Christoph Hellwig   block: get rid of...
1710
  		if (bio_data_dir(bio) == WRITE)
ee18026ac   Mikulas Patocka   dm snapshot: do n...
1711
  			track_chunk(s, bio, chunk);
3452c2a1e   Mikulas Patocka   dm snapshot: avoi...
1712
1713
  		goto out_unlock;
  	}
d2fdb776e   Mikulas Patocka   dm snapshot: use ...
1714
  redirect_to_origin:
74d46992e   Christoph Hellwig   block: replace bi...
1715
  	bio_set_dev(bio, s->origin->bdev);
3452c2a1e   Mikulas Patocka   dm snapshot: avoi...
1716

70246286e   Christoph Hellwig   block: get rid of...
1717
  	if (bio_data_dir(bio) == WRITE) {
9fe862548   Mikulas Patocka   dm snapshot: queu...
1718
  		up_write(&s->lock);
3452c2a1e   Mikulas Patocka   dm snapshot: avoi...
1719
1720
1721
1722
  		return do_origin(s->origin, bio);
  	}
  
  out_unlock:
9fe862548   Mikulas Patocka   dm snapshot: queu...
1723
  	up_write(&s->lock);
3452c2a1e   Mikulas Patocka   dm snapshot: avoi...
1724
1725
1726
  
  	return r;
  }
4e4cbee93   Christoph Hellwig   block: switch bio...
1727
1728
  static int snapshot_end_io(struct dm_target *ti, struct bio *bio,
  		blk_status_t *error)
cd45daffd   Mikulas Patocka   dm snapshot: trac...
1729
1730
  {
  	struct dm_snapshot *s = ti->private;
cd45daffd   Mikulas Patocka   dm snapshot: trac...
1731

ee18026ac   Mikulas Patocka   dm snapshot: do n...
1732
1733
  	if (is_bio_tracked(bio))
  		stop_tracking_chunk(s, bio);
cd45daffd   Mikulas Patocka   dm snapshot: trac...
1734

1be569098   Christoph Hellwig   dm: change ->end_...
1735
  	return DM_ENDIO_DONE;
cd45daffd   Mikulas Patocka   dm snapshot: trac...
1736
  }
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
1737
1738
1739
1740
1741
1742
  static void snapshot_merge_presuspend(struct dm_target *ti)
  {
  	struct dm_snapshot *s = ti->private;
  
  	stop_merge(s);
  }
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1743
1744
1745
1746
1747
1748
1749
  static int snapshot_preresume(struct dm_target *ti)
  {
  	int r = 0;
  	struct dm_snapshot *s = ti->private;
  	struct dm_snapshot *snap_src = NULL, *snap_dest = NULL;
  
  	down_read(&_origins_lock);
9d3b15c4c   Mikulas Patocka   dm snapshot: perm...
1750
  	(void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL);
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1751
1752
1753
1754
1755
1756
  	if (snap_src && snap_dest) {
  		down_read(&snap_src->lock);
  		if (s == snap_src) {
  			DMERR("Unable to resume snapshot source until "
  			      "handover completes.");
  			r = -EINVAL;
b83b2f295   Mike Snitzer   dm snapshot: avoi...
1757
  		} else if (!dm_suspended(snap_src->ti)) {
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
  			DMERR("Unable to perform snapshot handover until "
  			      "source is suspended.");
  			r = -EINVAL;
  		}
  		up_read(&snap_src->lock);
  	}
  	up_read(&_origins_lock);
  
  	return r;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1768
1769
  static void snapshot_resume(struct dm_target *ti)
  {
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
1770
  	struct dm_snapshot *s = ti->private;
09ee96b21   Mikulas Patocka   dm snapshot: susp...
1771
  	struct dm_snapshot *snap_src = NULL, *snap_dest = NULL, *snap_merging = NULL;
b735fede8   Mikulas Patocka   dm snapshot: susp...
1772
1773
  	struct dm_origin *o;
  	struct mapped_device *origin_md = NULL;
09ee96b21   Mikulas Patocka   dm snapshot: susp...
1774
  	bool must_restart_merging = false;
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1775
1776
  
  	down_read(&_origins_lock);
b735fede8   Mikulas Patocka   dm snapshot: susp...
1777
1778
1779
1780
  
  	o = __lookup_dm_origin(s->origin->bdev);
  	if (o)
  		origin_md = dm_table_get_md(o->ti->table);
09ee96b21   Mikulas Patocka   dm snapshot: susp...
1781
1782
1783
1784
1785
  	if (!origin_md) {
  		(void) __find_snapshots_sharing_cow(s, NULL, NULL, &snap_merging);
  		if (snap_merging)
  			origin_md = dm_table_get_md(snap_merging->ti->table);
  	}
b735fede8   Mikulas Patocka   dm snapshot: susp...
1786
1787
  	if (origin_md == dm_table_get_md(ti->table))
  		origin_md = NULL;
09ee96b21   Mikulas Patocka   dm snapshot: susp...
1788
1789
1790
1791
  	if (origin_md) {
  		if (dm_hold(origin_md))
  			origin_md = NULL;
  	}
b735fede8   Mikulas Patocka   dm snapshot: susp...
1792

09ee96b21   Mikulas Patocka   dm snapshot: susp...
1793
1794
1795
  	up_read(&_origins_lock);
  
  	if (origin_md) {
b735fede8   Mikulas Patocka   dm snapshot: susp...
1796
  		dm_internal_suspend_fast(origin_md);
09ee96b21   Mikulas Patocka   dm snapshot: susp...
1797
1798
1799
1800
1801
1802
1803
  		if (snap_merging && test_bit(RUNNING_MERGE, &snap_merging->state_bits)) {
  			must_restart_merging = true;
  			stop_merge(snap_merging);
  		}
  	}
  
  	down_read(&_origins_lock);
b735fede8   Mikulas Patocka   dm snapshot: susp...
1804

9d3b15c4c   Mikulas Patocka   dm snapshot: perm...
1805
  	(void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL);
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1806
1807
1808
1809
1810
1811
1812
  	if (snap_src && snap_dest) {
  		down_write(&snap_src->lock);
  		down_write_nested(&snap_dest->lock, SINGLE_DEPTH_NESTING);
  		__handover_exceptions(snap_src, snap_dest);
  		up_write(&snap_dest->lock);
  		up_write(&snap_src->lock);
  	}
b735fede8   Mikulas Patocka   dm snapshot: susp...
1813

c1f0c183f   Mike Snitzer   dm snapshot: allo...
1814
  	up_read(&_origins_lock);
09ee96b21   Mikulas Patocka   dm snapshot: susp...
1815
1816
1817
1818
1819
1820
  	if (origin_md) {
  		if (must_restart_merging)
  			start_merge(snap_merging);
  		dm_internal_resume_fast(origin_md);
  		dm_put(origin_md);
  	}
c1f0c183f   Mike Snitzer   dm snapshot: allo...
1821
1822
  	/* Now we have correct chunk size, reregister */
  	reregister_snapshot(s);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1823

aa14edeb9   Alasdair G Kergon   [PATCH] device-ma...
1824
1825
1826
  	down_write(&s->lock);
  	s->active = 1;
  	up_write(&s->lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1827
  }
542f90381   Mike Snitzer   dm: support non p...
1828
  static uint32_t get_origin_minimum_chunksize(struct block_device *bdev)
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
1829
  {
542f90381   Mike Snitzer   dm: support non p...
1830
  	uint32_t min_chunksize;
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
  
  	down_read(&_origins_lock);
  	min_chunksize = __minimum_chunk_size(__lookup_origin(bdev));
  	up_read(&_origins_lock);
  
  	return min_chunksize;
  }
  
  static void snapshot_merge_resume(struct dm_target *ti)
  {
  	struct dm_snapshot *s = ti->private;
  
  	/*
  	 * Handover exceptions from existing snapshot.
  	 */
  	snapshot_resume(ti);
  
  	/*
542f90381   Mike Snitzer   dm: support non p...
1849
  	 * snapshot-merge acts as an origin, so set ti->max_io_len
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
1850
  	 */
542f90381   Mike Snitzer   dm: support non p...
1851
  	ti->max_io_len = get_origin_minimum_chunksize(s->origin->bdev);
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
1852
1853
1854
  
  	start_merge(s);
  }
fd7c092e7   Mikulas Patocka   dm: fix truncated...
1855
1856
  static void snapshot_status(struct dm_target *ti, status_type_t type,
  			    unsigned status_flags, char *result, unsigned maxlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1857
  {
2e4a31df2   Jonathan Brassow   dm snapshot: use ...
1858
  	unsigned sz = 0;
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
1859
  	struct dm_snapshot *snap = ti->private;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1860
1861
1862
  
  	switch (type) {
  	case STATUSTYPE_INFO:
94e76572b   Mikulas Patocka   dm snapshot: only...
1863
1864
  
  		down_write(&snap->lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1865
  		if (!snap->valid)
2e4a31df2   Jonathan Brassow   dm snapshot: use ...
1866
  			DMEMIT("Invalid");
d8ddb1cff   Mike Snitzer   dm snapshot: repo...
1867
1868
  		else if (snap->merge_failed)
  			DMEMIT("Merge failed");
76c44f6d8   Mikulas Patocka   dm snapshot: don'...
1869
1870
  		else if (snap->snapshot_overflowed)
  			DMEMIT("Overflow");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1871
  		else {
985903bb3   Mike Snitzer   dm snapshot: add ...
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
  			if (snap->store->type->usage) {
  				sector_t total_sectors, sectors_allocated,
  					 metadata_sectors;
  				snap->store->type->usage(snap->store,
  							 &total_sectors,
  							 &sectors_allocated,
  							 &metadata_sectors);
  				DMEMIT("%llu/%llu %llu",
  				       (unsigned long long)sectors_allocated,
  				       (unsigned long long)total_sectors,
  				       (unsigned long long)metadata_sectors);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1883
1884
  			}
  			else
2e4a31df2   Jonathan Brassow   dm snapshot: use ...
1885
  				DMEMIT("Unknown");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1886
  		}
94e76572b   Mikulas Patocka   dm snapshot: only...
1887
1888
  
  		up_write(&snap->lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1889
1890
1891
1892
1893
1894
1895
1896
  		break;
  
  	case STATUSTYPE_TABLE:
  		/*
  		 * kdevname returns a static pointer so we need
  		 * to make private copies if the output is to
  		 * make sense.
  		 */
fc56f6fbc   Mike Snitzer   dm snapshot: move...
1897
  		DMEMIT("%s %s", snap->origin->name, snap->cow->name);
1e302a929   Jonathan Brassow   dm snapshot: move...
1898
1899
  		snap->store->type->status(snap->store, type, result + sz,
  					  maxlen - sz);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1900
1901
  		break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1902
  }
8811f46c1   Mike Snitzer   dm snapshot: impl...
1903
1904
1905
1906
  static int snapshot_iterate_devices(struct dm_target *ti,
  				    iterate_devices_callout_fn fn, void *data)
  {
  	struct dm_snapshot *snap = ti->private;
1e5554c84   Mikulas Patocka   dm snapshot: iter...
1907
1908
1909
  	int r;
  
  	r = fn(ti, snap->origin, 0, ti->len, data);
8811f46c1   Mike Snitzer   dm snapshot: impl...
1910

1e5554c84   Mikulas Patocka   dm snapshot: iter...
1911
1912
1913
1914
  	if (!r)
  		r = fn(ti, snap->cow, 0, get_dev_size(snap->cow->bdev), data);
  
  	return r;
8811f46c1   Mike Snitzer   dm snapshot: impl...
1915
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1916
1917
1918
  /*-----------------------------------------------------------------
   * Origin methods
   *---------------------------------------------------------------*/
9eaae8ffb   Mikulas Patocka   dm snapshot: make...
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
  
  /*
   * If no exceptions need creating, DM_MAPIO_REMAPPED is returned and any
   * supplied bio was ignored.  The caller may submit it immediately.
   * (No remapping actually occurs as the origin is always a direct linear
   * map.)
   *
   * If further exceptions are required, DM_MAPIO_SUBMITTED is returned
   * and any supplied bio is added to a list to be submitted once all
   * the necessary exceptions exist.
   */
  static int __origin_write(struct list_head *snapshots, sector_t sector,
  			  struct bio *bio)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1932
  {
515ad66cc   Mikulas Patocka   dm snapshot: rewo...
1933
  	int r = DM_MAPIO_REMAPPED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1934
  	struct dm_snapshot *snap;
1d4989c85   Jon Brassow   dm snapshot: rena...
1935
  	struct dm_exception *e;
515ad66cc   Mikulas Patocka   dm snapshot: rewo...
1936
1937
1938
  	struct dm_snap_pending_exception *pe;
  	struct dm_snap_pending_exception *pe_to_start_now = NULL;
  	struct dm_snap_pending_exception *pe_to_start_last = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1939
1940
1941
1942
  	chunk_t chunk;
  
  	/* Do all the snapshots on this origin */
  	list_for_each_entry (snap, snapshots, list) {
3452c2a1e   Mikulas Patocka   dm snapshot: avoi...
1943
1944
1945
1946
1947
1948
  		/*
  		 * Don't make new exceptions in a merging snapshot
  		 * because it has effectively been deleted
  		 */
  		if (dm_target_is_snapshot_merge(snap->ti))
  			continue;
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1949
  		down_write(&snap->lock);
aa14edeb9   Alasdair G Kergon   [PATCH] device-ma...
1950
1951
  		/* Only deal with valid and active snapshots */
  		if (!snap->valid || !snap->active)
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1952
  			goto next_snapshot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1953

d5e404c10   Alasdair G Kergon   [PATCH] device-ma...
1954
  		/* Nothing to do if writing beyond end of snapshot */
9eaae8ffb   Mikulas Patocka   dm snapshot: make...
1955
  		if (sector >= dm_table_get_size(snap->ti->table))
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1956
  			goto next_snapshot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1957
1958
1959
1960
1961
  
  		/*
  		 * Remember, different snapshots can have
  		 * different chunk sizes.
  		 */
9eaae8ffb   Mikulas Patocka   dm snapshot: make...
1962
  		chunk = sector_to_chunk(snap->store, sector);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1963
1964
1965
1966
1967
1968
  
  		/*
  		 * Check exception table to see if block
  		 * is already remapped in this snapshot
  		 * and trigger an exception if not.
  		 */
3510cb94f   Jon Brassow   dm snapshot: rena...
1969
  		e = dm_lookup_exception(&snap->complete, chunk);
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1970
1971
  		if (e)
  			goto next_snapshot;
2913808eb   Mikulas Patocka   dm snapshot: refa...
1972
  		pe = __lookup_pending_exception(snap, chunk);
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1973
  		if (!pe) {
c66213921   Mikulas Patocka   dm snapshot: avoi...
1974
1975
1976
1977
1978
1979
1980
1981
  			up_write(&snap->lock);
  			pe = alloc_pending_exception(snap);
  			down_write(&snap->lock);
  
  			if (!snap->valid) {
  				free_pending_exception(pe);
  				goto next_snapshot;
  			}
3510cb94f   Jon Brassow   dm snapshot: rena...
1982
  			e = dm_lookup_exception(&snap->complete, chunk);
35bf659b0   Mikulas Patocka   dm snapshot: avoi...
1983
1984
1985
1986
  			if (e) {
  				free_pending_exception(pe);
  				goto next_snapshot;
  			}
c66213921   Mikulas Patocka   dm snapshot: avoi...
1987
  			pe = __find_pending_exception(snap, pe, chunk);
2913808eb   Mikulas Patocka   dm snapshot: refa...
1988
1989
1990
1991
  			if (!pe) {
  				__invalidate_snapshot(snap, -ENOMEM);
  				goto next_snapshot;
  			}
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1992
  		}
515ad66cc   Mikulas Patocka   dm snapshot: rewo...
1993
  		r = DM_MAPIO_SUBMITTED;
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
1994

515ad66cc   Mikulas Patocka   dm snapshot: rewo...
1995
1996
1997
1998
1999
2000
2001
2002
  		/*
  		 * If an origin bio was supplied, queue it to wait for the
  		 * completion of this exception, and start this one last,
  		 * at the end of the function.
  		 */
  		if (bio) {
  			bio_list_add(&pe->origin_bios, bio);
  			bio = NULL;
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
2003

515ad66cc   Mikulas Patocka   dm snapshot: rewo...
2004
2005
2006
2007
  			if (!pe->started) {
  				pe->started = 1;
  				pe_to_start_last = pe;
  			}
76df1c651   Alasdair G Kergon   [PATCH] device-ma...
2008
2009
2010
2011
  		}
  
  		if (!pe->started) {
  			pe->started = 1;
515ad66cc   Mikulas Patocka   dm snapshot: rewo...
2012
  			pe_to_start_now = pe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2013
  		}
a2d2b0345   Jonathan Brassow   dm snapshot: styl...
2014
  next_snapshot:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2015
  		up_write(&snap->lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2016

515ad66cc   Mikulas Patocka   dm snapshot: rewo...
2017
2018
2019
2020
  		if (pe_to_start_now) {
  			start_copy(pe_to_start_now);
  			pe_to_start_now = NULL;
  		}
b4b610f68   Alasdair G Kergon   [PATCH] device-ma...
2021
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2022
  	/*
515ad66cc   Mikulas Patocka   dm snapshot: rewo...
2023
2024
  	 * Submit the exception against which the bio is queued last,
  	 * to give the other exceptions a head start.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2025
  	 */
515ad66cc   Mikulas Patocka   dm snapshot: rewo...
2026
2027
  	if (pe_to_start_last)
  		start_copy(pe_to_start_last);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
  
  	return r;
  }
  
  /*
   * Called on a write from the origin driver.
   */
  static int do_origin(struct dm_dev *origin, struct bio *bio)
  {
  	struct origin *o;
d2a7ad29a   Kiyoshi Ueda   [PATCH] dm: map a...
2038
  	int r = DM_MAPIO_REMAPPED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2039
2040
2041
2042
  
  	down_read(&_origins_lock);
  	o = __lookup_origin(origin->bdev);
  	if (o)
4f024f379   Kent Overstreet   block: Abstract o...
2043
  		r = __origin_write(&o->snapshots, bio->bi_iter.bi_sector, bio);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2044
2045
2046
2047
2048
2049
  	up_read(&_origins_lock);
  
  	return r;
  }
  
  /*
73dfd078c   Mikulas Patocka   dm snapshot: trig...
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
   * Trigger exceptions in all non-merging snapshots.
   *
   * The chunk size of the merging snapshot may be larger than the chunk
   * size of some other snapshot so we may need to reallocate multiple
   * chunks in other snapshots.
   *
   * We scan all the overlapping exceptions in the other snapshots.
   * Returns 1 if anything was reallocated and must be waited for,
   * otherwise returns 0.
   *
   * size must be a multiple of merging_snap's chunk_size.
   */
  static int origin_write_extent(struct dm_snapshot *merging_snap,
  			       sector_t sector, unsigned size)
  {
  	int must_wait = 0;
  	sector_t n;
  	struct origin *o;
  
  	/*
542f90381   Mike Snitzer   dm: support non p...
2070
  	 * The origin's __minimum_chunk_size() got stored in max_io_len
73dfd078c   Mikulas Patocka   dm snapshot: trig...
2071
2072
2073
2074
  	 * by snapshot_merge_resume().
  	 */
  	down_read(&_origins_lock);
  	o = __lookup_origin(merging_snap->origin->bdev);
542f90381   Mike Snitzer   dm: support non p...
2075
  	for (n = 0; n < size; n += merging_snap->ti->max_io_len)
73dfd078c   Mikulas Patocka   dm snapshot: trig...
2076
2077
2078
2079
2080
2081
2082
2083
2084
  		if (__origin_write(&o->snapshots, sector + n, NULL) ==
  		    DM_MAPIO_SUBMITTED)
  			must_wait = 1;
  	up_read(&_origins_lock);
  
  	return must_wait;
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
   * Origin: maps a linear range of a device, with hooks for snapshotting.
   */
  
  /*
   * Construct an origin mapping: <dev_path>
   * The context for an origin is merely a 'struct dm_dev *'
   * pointing to the real device.
   */
  static int origin_ctr(struct dm_target *ti, unsigned int argc, char **argv)
  {
  	int r;
599cdf3bf   Mikulas Patocka   dm snapshot: allo...
2096
  	struct dm_origin *o;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2097
2098
  
  	if (argc != 1) {
72d948616   Alasdair G Kergon   [PATCH] dm: impro...
2099
  		ti->error = "origin: incorrect number of arguments";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2100
2101
  		return -EINVAL;
  	}
599cdf3bf   Mikulas Patocka   dm snapshot: allo...
2102
2103
2104
2105
2106
2107
2108
2109
  	o = kmalloc(sizeof(struct dm_origin), GFP_KERNEL);
  	if (!o) {
  		ti->error = "Cannot allocate private origin structure";
  		r = -ENOMEM;
  		goto bad_alloc;
  	}
  
  	r = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &o->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2110
2111
  	if (r) {
  		ti->error = "Cannot get target device";
599cdf3bf   Mikulas Patocka   dm snapshot: allo...
2112
  		goto bad_open;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2113
  	}
b735fede8   Mikulas Patocka   dm snapshot: susp...
2114
  	o->ti = ti;
599cdf3bf   Mikulas Patocka   dm snapshot: allo...
2115
  	ti->private = o;
55a62eef8   Alasdair G Kergon   dm: rename reques...
2116
  	ti->num_flush_bios = 1;
494b3ee7d   Mikulas Patocka   dm snapshot: supp...
2117

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2118
  	return 0;
599cdf3bf   Mikulas Patocka   dm snapshot: allo...
2119
2120
2121
2122
2123
  
  bad_open:
  	kfree(o);
  bad_alloc:
  	return r;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2124
2125
2126
2127
  }
  
  static void origin_dtr(struct dm_target *ti)
  {
599cdf3bf   Mikulas Patocka   dm snapshot: allo...
2128
  	struct dm_origin *o = ti->private;
b735fede8   Mikulas Patocka   dm snapshot: susp...
2129

599cdf3bf   Mikulas Patocka   dm snapshot: allo...
2130
2131
  	dm_put_device(ti, o->dev);
  	kfree(o);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2132
  }
7de3ee57d   Mikulas Patocka   dm: remove map_info
2133
  static int origin_map(struct dm_target *ti, struct bio *bio)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2134
  {
599cdf3bf   Mikulas Patocka   dm snapshot: allo...
2135
  	struct dm_origin *o = ti->private;
298eaa89b   Mikulas Patocka   dm snapshot: do n...
2136
  	unsigned available_sectors;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2137

74d46992e   Christoph Hellwig   block: replace bi...
2138
  	bio_set_dev(bio, o->dev->bdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2139

1eff9d322   Jens Axboe   block: rename bio...
2140
  	if (unlikely(bio->bi_opf & REQ_PREFLUSH))
494b3ee7d   Mikulas Patocka   dm snapshot: supp...
2141
  		return DM_MAPIO_REMAPPED;
70246286e   Christoph Hellwig   block: get rid of...
2142
  	if (bio_data_dir(bio) != WRITE)
494b3ee7d   Mikulas Patocka   dm snapshot: supp...
2143
  		return DM_MAPIO_REMAPPED;
298eaa89b   Mikulas Patocka   dm snapshot: do n...
2144
2145
2146
2147
2148
  	available_sectors = o->split_boundary -
  		((unsigned)bio->bi_iter.bi_sector & (o->split_boundary - 1));
  
  	if (bio_sectors(bio) > available_sectors)
  		dm_accept_partial_bio(bio, available_sectors);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2149
  	/* Only tell snapshots if this is a write */
298eaa89b   Mikulas Patocka   dm snapshot: do n...
2150
  	return do_origin(o->dev, bio);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2151
  }
817bf4026   Dan Williams   dm: teach dm-targ...
2152
2153
  static long origin_dax_direct_access(struct dm_target *ti, pgoff_t pgoff,
  		long nr_pages, void **kaddr, pfn_t *pfn)
f6e629bd2   Toshi Kani   dm snap: add fake...
2154
2155
2156
2157
  {
  	DMWARN("device does not support dax.");
  	return -EIO;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2158
  /*
542f90381   Mike Snitzer   dm: support non p...
2159
   * Set the target "max_io_len" field to the minimum of all the snapshots'
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2160
2161
2162
2163
   * chunk sizes.
   */
  static void origin_resume(struct dm_target *ti)
  {
599cdf3bf   Mikulas Patocka   dm snapshot: allo...
2164
  	struct dm_origin *o = ti->private;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2165

298eaa89b   Mikulas Patocka   dm snapshot: do n...
2166
  	o->split_boundary = get_origin_minimum_chunksize(o->dev->bdev);
b735fede8   Mikulas Patocka   dm snapshot: susp...
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
  
  	down_write(&_origins_lock);
  	__insert_dm_origin(o);
  	up_write(&_origins_lock);
  }
  
  static void origin_postsuspend(struct dm_target *ti)
  {
  	struct dm_origin *o = ti->private;
  
  	down_write(&_origins_lock);
  	__remove_dm_origin(o);
  	up_write(&_origins_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2180
  }
fd7c092e7   Mikulas Patocka   dm: fix truncated...
2181
2182
  static void origin_status(struct dm_target *ti, status_type_t type,
  			  unsigned status_flags, char *result, unsigned maxlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2183
  {
599cdf3bf   Mikulas Patocka   dm snapshot: allo...
2184
  	struct dm_origin *o = ti->private;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2185
2186
2187
2188
2189
2190
2191
  
  	switch (type) {
  	case STATUSTYPE_INFO:
  		result[0] = '\0';
  		break;
  
  	case STATUSTYPE_TABLE:
599cdf3bf   Mikulas Patocka   dm snapshot: allo...
2192
  		snprintf(result, maxlen, "%s", o->dev->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2193
2194
  		break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2195
  }
8811f46c1   Mike Snitzer   dm snapshot: impl...
2196
2197
2198
  static int origin_iterate_devices(struct dm_target *ti,
  				  iterate_devices_callout_fn fn, void *data)
  {
599cdf3bf   Mikulas Patocka   dm snapshot: allo...
2199
  	struct dm_origin *o = ti->private;
8811f46c1   Mike Snitzer   dm snapshot: impl...
2200

599cdf3bf   Mikulas Patocka   dm snapshot: allo...
2201
  	return fn(ti, o->dev, 0, ti->len, data);
8811f46c1   Mike Snitzer   dm snapshot: impl...
2202
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2203
2204
  static struct target_type origin_target = {
  	.name    = "snapshot-origin",
b735fede8   Mikulas Patocka   dm snapshot: susp...
2205
  	.version = {1, 9, 0},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2206
2207
2208
2209
2210
  	.module  = THIS_MODULE,
  	.ctr     = origin_ctr,
  	.dtr     = origin_dtr,
  	.map     = origin_map,
  	.resume  = origin_resume,
b735fede8   Mikulas Patocka   dm snapshot: susp...
2211
  	.postsuspend = origin_postsuspend,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2212
  	.status  = origin_status,
8811f46c1   Mike Snitzer   dm snapshot: impl...
2213
  	.iterate_devices = origin_iterate_devices,
817bf4026   Dan Williams   dm: teach dm-targ...
2214
  	.direct_access = origin_dax_direct_access,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2215
2216
2217
2218
  };
  
  static struct target_type snapshot_target = {
  	.name    = "snapshot",
b0d3cc011   Mike Snitzer   dm snapshot: add ...
2219
  	.version = {1, 15, 0},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2220
2221
2222
2223
  	.module  = THIS_MODULE,
  	.ctr     = snapshot_ctr,
  	.dtr     = snapshot_dtr,
  	.map     = snapshot_map,
cd45daffd   Mikulas Patocka   dm snapshot: trac...
2224
  	.end_io  = snapshot_end_io,
c1f0c183f   Mike Snitzer   dm snapshot: allo...
2225
  	.preresume  = snapshot_preresume,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2226
2227
  	.resume  = snapshot_resume,
  	.status  = snapshot_status,
8811f46c1   Mike Snitzer   dm snapshot: impl...
2228
  	.iterate_devices = snapshot_iterate_devices,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2229
  };
d698aa450   Mikulas Patocka   dm snapshot: add ...
2230
2231
  static struct target_type merge_target = {
  	.name    = dm_snapshot_merge_target_name,
b0d3cc011   Mike Snitzer   dm snapshot: add ...
2232
  	.version = {1, 4, 0},
d698aa450   Mikulas Patocka   dm snapshot: add ...
2233
2234
2235
  	.module  = THIS_MODULE,
  	.ctr     = snapshot_ctr,
  	.dtr     = snapshot_dtr,
3452c2a1e   Mikulas Patocka   dm snapshot: avoi...
2236
  	.map     = snapshot_merge_map,
d698aa450   Mikulas Patocka   dm snapshot: add ...
2237
  	.end_io  = snapshot_end_io,
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
2238
  	.presuspend = snapshot_merge_presuspend,
d698aa450   Mikulas Patocka   dm snapshot: add ...
2239
  	.preresume  = snapshot_preresume,
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
2240
  	.resume  = snapshot_merge_resume,
d698aa450   Mikulas Patocka   dm snapshot: add ...
2241
2242
2243
  	.status  = snapshot_status,
  	.iterate_devices = snapshot_iterate_devices,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2244
2245
2246
  static int __init dm_snapshot_init(void)
  {
  	int r;
4db6bfe02   Alasdair G Kergon   dm snapshot: spli...
2247
2248
2249
2250
2251
  	r = dm_exception_store_init();
  	if (r) {
  		DMERR("Failed to initialize exception stores");
  		return r;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2252
2253
2254
  	r = init_origin_hash();
  	if (r) {
  		DMERR("init_origin_hash failed.");
d698aa450   Mikulas Patocka   dm snapshot: add ...
2255
  		goto bad_origin_hash;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2256
  	}
1d4989c85   Jon Brassow   dm snapshot: rena...
2257
  	exception_cache = KMEM_CACHE(dm_exception, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2258
2259
2260
  	if (!exception_cache) {
  		DMERR("Couldn't create exception cache.");
  		r = -ENOMEM;
d698aa450   Mikulas Patocka   dm snapshot: add ...
2261
  		goto bad_exception_cache;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2262
  	}
028867ac2   Alasdair G Kergon   dm: use kmem_cach...
2263
  	pending_cache = KMEM_CACHE(dm_snap_pending_exception, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2264
2265
2266
  	if (!pending_cache) {
  		DMERR("Couldn't create pending cache.");
  		r = -ENOMEM;
d698aa450   Mikulas Patocka   dm snapshot: add ...
2267
  		goto bad_pending_cache;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2268
  	}
fbce429b4   monty_pavel@sina.com   dm: fix various t...
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
  	r = dm_register_target(&snapshot_target);
  	if (r < 0) {
  		DMERR("snapshot target register failed %d", r);
  		goto bad_register_snapshot_target;
  	}
  
  	r = dm_register_target(&origin_target);
  	if (r < 0) {
  		DMERR("Origin target register failed %d", r);
  		goto bad_register_origin_target;
  	}
  
  	r = dm_register_target(&merge_target);
  	if (r < 0) {
  		DMERR("Merge target register failed %d", r);
  		goto bad_register_merge_target;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2286
  	return 0;
d698aa450   Mikulas Patocka   dm snapshot: add ...
2287
  bad_register_merge_target:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2288
  	dm_unregister_target(&origin_target);
d698aa450   Mikulas Patocka   dm snapshot: add ...
2289
  bad_register_origin_target:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2290
  	dm_unregister_target(&snapshot_target);
034a186d2   Jonathan Brassow   dm snapshot: free...
2291
  bad_register_snapshot_target:
fbce429b4   monty_pavel@sina.com   dm: fix various t...
2292
2293
2294
2295
2296
2297
  	kmem_cache_destroy(pending_cache);
  bad_pending_cache:
  	kmem_cache_destroy(exception_cache);
  bad_exception_cache:
  	exit_origin_hash();
  bad_origin_hash:
034a186d2   Jonathan Brassow   dm snapshot: free...
2298
  	dm_exception_store_exit();
d698aa450   Mikulas Patocka   dm snapshot: add ...
2299

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2300
2301
2302
2303
2304
  	return r;
  }
  
  static void __exit dm_snapshot_exit(void)
  {
10d3bd09a   Mikulas Patocka   dm: consolidate t...
2305
2306
  	dm_unregister_target(&snapshot_target);
  	dm_unregister_target(&origin_target);
d698aa450   Mikulas Patocka   dm snapshot: add ...
2307
  	dm_unregister_target(&merge_target);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2308
2309
  
  	exit_origin_hash();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2310
2311
  	kmem_cache_destroy(pending_cache);
  	kmem_cache_destroy(exception_cache);
4db6bfe02   Alasdair G Kergon   dm snapshot: spli...
2312
2313
  
  	dm_exception_store_exit();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2314
2315
2316
2317
2318
2319
2320
2321
2322
  }
  
  /* Module hooks */
  module_init(dm_snapshot_init);
  module_exit(dm_snapshot_exit);
  
  MODULE_DESCRIPTION(DM_NAME " snapshot target");
  MODULE_AUTHOR("Joe Thornber");
  MODULE_LICENSE("GPL");
23cb21092   Mikulas Patocka   dm snapshot: add ...
2323
2324
  MODULE_ALIAS("dm-snapshot-origin");
  MODULE_ALIAS("dm-snapshot-merge");