Blame view

drivers/md/dm-exception-store.h 5.65 KB
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
1
2
3
4
5
6
7
8
9
10
11
12
13
  /*
   * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
   * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
   *
   * Device-mapper snapshot exception store.
   *
   * This file is released under the GPL.
   */
  
  #ifndef _LINUX_DM_EXCEPTION_STORE
  #define _LINUX_DM_EXCEPTION_STORE
  
  #include <linux/blkdev.h>
a159c1ac5   Jonathan Brassow   dm snapshot: exte...
14
  #include <linux/device-mapper.h>
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  
  /*
   * The snapshot code deals with largish chunks of the disk at a
   * time. Typically 32k - 512k.
   */
  typedef sector_t chunk_t;
  
  /*
   * An exception is used where an old chunk of data has been
   * replaced by a new one.
   * If chunk_t is 64 bits in size, the top 8 bits of new_chunk hold the number
   * of chunks that follow contiguously.  Remaining bits hold the number of the
   * chunk within the device.
   */
1d4989c85   Jon Brassow   dm snapshot: rena...
29
  struct dm_exception {
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
30
31
32
33
34
35
36
37
38
39
  	struct list_head hash_list;
  
  	chunk_t old_chunk;
  	chunk_t new_chunk;
  };
  
  /*
   * Abstraction to handle the meta/layout of exception stores (the
   * COW device).
   */
b2a114652   Jonathan Brassow   dm exception stor...
40
41
  struct dm_exception_store;
  struct dm_exception_store_type {
493df71c6   Jonathan Brassow   dm exception stor...
42
43
  	const char *name;
  	struct module *module;
b2a114652   Jonathan Brassow   dm exception stor...
44
45
  	int (*ctr) (struct dm_exception_store *store,
  		    unsigned argc, char **argv);
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
46
47
48
  	/*
  	 * Destroys this object when you've finished with it.
  	 */
b2a114652   Jonathan Brassow   dm exception stor...
49
  	void (*dtr) (struct dm_exception_store *store);
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
50
51
52
  
  	/*
  	 * The target shouldn't read the COW device until this is
a159c1ac5   Jonathan Brassow   dm snapshot: exte...
53
54
  	 * called.  As exceptions are read from the COW, they are
  	 * reported back via the callback.
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
55
  	 */
a159c1ac5   Jonathan Brassow   dm snapshot: exte...
56
57
58
59
  	int (*read_metadata) (struct dm_exception_store *store,
  			      int (*callback)(void *callback_context,
  					      chunk_t old, chunk_t new),
  			      void *callback_context);
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
60
61
62
63
  
  	/*
  	 * Find somewhere to store the next exception.
  	 */
1ae25f9c9   Jonathan Brassow   dm snapshot: rena...
64
  	int (*prepare_exception) (struct dm_exception_store *store,
1d4989c85   Jon Brassow   dm snapshot: rena...
65
  				  struct dm_exception *e);
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
66
67
68
69
  
  	/*
  	 * Update the metadata with this exception.
  	 */
1ae25f9c9   Jonathan Brassow   dm snapshot: rena...
70
  	void (*commit_exception) (struct dm_exception_store *store,
1d4989c85   Jon Brassow   dm snapshot: rena...
71
  				  struct dm_exception *e,
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
72
73
74
75
  				  void (*callback) (void *, int success),
  				  void *callback_context);
  
  	/*
4454a6216   Mikulas Patocka   dm exception stor...
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
  	 * Returns 0 if the exception store is empty.
  	 *
  	 * If there are exceptions still to be merged, sets
  	 * *last_old_chunk and *last_new_chunk to the most recent
  	 * still-to-be-merged chunk and returns the number of
  	 * consecutive previous ones.
  	 */
  	int (*prepare_merge) (struct dm_exception_store *store,
  			      chunk_t *last_old_chunk, chunk_t *last_new_chunk);
  
  	/*
  	 * Clear the last n exceptions.
  	 * nr_merged must be <= the value returned by prepare_merge.
  	 */
  	int (*commit_merge) (struct dm_exception_store *store, int nr_merged);
  
  	/*
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
93
94
  	 * The snapshot is invalid, note this in the metadata.
  	 */
1ae25f9c9   Jonathan Brassow   dm snapshot: rena...
95
  	void (*drop_snapshot) (struct dm_exception_store *store);
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
96

1e302a929   Jonathan Brassow   dm snapshot: move...
97
98
99
  	unsigned (*status) (struct dm_exception_store *store,
  			    status_type_t status, char *result,
  			    unsigned maxlen);
a159c1ac5   Jonathan Brassow   dm snapshot: exte...
100

aea53d92f   Jonathan Brassow   dm snapshot: sepa...
101
102
103
  	/*
  	 * Return how full the snapshot is.
  	 */
985903bb3   Mike Snitzer   dm snapshot: add ...
104
105
106
  	void (*usage) (struct dm_exception_store *store,
  		       sector_t *total_sectors, sector_t *sectors_allocated,
  		       sector_t *metadata_sectors);
493df71c6   Jonathan Brassow   dm exception stor...
107
108
109
  
  	/* For internal device-mapper use only. */
  	struct list_head list;
b2a114652   Jonathan Brassow   dm exception stor...
110
  };
fc56f6fbc   Mike Snitzer   dm snapshot: move...
111
  struct dm_snapshot;
