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 */ 29*1d4989c8SJon 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, 67*1d4989c8SJon 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, 73*1d4989c8SJon 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 */ 891ae25f9cSJonathan Brassow void (*fraction_full) (struct dm_exception_store *store, 90aea53d92SJonathan Brassow sector_t *numerator, 91aea53d92SJonathan Brassow sector_t *denominator); 92493df71cSJonathan Brassow 93493df71cSJonathan Brassow /* For internal device-mapper use only. */ 94493df71cSJonathan Brassow struct list_head list; 95b2a11465SJonathan Brassow }; 96b2a11465SJonathan Brassow 97b2a11465SJonathan Brassow struct dm_exception_store { 98493df71cSJonathan Brassow struct dm_exception_store_type *type; 990cea9c78SJonathan Brassow struct dm_target *ti; 100aea53d92SJonathan Brassow 10149beb2b8SJonathan Brassow struct dm_dev *cow; 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 /* 112aea53d92SJonathan Brassow * Funtions to manipulate consecutive chunks 113aea53d92SJonathan Brassow */ 11490c699a9SBartlomiej Zolnierkiewicz # if defined(CONFIG_LBDAF) || (BITS_PER_LONG == 64) 115aea53d92SJonathan Brassow # define DM_CHUNK_CONSECUTIVE_BITS 8 116aea53d92SJonathan Brassow # define DM_CHUNK_NUMBER_BITS 56 117aea53d92SJonathan Brassow 118aea53d92SJonathan Brassow static inline chunk_t dm_chunk_number(chunk_t chunk) 119aea53d92SJonathan Brassow { 120aea53d92SJonathan Brassow return chunk & (chunk_t)((1ULL << DM_CHUNK_NUMBER_BITS) - 1ULL); 121aea53d92SJonathan Brassow } 122aea53d92SJonathan Brassow 123*1d4989c8SJon Brassow static inline unsigned dm_consecutive_chunk_count(struct dm_exception *e) 124aea53d92SJonathan Brassow { 125aea53d92SJonathan Brassow return e->new_chunk >> DM_CHUNK_NUMBER_BITS; 126aea53d92SJonathan Brassow } 127aea53d92SJonathan Brassow 128*1d4989c8SJon Brassow static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e) 129aea53d92SJonathan Brassow { 130aea53d92SJonathan Brassow e->new_chunk += (1ULL << DM_CHUNK_NUMBER_BITS); 131aea53d92SJonathan Brassow 132aea53d92SJonathan Brassow BUG_ON(!dm_consecutive_chunk_count(e)); 133aea53d92SJonathan Brassow } 134aea53d92SJonathan Brassow 135aea53d92SJonathan Brassow # else 136aea53d92SJonathan Brassow # define DM_CHUNK_CONSECUTIVE_BITS 0 137aea53d92SJonathan Brassow 138aea53d92SJonathan Brassow static inline chunk_t dm_chunk_number(chunk_t chunk) 139aea53d92SJonathan Brassow { 140aea53d92SJonathan Brassow return chunk; 141aea53d92SJonathan Brassow } 142aea53d92SJonathan Brassow 143*1d4989c8SJon Brassow static inline unsigned dm_consecutive_chunk_count(struct dm_exception *e) 144aea53d92SJonathan Brassow { 145aea53d92SJonathan Brassow return 0; 146aea53d92SJonathan Brassow } 147aea53d92SJonathan Brassow 148*1d4989c8SJon Brassow static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e) 149aea53d92SJonathan Brassow { 150aea53d92SJonathan Brassow } 151aea53d92SJonathan Brassow 152aea53d92SJonathan Brassow # endif 153aea53d92SJonathan Brassow 15471fab00aSJonathan Brassow /* 15571fab00aSJonathan Brassow * Return the number of sectors in the device. 15671fab00aSJonathan Brassow */ 15771fab00aSJonathan Brassow static inline sector_t get_dev_size(struct block_device *bdev) 15871fab00aSJonathan Brassow { 1595657e8faSMikulas Patocka return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; 16071fab00aSJonathan Brassow } 16171fab00aSJonathan Brassow 16271fab00aSJonathan Brassow static inline chunk_t sector_to_chunk(struct dm_exception_store *store, 16371fab00aSJonathan Brassow sector_t sector) 16471fab00aSJonathan Brassow { 165102c6ddbSMikulas Patocka return sector >> store->chunk_shift; 16671fab00aSJonathan Brassow } 16771fab00aSJonathan Brassow 168493df71cSJonathan Brassow int dm_exception_store_type_register(struct dm_exception_store_type *type); 169493df71cSJonathan Brassow int dm_exception_store_type_unregister(struct dm_exception_store_type *type); 170493df71cSJonathan Brassow 1712defcc3fSMikulas Patocka int dm_exception_store_set_chunk_size(struct dm_exception_store *store, 172df96eee6SMikulas Patocka unsigned chunk_size, 1732defcc3fSMikulas Patocka char **error); 1742defcc3fSMikulas Patocka 175fee1998eSJonathan Brassow int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, 176fee1998eSJonathan Brassow unsigned *args_used, 177493df71cSJonathan Brassow struct dm_exception_store **store); 178493df71cSJonathan Brassow void dm_exception_store_destroy(struct dm_exception_store *store); 179493df71cSJonathan Brassow 1804db6bfe0SAlasdair G Kergon int dm_exception_store_init(void); 1814db6bfe0SAlasdair G Kergon void dm_exception_store_exit(void); 1824db6bfe0SAlasdair G Kergon 183aea53d92SJonathan Brassow /* 184aea53d92SJonathan Brassow * Two exception store implementations. 185aea53d92SJonathan Brassow */ 1864db6bfe0SAlasdair G Kergon int dm_persistent_snapshot_init(void); 1874db6bfe0SAlasdair G Kergon void dm_persistent_snapshot_exit(void); 1884db6bfe0SAlasdair G Kergon 1894db6bfe0SAlasdair G Kergon int dm_transient_snapshot_init(void); 1904db6bfe0SAlasdair G Kergon void dm_transient_snapshot_exit(void); 1914db6bfe0SAlasdair G Kergon 192aea53d92SJonathan Brassow #endif /* _LINUX_DM_EXCEPTION_STORE */ 193