xref: /OK3568_Linux_fs/kernel/drivers/md/dm-exception-store.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
3*4882a593Smuzhiyun  * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Device-mapper snapshot exception store.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * This file is released under the GPL.
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #ifndef _LINUX_DM_EXCEPTION_STORE
11*4882a593Smuzhiyun #define _LINUX_DM_EXCEPTION_STORE
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <linux/blkdev.h>
14*4882a593Smuzhiyun #include <linux/list_bl.h>
15*4882a593Smuzhiyun #include <linux/device-mapper.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun /*
18*4882a593Smuzhiyun  * The snapshot code deals with largish chunks of the disk at a
19*4882a593Smuzhiyun  * time. Typically 32k - 512k.
20*4882a593Smuzhiyun  */
21*4882a593Smuzhiyun typedef sector_t chunk_t;
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun /*
24*4882a593Smuzhiyun  * An exception is used where an old chunk of data has been
25*4882a593Smuzhiyun  * replaced by a new one.
26*4882a593Smuzhiyun  * If chunk_t is 64 bits in size, the top 8 bits of new_chunk hold the number
27*4882a593Smuzhiyun  * of chunks that follow contiguously.  Remaining bits hold the number of the
28*4882a593Smuzhiyun  * chunk within the device.
29*4882a593Smuzhiyun  */
30*4882a593Smuzhiyun struct dm_exception {
31*4882a593Smuzhiyun 	struct hlist_bl_node hash_list;
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun 	chunk_t old_chunk;
34*4882a593Smuzhiyun 	chunk_t new_chunk;
35*4882a593Smuzhiyun };
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun /*
38*4882a593Smuzhiyun  * Abstraction to handle the meta/layout of exception stores (the
39*4882a593Smuzhiyun  * COW device).
40*4882a593Smuzhiyun  */
41*4882a593Smuzhiyun struct dm_exception_store;
42*4882a593Smuzhiyun struct dm_exception_store_type {
43*4882a593Smuzhiyun 	const char *name;
44*4882a593Smuzhiyun 	struct module *module;
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 	int (*ctr) (struct dm_exception_store *store, char *options);
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 	/*
49*4882a593Smuzhiyun 	 * Destroys this object when you've finished with it.
50*4882a593Smuzhiyun 	 */
51*4882a593Smuzhiyun 	void (*dtr) (struct dm_exception_store *store);
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 	/*
54*4882a593Smuzhiyun 	 * The target shouldn't read the COW device until this is
55*4882a593Smuzhiyun 	 * called.  As exceptions are read from the COW, they are
56*4882a593Smuzhiyun 	 * reported back via the callback.
57*4882a593Smuzhiyun 	 */
58*4882a593Smuzhiyun 	int (*read_metadata) (struct dm_exception_store *store,
59*4882a593Smuzhiyun 			      int (*callback)(void *callback_context,
60*4882a593Smuzhiyun 					      chunk_t old, chunk_t new),
61*4882a593Smuzhiyun 			      void *callback_context);
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 	/*
64*4882a593Smuzhiyun 	 * Find somewhere to store the next exception.
65*4882a593Smuzhiyun 	 */
66*4882a593Smuzhiyun 	int (*prepare_exception) (struct dm_exception_store *store,
67*4882a593Smuzhiyun 				  struct dm_exception *e);
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	/*
70*4882a593Smuzhiyun 	 * Update the metadata with this exception.
71*4882a593Smuzhiyun 	 */
72*4882a593Smuzhiyun 	void (*commit_exception) (struct dm_exception_store *store,
73*4882a593Smuzhiyun 				  struct dm_exception *e, int valid,
74*4882a593Smuzhiyun 				  void (*callback) (void *, int success),
75*4882a593Smuzhiyun 				  void *callback_context);
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	/*
78*4882a593Smuzhiyun 	 * Returns 0 if the exception store is empty.
79*4882a593Smuzhiyun 	 *
80*4882a593Smuzhiyun 	 * If there are exceptions still to be merged, sets
81*4882a593Smuzhiyun 	 * *last_old_chunk and *last_new_chunk to the most recent
82*4882a593Smuzhiyun 	 * still-to-be-merged chunk and returns the number of
83*4882a593Smuzhiyun 	 * consecutive previous ones.
84*4882a593Smuzhiyun 	 */
85*4882a593Smuzhiyun 	int (*prepare_merge) (struct dm_exception_store *store,
86*4882a593Smuzhiyun 			      chunk_t *last_old_chunk, chunk_t *last_new_chunk);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	/*
89*4882a593Smuzhiyun 	 * Clear the last n exceptions.
90*4882a593Smuzhiyun 	 * nr_merged must be <= the value returned by prepare_merge.
91*4882a593Smuzhiyun 	 */
92*4882a593Smuzhiyun 	int (*commit_merge) (struct dm_exception_store *store, int nr_merged);
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	/*
95*4882a593Smuzhiyun 	 * The snapshot is invalid, note this in the metadata.
96*4882a593Smuzhiyun 	 */
97*4882a593Smuzhiyun 	void (*drop_snapshot) (struct dm_exception_store *store);
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	unsigned (*status) (struct dm_exception_store *store,
100*4882a593Smuzhiyun 			    status_type_t status, char *result,
101*4882a593Smuzhiyun 			    unsigned maxlen);
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	/*
104*4882a593Smuzhiyun 	 * Return how full the snapshot is.
105*4882a593Smuzhiyun 	 */
106*4882a593Smuzhiyun 	void (*usage) (struct dm_exception_store *store,
107*4882a593Smuzhiyun 		       sector_t *total_sectors, sector_t *sectors_allocated,
108*4882a593Smuzhiyun 		       sector_t *metadata_sectors);
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	/* For internal device-mapper use only. */
111*4882a593Smuzhiyun 	struct list_head list;
112*4882a593Smuzhiyun };
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun struct dm_snapshot;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun struct dm_exception_store {
117*4882a593Smuzhiyun 	struct dm_exception_store_type *type;
118*4882a593Smuzhiyun 	struct dm_snapshot *snap;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	/* Size of data blocks saved - must be a power of 2 */
121*4882a593Smuzhiyun 	unsigned chunk_size;
122*4882a593Smuzhiyun 	unsigned chunk_mask;
123*4882a593Smuzhiyun 	unsigned chunk_shift;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	void *context;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	bool userspace_supports_overflow;
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun /*
131*4882a593Smuzhiyun  * Obtain the origin or cow device used by a given snapshot.
132*4882a593Smuzhiyun  */
133*4882a593Smuzhiyun struct dm_dev *dm_snap_origin(struct dm_snapshot *snap);
134*4882a593Smuzhiyun struct dm_dev *dm_snap_cow(struct dm_snapshot *snap);
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun /*
137*4882a593Smuzhiyun  * Funtions to manipulate consecutive chunks
138*4882a593Smuzhiyun  */
139*4882a593Smuzhiyun #define DM_CHUNK_CONSECUTIVE_BITS 8
140*4882a593Smuzhiyun #define DM_CHUNK_NUMBER_BITS 56
141*4882a593Smuzhiyun 
dm_chunk_number(chunk_t chunk)142*4882a593Smuzhiyun static inline chunk_t dm_chunk_number(chunk_t chunk)
143*4882a593Smuzhiyun {
144*4882a593Smuzhiyun 	return chunk & (chunk_t)((1ULL << DM_CHUNK_NUMBER_BITS) - 1ULL);
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun 
dm_consecutive_chunk_count(struct dm_exception * e)147*4882a593Smuzhiyun static inline unsigned dm_consecutive_chunk_count(struct dm_exception *e)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun 	return e->new_chunk >> DM_CHUNK_NUMBER_BITS;
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun 
dm_consecutive_chunk_count_inc(struct dm_exception * e)152*4882a593Smuzhiyun static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun 	e->new_chunk += (1ULL << DM_CHUNK_NUMBER_BITS);
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	BUG_ON(!dm_consecutive_chunk_count(e));
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun 
dm_consecutive_chunk_count_dec(struct dm_exception * e)159*4882a593Smuzhiyun static inline void dm_consecutive_chunk_count_dec(struct dm_exception *e)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun 	BUG_ON(!dm_consecutive_chunk_count(e));
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	e->new_chunk -= (1ULL << DM_CHUNK_NUMBER_BITS);
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun /*
167*4882a593Smuzhiyun  * Return the number of sectors in the device.
168*4882a593Smuzhiyun  */
get_dev_size(struct block_device * bdev)169*4882a593Smuzhiyun static inline sector_t get_dev_size(struct block_device *bdev)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun 	return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun 
sector_to_chunk(struct dm_exception_store * store,sector_t sector)174*4882a593Smuzhiyun static inline chunk_t sector_to_chunk(struct dm_exception_store *store,
175*4882a593Smuzhiyun 				      sector_t sector)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun 	return sector >> store->chunk_shift;
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun int dm_exception_store_type_register(struct dm_exception_store_type *type);
181*4882a593Smuzhiyun int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
184*4882a593Smuzhiyun 				      unsigned chunk_size,
185*4882a593Smuzhiyun 				      char **error);
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
188*4882a593Smuzhiyun 			      struct dm_snapshot *snap,
189*4882a593Smuzhiyun 			      unsigned *args_used,
190*4882a593Smuzhiyun 			      struct dm_exception_store **store);
191*4882a593Smuzhiyun void dm_exception_store_destroy(struct dm_exception_store *store);
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun int dm_exception_store_init(void);
194*4882a593Smuzhiyun void dm_exception_store_exit(void);
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun /*
197*4882a593Smuzhiyun  * Two exception store implementations.
198*4882a593Smuzhiyun  */
199*4882a593Smuzhiyun int dm_persistent_snapshot_init(void);
200*4882a593Smuzhiyun void dm_persistent_snapshot_exit(void);
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun int dm_transient_snapshot_init(void);
203*4882a593Smuzhiyun void dm_transient_snapshot_exit(void);
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun #endif /* _LINUX_DM_EXCEPTION_STORE */
206