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