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 */ 29aea53d92SJonathan Brassow struct dm_snap_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 */ 40*b2a11465SJonathan Brassow struct dm_exception_store; 41*b2a11465SJonathan Brassow struct dm_exception_store_type { 42*b2a11465SJonathan Brassow int (*ctr) (struct dm_exception_store *store, 43*b2a11465SJonathan Brassow unsigned argc, char **argv); 44*b2a11465SJonathan Brassow 45aea53d92SJonathan Brassow /* 46aea53d92SJonathan Brassow * Destroys this object when you've finished with it. 47aea53d92SJonathan Brassow */ 48*b2a11465SJonathan Brassow void (*dtr) (struct dm_exception_store *store); 49aea53d92SJonathan Brassow 50aea53d92SJonathan Brassow /* 51aea53d92SJonathan Brassow * The target shouldn't read the COW device until this is 52a159c1acSJonathan Brassow * called. As exceptions are read from the COW, they are 53a159c1acSJonathan Brassow * reported back via the callback. 54aea53d92SJonathan Brassow */ 55a159c1acSJonathan Brassow int (*read_metadata) (struct dm_exception_store *store, 56a159c1acSJonathan Brassow int (*callback)(void *callback_context, 57a159c1acSJonathan Brassow chunk_t old, chunk_t new), 58a159c1acSJonathan Brassow void *callback_context); 59aea53d92SJonathan Brassow 60aea53d92SJonathan Brassow /* 61aea53d92SJonathan Brassow * Find somewhere to store the next exception. 62aea53d92SJonathan Brassow */ 631ae25f9cSJonathan Brassow int (*prepare_exception) (struct dm_exception_store *store, 64aea53d92SJonathan Brassow struct dm_snap_exception *e); 65aea53d92SJonathan Brassow 66aea53d92SJonathan Brassow /* 67aea53d92SJonathan Brassow * Update the metadata with this exception. 68aea53d92SJonathan Brassow */ 691ae25f9cSJonathan Brassow void (*commit_exception) (struct dm_exception_store *store, 70aea53d92SJonathan Brassow struct dm_snap_exception *e, 71aea53d92SJonathan Brassow void (*callback) (void *, int success), 72aea53d92SJonathan Brassow void *callback_context); 73aea53d92SJonathan Brassow 74aea53d92SJonathan Brassow /* 75aea53d92SJonathan Brassow * The snapshot is invalid, note this in the metadata. 76aea53d92SJonathan Brassow */ 771ae25f9cSJonathan Brassow void (*drop_snapshot) (struct dm_exception_store *store); 78aea53d92SJonathan Brassow 79a159c1acSJonathan Brassow int (*status) (struct dm_exception_store *store, status_type_t status, 80a159c1acSJonathan Brassow char *result, unsigned int maxlen); 81a159c1acSJonathan Brassow 82aea53d92SJonathan Brassow /* 83aea53d92SJonathan Brassow * Return how full the snapshot is. 84aea53d92SJonathan Brassow */ 851ae25f9cSJonathan Brassow void (*fraction_full) (struct dm_exception_store *store, 86aea53d92SJonathan Brassow sector_t *numerator, 87aea53d92SJonathan Brassow sector_t *denominator); 88*b2a11465SJonathan Brassow }; 89*b2a11465SJonathan Brassow 90*b2a11465SJonathan Brassow struct dm_exception_store { 91*b2a11465SJonathan Brassow struct dm_exception_store_type type; 92aea53d92SJonathan Brassow 93aea53d92SJonathan Brassow struct dm_snapshot *snap; 94*b2a11465SJonathan Brassow 95aea53d92SJonathan Brassow void *context; 96aea53d92SJonathan Brassow }; 97aea53d92SJonathan Brassow 98aea53d92SJonathan Brassow /* 99aea53d92SJonathan Brassow * Funtions to manipulate consecutive chunks 100aea53d92SJonathan Brassow */ 101aea53d92SJonathan Brassow # if defined(CONFIG_LBD) || (BITS_PER_LONG == 64) 102aea53d92SJonathan Brassow # define DM_CHUNK_CONSECUTIVE_BITS 8 103aea53d92SJonathan Brassow # define DM_CHUNK_NUMBER_BITS 56 104aea53d92SJonathan Brassow 105aea53d92SJonathan Brassow static inline chunk_t dm_chunk_number(chunk_t chunk) 106aea53d92SJonathan Brassow { 107aea53d92SJonathan Brassow return chunk & (chunk_t)((1ULL << DM_CHUNK_NUMBER_BITS) - 1ULL); 108aea53d92SJonathan Brassow } 109aea53d92SJonathan Brassow 110aea53d92SJonathan Brassow static inline unsigned dm_consecutive_chunk_count(struct dm_snap_exception *e) 111aea53d92SJonathan Brassow { 112aea53d92SJonathan Brassow return e->new_chunk >> DM_CHUNK_NUMBER_BITS; 113aea53d92SJonathan Brassow } 114aea53d92SJonathan Brassow 115aea53d92SJonathan Brassow static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e) 116aea53d92SJonathan Brassow { 117aea53d92SJonathan Brassow e->new_chunk += (1ULL << DM_CHUNK_NUMBER_BITS); 118aea53d92SJonathan Brassow 119aea53d92SJonathan Brassow BUG_ON(!dm_consecutive_chunk_count(e)); 120aea53d92SJonathan Brassow } 121aea53d92SJonathan Brassow 122aea53d92SJonathan Brassow # else 123aea53d92SJonathan Brassow # define DM_CHUNK_CONSECUTIVE_BITS 0 124aea53d92SJonathan Brassow 125aea53d92SJonathan Brassow static inline chunk_t dm_chunk_number(chunk_t chunk) 126aea53d92SJonathan Brassow { 127aea53d92SJonathan Brassow return chunk; 128aea53d92SJonathan Brassow } 129aea53d92SJonathan Brassow 130aea53d92SJonathan Brassow static inline unsigned dm_consecutive_chunk_count(struct dm_snap_exception *e) 131aea53d92SJonathan Brassow { 132aea53d92SJonathan Brassow return 0; 133aea53d92SJonathan Brassow } 134aea53d92SJonathan Brassow 135aea53d92SJonathan Brassow static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e) 136aea53d92SJonathan Brassow { 137aea53d92SJonathan Brassow } 138aea53d92SJonathan Brassow 139aea53d92SJonathan Brassow # endif 140aea53d92SJonathan Brassow 1414db6bfe0SAlasdair G Kergon int dm_exception_store_init(void); 1424db6bfe0SAlasdair G Kergon void dm_exception_store_exit(void); 1434db6bfe0SAlasdair G Kergon 144aea53d92SJonathan Brassow /* 145aea53d92SJonathan Brassow * Two exception store implementations. 146aea53d92SJonathan Brassow */ 1474db6bfe0SAlasdair G Kergon int dm_persistent_snapshot_init(void); 1484db6bfe0SAlasdair G Kergon void dm_persistent_snapshot_exit(void); 1494db6bfe0SAlasdair G Kergon 1504db6bfe0SAlasdair G Kergon int dm_transient_snapshot_init(void); 1514db6bfe0SAlasdair G Kergon void dm_transient_snapshot_exit(void); 1524db6bfe0SAlasdair G Kergon 1531ae25f9cSJonathan Brassow int dm_create_persistent(struct dm_exception_store *store); 154aea53d92SJonathan Brassow 1551ae25f9cSJonathan Brassow int dm_create_transient(struct dm_exception_store *store); 156aea53d92SJonathan Brassow 157aea53d92SJonathan Brassow #endif /* _LINUX_DM_EXCEPTION_STORE */ 158