1aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow/*
2aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
3aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
4aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow *
5aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * Device-mapper snapshot exception store.
6aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow *
7aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * This file is released under the GPL.
8aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow */
9aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
10aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow#ifndef _LINUX_DM_EXCEPTION_STORE
11aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow#define _LINUX_DM_EXCEPTION_STORE
12aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
13aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow#include <linux/blkdev.h>
14a159c1ac5f33c6cf0f5aa3c9d1ccdc82c907ee46Jonathan Brassow#include <linux/device-mapper.h>
15aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
16aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow/*
17aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * The snapshot code deals with largish chunks of the disk at a
18aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * time. Typically 32k - 512k.
19aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow */
20aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassowtypedef sector_t chunk_t;
21aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
22aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow/*
23aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * An exception is used where an old chunk of data has been
24aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * replaced by a new one.
25aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * If chunk_t is 64 bits in size, the top 8 bits of new_chunk hold the number
26aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * of chunks that follow contiguously.  Remaining bits hold the number of the
27aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * chunk within the device.
28aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow */
291d4989c858093bda0426be536fc7f9c415857836Jon Brassowstruct dm_exception {
30aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	struct list_head hash_list;
31aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
32aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	chunk_t old_chunk;
33aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	chunk_t new_chunk;
34aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow};
35aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
36aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow/*
37aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * Abstraction to handle the meta/layout of exception stores (the
38aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * COW device).
39aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow */
40b2a114652940ccf7e9668ad447ca78bf16a31139Jonathan Brassowstruct dm_exception_store;
41b2a114652940ccf7e9668ad447ca78bf16a31139Jonathan Brassowstruct dm_exception_store_type {
42493df71c6420b211a68ae82b889c1e8a5fe701beJonathan Brassow	const char *name;
43493df71c6420b211a68ae82b889c1e8a5fe701beJonathan Brassow	struct module *module;
44493df71c6420b211a68ae82b889c1e8a5fe701beJonathan Brassow
45b2a114652940ccf7e9668ad447ca78bf16a31139Jonathan Brassow	int (*ctr) (struct dm_exception_store *store,
46b2a114652940ccf7e9668ad447ca78bf16a31139Jonathan Brassow		    unsigned argc, char **argv);
47b2a114652940ccf7e9668ad447ca78bf16a31139Jonathan Brassow
48aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	/*
49aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	 * Destroys this object when you've finished with it.
50aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	 */
51b2a114652940ccf7e9668ad447ca78bf16a31139Jonathan Brassow	void (*dtr) (struct dm_exception_store *store);
52aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
53aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	/*
54aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	 * The target shouldn't read the COW device until this is
55a159c1ac5f33c6cf0f5aa3c9d1ccdc82c907ee46Jonathan Brassow	 * called.  As exceptions are read from the COW, they are
56a159c1ac5f33c6cf0f5aa3c9d1ccdc82c907ee46Jonathan Brassow	 * reported back via the callback.
57aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	 */
58a159c1ac5f33c6cf0f5aa3c9d1ccdc82c907ee46Jonathan Brassow	int (*read_metadata) (struct dm_exception_store *store,
59a159c1ac5f33c6cf0f5aa3c9d1ccdc82c907ee46Jonathan Brassow			      int (*callback)(void *callback_context,
60a159c1ac5f33c6cf0f5aa3c9d1ccdc82c907ee46Jonathan Brassow					      chunk_t old, chunk_t new),
61a159c1ac5f33c6cf0f5aa3c9d1ccdc82c907ee46Jonathan Brassow			      void *callback_context);
62aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
63aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	/*
64aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	 * Find somewhere to store the next exception.
65aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	 */
661ae25f9c933d1432fbffdf3e126051a974608abfJonathan Brassow	int (*prepare_exception) (struct dm_exception_store *store,
671d4989c858093bda0426be536fc7f9c415857836Jon Brassow				  struct dm_exception *e);
68aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
69aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	/*
70aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	 * Update the metadata with this exception.
71aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	 */
721ae25f9c933d1432fbffdf3e126051a974608abfJonathan Brassow	void (*commit_exception) (struct dm_exception_store *store,
731d4989c858093bda0426be536fc7f9c415857836Jon Brassow				  struct dm_exception *e,
74aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow				  void (*callback) (void *, int success),
75aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow				  void *callback_context);
76aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
77aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	/*
784454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	 * Returns 0 if the exception store is empty.
794454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	 *
804454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	 * If there are exceptions still to be merged, sets
814454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	 * *last_old_chunk and *last_new_chunk to the most recent
824454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	 * still-to-be-merged chunk and returns the number of
834454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	 * consecutive previous ones.
844454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	 */
854454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	int (*prepare_merge) (struct dm_exception_store *store,
864454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka			      chunk_t *last_old_chunk, chunk_t *last_new_chunk);
874454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka
884454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	/*
894454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	 * Clear the last n exceptions.
904454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	 * nr_merged must be <= the value returned by prepare_merge.
914454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	 */
924454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	int (*commit_merge) (struct dm_exception_store *store, int nr_merged);
934454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka
944454a6216f75a9ef8c4bd0a65e34b101f725ef1eMikulas Patocka	/*
95aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	 * The snapshot is invalid, note this in the metadata.
96aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	 */
971ae25f9c933d1432fbffdf3e126051a974608abfJonathan Brassow	void (*drop_snapshot) (struct dm_exception_store *store);
98aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
991e302a929e2da6e8448e2058e4b07b07252b57feJonathan Brassow	unsigned (*status) (struct dm_exception_store *store,
1001e302a929e2da6e8448e2058e4b07b07252b57feJonathan Brassow			    status_type_t status, char *result,
1011e302a929e2da6e8448e2058e4b07b07252b57feJonathan Brassow			    unsigned maxlen);
102a159c1ac5f33c6cf0f5aa3c9d1ccdc82c907ee46Jonathan Brassow
103aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	/*
104aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	 * Return how full the snapshot is.
105aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	 */
106985903bb3a6d98623360ab6c855417f638840029Mike Snitzer	void (*usage) (struct dm_exception_store *store,
107985903bb3a6d98623360ab6c855417f638840029Mike Snitzer		       sector_t *total_sectors, sector_t *sectors_allocated,
108985903bb3a6d98623360ab6c855417f638840029Mike Snitzer		       sector_t *metadata_sectors);
109493df71c6420b211a68ae82b889c1e8a5fe701beJonathan Brassow
110493df71c6420b211a68ae82b889c1e8a5fe701beJonathan Brassow	/* For internal device-mapper use only. */
111493df71c6420b211a68ae82b889c1e8a5fe701beJonathan Brassow	struct list_head list;
112b2a114652940ccf7e9668ad447ca78bf16a31139Jonathan Brassow};
113b2a114652940ccf7e9668ad447ca78bf16a31139Jonathan Brassow
114fc56f6fbcca3672c63c93c65f45105faacfc13cbMike Snitzerstruct dm_snapshot;
115fc56f6fbcca3672c63c93c65f45105faacfc13cbMike Snitzer
116b2a114652940ccf7e9668ad447ca78bf16a31139Jonathan Brassowstruct dm_exception_store {
117493df71c6420b211a68ae82b889c1e8a5fe701beJonathan Brassow	struct dm_exception_store_type *type;
118fc56f6fbcca3672c63c93c65f45105faacfc13cbMike Snitzer	struct dm_snapshot *snap;
11949beb2b87a972a994ff77633234ca3bf0d30a1d8Jonathan Brassow
120d0216849519bec8dc96301a3cd80316e71243839Jonathan Brassow	/* Size of data blocks saved - must be a power of 2 */
121df96eee679ba28c98cf722fa7c9f4286ee1ed0bdMikulas Patocka	unsigned chunk_size;
122df96eee679ba28c98cf722fa7c9f4286ee1ed0bdMikulas Patocka	unsigned chunk_mask;
123df96eee679ba28c98cf722fa7c9f4286ee1ed0bdMikulas Patocka	unsigned chunk_shift;
124d0216849519bec8dc96301a3cd80316e71243839Jonathan Brassow
125aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	void *context;
126aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow};
127aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
128aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow/*
129c24110450650f17f7d3ba4fbe01f01ac5a115456Mikulas Patocka * Obtain the origin or cow device used by a given snapshot.
130fc56f6fbcca3672c63c93c65f45105faacfc13cbMike Snitzer */
131c24110450650f17f7d3ba4fbe01f01ac5a115456Mikulas Patockastruct dm_dev *dm_snap_origin(struct dm_snapshot *snap);
132fc56f6fbcca3672c63c93c65f45105faacfc13cbMike Snitzerstruct dm_dev *dm_snap_cow(struct dm_snapshot *snap);
133fc56f6fbcca3672c63c93c65f45105faacfc13cbMike Snitzer
134fc56f6fbcca3672c63c93c65f45105faacfc13cbMike Snitzer/*
135aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * Funtions to manipulate consecutive chunks
136aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow */
13790c699a9ee4be165966d40f1837909ccb8890a68Bartlomiej Zolnierkiewicz#  if defined(CONFIG_LBDAF) || (BITS_PER_LONG == 64)
138aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow#    define DM_CHUNK_CONSECUTIVE_BITS 8
139aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow#    define DM_CHUNK_NUMBER_BITS 56
140aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
141aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassowstatic inline chunk_t dm_chunk_number(chunk_t chunk)
142aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow{
143aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	return chunk & (chunk_t)((1ULL << DM_CHUNK_NUMBER_BITS) - 1ULL);
144aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow}
145aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
1461d4989c858093bda0426be536fc7f9c415857836Jon Brassowstatic inline unsigned dm_consecutive_chunk_count(struct dm_exception *e)
147aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow{
148aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	return e->new_chunk >> DM_CHUNK_NUMBER_BITS;
149aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow}
150aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
1511d4989c858093bda0426be536fc7f9c415857836Jon Brassowstatic inline void dm_consecutive_chunk_count_inc(struct dm_exception *e)
152aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow{
153aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	e->new_chunk += (1ULL << DM_CHUNK_NUMBER_BITS);
154aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
155aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	BUG_ON(!dm_consecutive_chunk_count(e));
156aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow}
157aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
1581e03f97e4301f75a2f3b649787f7876516764929Mikulas Patockastatic inline void dm_consecutive_chunk_count_dec(struct dm_exception *e)
1591e03f97e4301f75a2f3b649787f7876516764929Mikulas Patocka{
1601e03f97e4301f75a2f3b649787f7876516764929Mikulas Patocka	BUG_ON(!dm_consecutive_chunk_count(e));
1611e03f97e4301f75a2f3b649787f7876516764929Mikulas Patocka
1621e03f97e4301f75a2f3b649787f7876516764929Mikulas Patocka	e->new_chunk -= (1ULL << DM_CHUNK_NUMBER_BITS);
1631e03f97e4301f75a2f3b649787f7876516764929Mikulas Patocka}
1641e03f97e4301f75a2f3b649787f7876516764929Mikulas Patocka
165aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow#  else
166aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow#    define DM_CHUNK_CONSECUTIVE_BITS 0
167aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
168aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassowstatic inline chunk_t dm_chunk_number(chunk_t chunk)
169aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow{
170aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	return chunk;
171aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow}
172aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
1731d4989c858093bda0426be536fc7f9c415857836Jon Brassowstatic inline unsigned dm_consecutive_chunk_count(struct dm_exception *e)
174aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow{
175aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow	return 0;
176aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow}
177aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
1781d4989c858093bda0426be536fc7f9c415857836Jon Brassowstatic inline void dm_consecutive_chunk_count_inc(struct dm_exception *e)
179aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow{
180aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow}
181aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
1821e03f97e4301f75a2f3b649787f7876516764929Mikulas Patockastatic inline void dm_consecutive_chunk_count_dec(struct dm_exception *e)
1831e03f97e4301f75a2f3b649787f7876516764929Mikulas Patocka{
1841e03f97e4301f75a2f3b649787f7876516764929Mikulas Patocka}
1851e03f97e4301f75a2f3b649787f7876516764929Mikulas Patocka
186aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow#  endif
187aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow
18871fab00a6bef7fb53119271a8abdbaf40970d28aJonathan Brassow/*
18971fab00a6bef7fb53119271a8abdbaf40970d28aJonathan Brassow * Return the number of sectors in the device.
19071fab00a6bef7fb53119271a8abdbaf40970d28aJonathan Brassow */
19171fab00a6bef7fb53119271a8abdbaf40970d28aJonathan Brassowstatic inline sector_t get_dev_size(struct block_device *bdev)
19271fab00a6bef7fb53119271a8abdbaf40970d28aJonathan Brassow{
1935657e8fa45cf230df278040c420fb80e06309d8fMikulas Patocka	return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
19471fab00a6bef7fb53119271a8abdbaf40970d28aJonathan Brassow}
19571fab00a6bef7fb53119271a8abdbaf40970d28aJonathan Brassow
19671fab00a6bef7fb53119271a8abdbaf40970d28aJonathan Brassowstatic inline chunk_t sector_to_chunk(struct dm_exception_store *store,
19771fab00a6bef7fb53119271a8abdbaf40970d28aJonathan Brassow				      sector_t sector)
19871fab00a6bef7fb53119271a8abdbaf40970d28aJonathan Brassow{
199102c6ddb1d081a6a1fede38c43a42c9811313ec7Mikulas Patocka	return sector >> store->chunk_shift;
20071fab00a6bef7fb53119271a8abdbaf40970d28aJonathan Brassow}
20171fab00a6bef7fb53119271a8abdbaf40970d28aJonathan Brassow
202493df71c6420b211a68ae82b889c1e8a5fe701beJonathan Brassowint dm_exception_store_type_register(struct dm_exception_store_type *type);
203493df71c6420b211a68ae82b889c1e8a5fe701beJonathan Brassowint dm_exception_store_type_unregister(struct dm_exception_store_type *type);
204493df71c6420b211a68ae82b889c1e8a5fe701beJonathan Brassow
2052defcc3fb4661e7351cb2ac48d843efc4c64db13Mikulas Patockaint dm_exception_store_set_chunk_size(struct dm_exception_store *store,
206df96eee679ba28c98cf722fa7c9f4286ee1ed0bdMikulas Patocka				      unsigned chunk_size,
2072defcc3fb4661e7351cb2ac48d843efc4c64db13Mikulas Patocka				      char **error);
2082defcc3fb4661e7351cb2ac48d843efc4c64db13Mikulas Patocka
209fee1998e9c690f9920671e1e0ef187a48cfbbde4Jonathan Brassowint dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
210fc56f6fbcca3672c63c93c65f45105faacfc13cbMike Snitzer			      struct dm_snapshot *snap,
211fee1998e9c690f9920671e1e0ef187a48cfbbde4Jonathan Brassow			      unsigned *args_used,
212493df71c6420b211a68ae82b889c1e8a5fe701beJonathan Brassow			      struct dm_exception_store **store);
213493df71c6420b211a68ae82b889c1e8a5fe701beJonathan Brassowvoid dm_exception_store_destroy(struct dm_exception_store *store);
214493df71c6420b211a68ae82b889c1e8a5fe701beJonathan Brassow
2154db6bfe02bdc7dc5048f46dd682a94801d029adcAlasdair G Kergonint dm_exception_store_init(void);
2164db6bfe02bdc7dc5048f46dd682a94801d029adcAlasdair G Kergonvoid dm_exception_store_exit(void);
2174db6bfe02bdc7dc5048f46dd682a94801d029adcAlasdair G Kergon
218aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow/*
219aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow * Two exception store implementations.
220aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow */
2214db6bfe02bdc7dc5048f46dd682a94801d029adcAlasdair G Kergonint dm_persistent_snapshot_init(void);
2224db6bfe02bdc7dc5048f46dd682a94801d029adcAlasdair G Kergonvoid dm_persistent_snapshot_exit(void);
2234db6bfe02bdc7dc5048f46dd682a94801d029adcAlasdair G Kergon
2244db6bfe02bdc7dc5048f46dd682a94801d029adcAlasdair G Kergonint dm_transient_snapshot_init(void);
2254db6bfe02bdc7dc5048f46dd682a94801d029adcAlasdair G Kergonvoid dm_transient_snapshot_exit(void);
2264db6bfe02bdc7dc5048f46dd682a94801d029adcAlasdair G Kergon
227aea53d92f70eeb00ae480e399a997dd55fd5055dJonathan Brassow#endif /* _LINUX_DM_EXCEPTION_STORE */
228