b2a114652   Jonathan Brassow   dm exception stor...
112
  struct dm_exception_store {
493df71c6   Jonathan Brassow   dm exception stor...
113
  	struct dm_exception_store_type *type;
fc56f6fbc   Mike Snitzer   dm snapshot: move...
114
  	struct dm_snapshot *snap;
49beb2b87   Jonathan Brassow   dm exception stor...
115

d02168495   Jonathan Brassow   dm exception stor...
116
  	/* Size of data blocks saved - must be a power of 2 */
df96eee67   Mikulas Patocka   dm snapshot: use ...
117
118
119
  	unsigned chunk_size;
  	unsigned chunk_mask;
  	unsigned chunk_shift;
d02168495   Jonathan Brassow   dm exception stor...
120

aea53d92f   Jonathan Brassow   dm snapshot: sepa...
121
122
123
124
  	void *context;
  };
  
  /*
c24110450   Mikulas Patocka   dm snapshot: test...
125
   * Obtain the origin or cow device used by a given snapshot.
fc56f6fbc   Mike Snitzer   dm snapshot: move...
126
   */
c24110450   Mikulas Patocka   dm snapshot: test...
127
  struct dm_dev *dm_snap_origin(struct dm_snapshot *snap);
fc56f6fbc   Mike Snitzer   dm snapshot: move...
128
129
130
  struct dm_dev *dm_snap_cow(struct dm_snapshot *snap);
  
  /*
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
131
132
   * Funtions to manipulate consecutive chunks
   */
90c699a9e   Bartlomiej Zolnierkiewicz   block: rename CON...
133
  #  if defined(CONFIG_LBDAF) || (BITS_PER_LONG == 64)
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
134
135
136
137
138
139
140
  #    define DM_CHUNK_CONSECUTIVE_BITS 8
  #    define DM_CHUNK_NUMBER_BITS 56
  
  static inline chunk_t dm_chunk_number(chunk_t chunk)
  {
  	return chunk & (chunk_t)((1ULL << DM_CHUNK_NUMBER_BITS) - 1ULL);
  }
1d4989c85   Jon Brassow   dm snapshot: rena...
141
  static inline unsigned dm_consecutive_chunk_count(struct dm_exception *e)
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
142
143
144
  {
  	return e->new_chunk >> DM_CHUNK_NUMBER_BITS;
  }
1d4989c85   Jon Brassow   dm snapshot: rena...
145
  static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e)
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
146
147
148
149
150
  {
  	e->new_chunk += (1ULL << DM_CHUNK_NUMBER_BITS);
  
  	BUG_ON(!dm_consecutive_chunk_count(e));
  }
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
151
152
153
154
155
156
  static inline void dm_consecutive_chunk_count_dec(struct dm_exception *e)
  {
  	BUG_ON(!dm_consecutive_chunk_count(e));
  
  	e->new_chunk -= (1ULL << DM_CHUNK_NUMBER_BITS);
  }
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
157
158
159
160
161
162
163
  #  else
  #    define DM_CHUNK_CONSECUTIVE_BITS 0
  
  static inline chunk_t dm_chunk_number(chunk_t chunk)
  {
  	return chunk;
  }
1d4989c85   Jon Brassow   dm snapshot: rena...
164
  static inline unsigned dm_consecutive_chunk_count(struct dm_exception *e)
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
165
166
167
  {
  	return 0;
  }
1d4989c85   Jon Brassow   dm snapshot: rena...
168
  static inline void dm_consecutive_chunk_count_inc(struct dm_exception *e)
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
169
170
  {
  }
1e03f97e4   Mikulas Patocka   dm snapshot: add ...
171
172
173
  static inline void dm_consecutive_chunk_count_dec(struct dm_exception *e)
  {
  }
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
174
  #  endif
71fab00a6   Jonathan Brassow   dm snapshot: remo...
175
176
177
178
179
  /*
   * Return the number of sectors in the device.
   */
  static inline sector_t get_dev_size(struct block_device *bdev)
  {
5657e8fa4   Mikulas Patocka   dm: use i_size_read
180
  	return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
71fab00a6   Jonathan Brassow   dm snapshot: remo...
181
182
183
184
185
  }
  
  static inline chunk_t sector_to_chunk(struct dm_exception_store *store,
  				      sector_t sector)
  {
102c6ddb1   Mikulas Patocka   dm snapshot: simp...
186
  	return sector >> store->chunk_shift;
71fab00a6   Jonathan Brassow   dm snapshot: remo...
187
  }
493df71c6   Jonathan Brassow   dm exception stor...
188
189
  int dm_exception_store_type_register(struct dm_exception_store_type *type);
  int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
2defcc3fb   Mikulas Patocka   dm exception stor...
190
  int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
df96eee67   Mikulas Patocka   dm snapshot: use ...
191
  				      unsigned chunk_size,
2defcc3fb   Mikulas Patocka   dm exception stor...
192
  				      char **error);
fee1998e9   Jonathan Brassow   dm snapshot: move...
193
  int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
fc56f6fbc   Mike Snitzer   dm snapshot: move...
194
  			      struct dm_snapshot *snap,
fee1998e9   Jonathan Brassow   dm snapshot: move...
195
  			      unsigned *args_used,
493df71c6   Jonathan Brassow   dm exception stor...
196
197
  			      struct dm_exception_store **store);
  void dm_exception_store_destroy(struct dm_exception_store *store);
4db6bfe02   Alasdair G Kergon   dm snapshot: spli...
198
199
  int dm_exception_store_init(void);
  void dm_exception_store_exit(void);
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
200
201
202
  /*
   * Two exception store implementations.
   */
4db6bfe02   Alasdair G Kergon   dm snapshot: spli...
203
204
205
206
207
  int dm_persistent_snapshot_init(void);
  void dm_persistent_snapshot_exit(void);
  
  int dm_transient_snapshot_init(void);
  void dm_transient_snapshot_exit(void);
aea53d92f   Jonathan Brassow   dm snapshot: sepa...
208
  #endif /* _LINUX_DM_EXCEPTION_STORE */