1aea53d92SJonathan Brassow /* 2aea53d92SJonathan Brassow * Copyright (C) 2001-2002 Sistina Software (UK) Limited. 3aea53d92SJonathan Brassow * Copyright (C) 2008 Red Hat, Inc. All rights reserved. 4aea53d92SJonathan Brassow * 5aea53d92SJonathan Brassow * Device-mapper snapshot exception store. 6aea53d92SJonathan Brassow * 7aea53d92SJonathan Brassow * This file is released under the GPL. 8aea53d92SJonathan Brassow */ 9aea53d92SJonathan Brassow 10aea53d92SJonathan Brassow #ifndef _LINUX_DM_EXCEPTION_STORE 11aea53d92SJonathan Brassow #define _LINUX_DM_EXCEPTION_STORE 12aea53d92SJonathan Brassow 13aea53d92SJonathan Brassow #include <linux/blkdev.h> 14a159c1acSJonathan Brassow #include <linux/device-mapper.h> 15aea53d92SJonathan Brassow 16aea53d92SJonathan Brassow /* 17aea53d92SJonathan Brassow * The snapshot code deals with largish chunks of the disk at a 18aea53d92SJonathan Brassow * time. Typically 32k - 512k. 19aea53d92SJonathan Brassow */ 20aea53d92SJonathan Brassow typedef sector_t chunk_t; 21aea53d92SJonathan Brassow 22aea53d92SJonathan Brassow /* 23aea53d92SJonathan Brassow * An exception is used where an old chunk of data has been 24aea53d92SJonathan Brassow * replaced by a new one. 25aea53d92SJonathan Brassow * If chunk_t is 64 bits in size, the top 8 bits of new_chunk hold the number 26aea53d92SJonathan Brassow * of chunks that follow contiguously. Remaining bits hold the number of the 27aea53d92SJonathan Brassow * chunk within the device. 28aea53d92SJonathan Brassow */ 291d4989c8SJon Brassow struct dm_exception { 30aea53d92SJonathan Brassow struct list_head hash_list; 31aea53d92SJonathan Brassow 32aea53d92SJonathan Brassow chunk_t old_chunk; 33aea53d92SJonathan Brassow chunk_t new_chunk; 34aea53d92SJonathan Brassow }; 35aea53d92SJonathan Brassow 36aea53d92SJonathan Brassow /* 37aea53d92SJonathan Brassow * Abstraction to handle the meta/layout of exception stores (the 38aea53d92SJonathan Brassow * COW device). 39aea53d92SJonathan Brassow */ 40b2a11465SJonathan Brassow struct dm_exception_store; 41b2a11465SJonathan Brassow struct dm_exception_store_type { 42493df71cSJonathan Brassow const char *name; 43493df71cSJonathan Brassow struct module *module; 44493df71cSJonathan Brassow 45b2a11465SJonathan Brassow int (*ctr) (struct dm_exception_store *store, 46b2a11465SJonathan Brassow unsigned argc, char **argv); 47b2a11465SJonathan Brassow 48aea53d92SJonathan Brassow /* 49aea53d92SJonathan Brassow * Destroys this object when you've finished with it. 50aea53d92SJonathan Brassow */ 51b2a11465SJonathan Brassow void (*dtr) (struct dm_exception_store *store); 52aea53d92SJonathan Brassow 53aea53d92SJonathan Brassow /* 54aea53d92SJonathan Brassow * The target shouldn't read the COW device until this is 55a159c1acSJonathan Brassow * called. As exceptions are read from the COW, they are 56a159c1acSJonathan Brassow * reported back via the callback. 57aea53d92SJonathan Brassow */ 58a159c1acSJonathan Brassow int (*read_metadata) (struct dm_exception_store *store, 59a159c1acSJonathan Brassow int (*callback)(void *callback_context, 60a159c1acSJonathan Brassow chunk_t old, chunk_t new), 61a159c1acSJonathan Brassow void *callback_context); 62aea53d92SJonathan Brassow 63aea53d92SJonathan Brassow /* 64aea53d92SJonathan Brassow * Find somewhere to store the next exception. 65aea53d92SJonathan Brassow */ 661ae25f9cSJonathan Brassow int (*prepare_exception) (struct dm_exception_store *store, 671d4989c8SJon Brassow struct dm_exception *e); 68aea53d92SJonathan Brassow 69aea53d92SJonathan Brassow /* 70aea53d92SJonathan Brassow * Update the metadata with this exception. 71aea53d92SJonathan Brassow */ 721ae25f9cSJonathan Brassow void (*commit_exception) (struct dm_exception_store *store, 731d4989c8SJon Brassow struct dm_exception *e, 74aea53d92SJonathan Brassow void (*callback) (void *, int success), 75aea53d92SJonathan Brassow void *callback_context); 76aea53d92SJonathan Brassow 77aea53d92SJonathan Brassow /* 78aea53d92SJonathan Brassow * The snapshot is invalid, note this in the metadata. 79aea53d92SJonathan Brassow */ 801ae25f9cSJonathan Brassow void (*drop_snapshot) (struct dm_exception_store *store); 81aea53d92SJonathan Brassow 821e302a92SJonathan Brassow unsigned (*status) (struct dm_exception_store *store, 831e302a92SJonathan Brassow status_type_t status, char *result, 841e302a92SJonathan Brassow unsigned maxlen); 85a159c1acSJonathan Brassow 86aea53d92SJonathan Brassow /* 87aea53d92SJonathan Brassow * Return how full the snapshot is. 88aea53d92SJonathan Brassow */ 89985903bbSMike Snitzer void (*usage) (struct dm_exception_store *store, 90985903bbSMike Snitzer sector_t *total_sectors, sector_t *sectors_allocated, 91985903bbSMike Snitzer sector_t *metadata_sectors); 92493df71cSJonathan Brassow 93493df71cSJonathan Brassow /* For internal device-mapper use only. */ 94493df71cSJonathan Brassow struct list_head list; 95b2a11465SJonathan Brassow }; 96b2a11465SJonathan Brassow 97*fc56f6fbSMike Snitzer struct dm_snapshot; 98*fc56f6fbSMike Snitzer 99b2a11465SJonathan Brassow struct dm_exception_store { 100493df71cSJonathan Brassow struct dm_exception_store_type *type; 101*fc56f6fbSMike Snitzer struct dm_snapshot *snap; 10249beb2b8SJonathan Brassow 103d0216849SJonathan Brassow /* Size of data blocks saved - must be a power of 2 */ 104df96eee6SMikulas Patocka unsigned chunk_size; 105df96eee6SMikulas Patocka unsigned chunk_mask; 106df96eee6SMikulas Patocka unsigned chunk_shift; 107d0216849SJonathan Brassow 108aea53d92SJonathan Brassow void *context; 109aea53d92SJonathan Brassow }; 110aea53d92SJonathan Brassow 111aea53d92SJonathan Brassow /* 112*fc56f6fbSMike Snitzer * Obtain the cow device used by a given snapshot. 113*fc56f6fbSMike Snitzer */ 114*fc56f6fbSMike Snitzer struct dm_dev *dm_snap_cow(struct dm_snapshot *snap); 115*fc56f6fbSMike Snitzer 116*fc56f6fbSMike Snitzer /* 117aea53d92SJonathan Brassow * Funtions to manipulate consecutive chunks 118aea53d92SJonathan Brassow */ 11990c699a9SBartlomiej Zolnierkiewicz # if defined(CONFIG_LBDAF) || (BITS_PER_LONG == 64) 120aea53d92SJonathan Brassow # define DM_CHUNK_CONSECUTIVE_BITS 8 121aea53d92SJonathan Brassow # define DM_CHUNK_NUMBER_BITS 56 122aea53d92SJonathan Brassow 123aea53d92SJonathan Brassow static inline chunk_t dm_chunk_number(chunk_t chunk) 124aea53d92SJonathan Brassow { 125aea53d92SJonathan Brassow return chunk & (chunk_t)((1ULL << DM_CHUNK_NUMBER_BITS) - 1ULL); 126aea53d92SJonathan Brassow } 127aea53d92SJonathan Brassow 1281d4989c8SJon Brassow static inline unsigned dm_consecutive_chunk_count(struct dm_exception *e) 129aea53d92SJonathan Brassow { 130aea53d92SJonathan Brassow return e->new_chunk >> DM_CHUNK_NUMBER_BITS; 131aea53d92SJonathan Brassow } 132aea53d92SJonathan Brassow 1331d4989c8SJon Brassow static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e) 134aea53d92SJonathan Brassow { 135aea53d92SJonathan Brassow e->new_chunk += (1ULL << DM_CHUNK_NUMBER_BITS); 136aea53d92SJonathan Brassow 137aea53d92SJonathan Brassow BUG_ON(!dm_consecutive_chunk_count(e)); 138aea53d92SJonathan Brassow } 139aea53d92SJonathan Brassow 140aea53d92SJonathan Brassow # else 141aea53d92SJonathan Brassow # define DM_CHUNK_CONSECUTIVE_BITS 0 142aea53d92SJonathan Brassow 143aea53d92SJonathan Brassow static inline chunk_t dm_chunk_number(chunk_t chunk) 144aea53d92SJonathan Brassow { 145aea53d92SJonathan Brassow return chunk; 146aea53d92SJonathan Brassow } 147aea53d92SJonathan Brassow 1481d4989c8SJon Brassow static inline unsigned dm_consecutive_chunk_count(struct dm_exception *e) 149aea53d92SJonathan Brassow { 150aea53d92SJonathan Brassow return 0; 151aea53d92SJonathan Brassow } 152aea53d92SJonathan Brassow 1531d4989c8SJon Brassow static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e) 154aea53d92SJonathan Brassow { 155aea53d92SJonathan Brassow } 156aea53d92SJonathan Brassow 157aea53d92SJonathan Brassow # endif 158aea53d92SJonathan Brassow 15971fab00aSJonathan Brassow /* 16071fab00aSJonathan Brassow * Return the number of sectors in the device. 16171fab00aSJonathan Brassow */ 16271fab00aSJonathan Brassow static inline sector_t get_dev_size(struct block_device *bdev) 16371fab00aSJonathan Brassow { 1645657e8faSMikulas Patocka return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; 16571fab00aSJonathan Brassow } 16671fab00aSJonathan Brassow 16771fab00aSJonathan Brassow static inline chunk_t sector_to_chunk(struct dm_exception_store *store, 16871fab00aSJonathan Brassow sector_t sector) 16971fab00aSJonathan Brassow { 170102c6ddbSMikulas Patocka return sector >> store->chunk_shift; 17171fab00aSJonathan Brassow } 17271fab00aSJonathan Brassow 173493df71cSJonathan Brassow int dm_exception_store_type_register(struct dm_exception_store_type *type); 174493df71cSJonathan Brassow int dm_exception_store_type_unregister(struct dm_exception_store_type *type); 175493df71cSJonathan Brassow 1762defcc3fSMikulas Patocka int dm_exception_store_set_chunk_size(struct dm_exception_store *store, 177df96eee6SMikulas Patocka unsigned chunk_size, 1782defcc3fSMikulas Patocka char **error); 1792defcc3fSMikulas Patocka 180fee1998eSJonathan Brassow int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, 181*fc56f6fbSMike Snitzer struct dm_snapshot *snap, 182fee1998eSJonathan Brassow unsigned *args_used, 183493df71cSJonathan Brassow struct dm_exception_store **store); 184493df71cSJonathan Brassow void dm_exception_store_destroy(struct dm_exception_store *store); 185493df71cSJonathan Brassow 1864db6bfe0SAlasdair G Kergon int dm_exception_store_init(void); 1874db6bfe0SAlasdair G Kergon void dm_exception_store_exit(void); 1884db6bfe0SAlasdair G Kergon 189aea53d92SJonathan Brassow /* 190aea53d92SJonathan Brassow * Two exception store implementations. 191aea53d92SJonathan Brassow */ 1924db6bfe0SAlasdair G Kergon int dm_persistent_snapshot_init(void); 1934db6bfe0SAlasdair G Kergon void dm_persistent_snapshot_exit(void); 1944db6bfe0SAlasdair G Kergon 1954db6bfe0SAlasdair G Kergon int dm_transient_snapshot_init(void); 1964db6bfe0SAlasdair G Kergon void dm_transient_snapshot_exit(void); 1974db6bfe0SAlasdair G Kergon 198aea53d92SJonathan Brassow #endif /* _LINUX_DM_EXCEPTION_STORE */ 199