aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-log.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-log.c')
-rw-r--r--drivers/md/dm-log.c48
1 files changed, 13 insertions, 35 deletions
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index efe4adf78530..d73779a42417 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -112,7 +112,7 @@ void dm_destroy_dirty_log(struct dirty_log *log)
112/* 112/*
113 * The on-disk version of the metadata. 113 * The on-disk version of the metadata.
114 */ 114 */
115#define MIRROR_DISK_VERSION 1 115#define MIRROR_DISK_VERSION 2
116#define LOG_OFFSET 2 116#define LOG_OFFSET 2
117 117
118struct log_header { 118struct log_header {
@@ -157,7 +157,6 @@ struct log_c {
157 struct log_header *disk_header; 157 struct log_header *disk_header;
158 158
159 struct io_region bits_location; 159 struct io_region bits_location;
160 uint32_t *disk_bits;
161}; 160};
162 161
163/* 162/*
@@ -166,20 +165,20 @@ struct log_c {
166 */ 165 */
167static inline int log_test_bit(uint32_t *bs, unsigned bit) 166static inline int log_test_bit(uint32_t *bs, unsigned bit)
168{ 167{
169 return test_bit(bit, (unsigned long *) bs) ? 1 : 0; 168 return ext2_test_bit(bit, (unsigned long *) bs) ? 1 : 0;
170} 169}
171 170
172static inline void log_set_bit(struct log_c *l, 171static inline void log_set_bit(struct log_c *l,
173 uint32_t *bs, unsigned bit) 172 uint32_t *bs, unsigned bit)
174{ 173{
175 set_bit(bit, (unsigned long *) bs); 174 ext2_set_bit(bit, (unsigned long *) bs);
176 l->touched = 1; 175 l->touched = 1;
177} 176}
178 177
179static inline void log_clear_bit(struct log_c *l, 178static inline void log_clear_bit(struct log_c *l,
180 uint32_t *bs, unsigned bit) 179 uint32_t *bs, unsigned bit)
181{ 180{
182 clear_bit(bit, (unsigned long *) bs); 181 ext2_clear_bit(bit, (unsigned long *) bs);
183 l->touched = 1; 182 l->touched = 1;
184} 183}
185 184
@@ -219,6 +218,11 @@ static int read_header(struct log_c *log)
219 log->header.nr_regions = 0; 218 log->header.nr_regions = 0;
220 } 219 }
221 220
221#ifdef __LITTLE_ENDIAN
222 if (log->header.version == 1)
223 log->header.version = 2;
224#endif
225
222 if (log->header.version != MIRROR_DISK_VERSION) { 226 if (log->header.version != MIRROR_DISK_VERSION) {
223 DMWARN("incompatible disk log version"); 227 DMWARN("incompatible disk log version");
224 return -EINVAL; 228 return -EINVAL;
@@ -239,45 +243,24 @@ static inline int write_header(struct log_c *log)
239/*---------------------------------------------------------------- 243/*----------------------------------------------------------------
240 * Bits IO 244 * Bits IO
241 *--------------------------------------------------------------*/ 245 *--------------------------------------------------------------*/
242static inline void bits_to_core(uint32_t *core, uint32_t *disk, unsigned count)
243{
244 unsigned i;
245
246 for (i = 0; i < count; i++)
247 core[i] = le32_to_cpu(disk[i]);
248}
249
250static inline void bits_to_disk(uint32_t *core, uint32_t *disk, unsigned count)
251{
252 unsigned i;
253
254 /* copy across the clean/dirty bitset */
255 for (i = 0; i < count; i++)
256 disk[i] = cpu_to_le32(core[i]);
257}
258
259static int read_bits(struct log_c *log) 246static int read_bits(struct log_c *log)
260{ 247{
261 int r; 248 int r;
262 unsigned long ebits; 249 unsigned long ebits;
263 250
264 r = dm_io_sync_vm(1, &log->bits_location, READ, 251 r = dm_io_sync_vm(1, &log->bits_location, READ,
265 log->disk_bits, &ebits); 252 log->clean_bits, &ebits);
266 if (r) 253 if (r)
267 return r; 254 return r;
268 255
269 bits_to_core(log->clean_bits, log->disk_bits,
270 log->bitset_uint32_count);
271 return 0; 256 return 0;
272} 257}
273 258
274static int write_bits(struct log_c *log) 259static int write_bits(struct log_c *log)
275{ 260{
276 unsigned long ebits; 261 unsigned long ebits;
277 bits_to_disk(log->clean_bits, log->disk_bits,
278 log->bitset_uint32_count);
279 return dm_io_sync_vm(1, &log->bits_location, WRITE, 262 return dm_io_sync_vm(1, &log->bits_location, WRITE,
280 log->disk_bits, &ebits); 263 log->clean_bits, &ebits);
281} 264}
282 265
283/*---------------------------------------------------------------- 266/*----------------------------------------------------------------
@@ -433,11 +416,6 @@ static int disk_ctr(struct dirty_log *log, struct dm_target *ti,
433 size = dm_round_up(lc->bitset_uint32_count * sizeof(uint32_t), 416 size = dm_round_up(lc->bitset_uint32_count * sizeof(uint32_t),
434 1 << SECTOR_SHIFT); 417 1 << SECTOR_SHIFT);
435 lc->bits_location.count = size >> SECTOR_SHIFT; 418 lc->bits_location.count = size >> SECTOR_SHIFT;
436 lc->disk_bits = vmalloc(size);
437 if (!lc->disk_bits) {
438 vfree(lc->disk_header);
439 goto bad;
440 }
441 return 0; 419 return 0;
442 420
443 bad: 421 bad:
@@ -451,7 +429,6 @@ static void disk_dtr(struct dirty_log *log)
451 struct log_c *lc = (struct log_c *) log->context; 429 struct log_c *lc = (struct log_c *) log->context;
452 dm_put_device(lc->ti, lc->log_dev); 430 dm_put_device(lc->ti, lc->log_dev);
453 vfree(lc->disk_header); 431 vfree(lc->disk_header);
454 vfree(lc->disk_bits);
455 core_dtr(log); 432 core_dtr(log);
456} 433}
457 434
@@ -568,7 +545,8 @@ static int core_get_resync_work(struct dirty_log *log, region_t *region)
568 return 0; 545 return 0;
569 546
570 do { 547 do {
571 *region = find_next_zero_bit((unsigned long *) lc->sync_bits, 548 *region = ext2_find_next_zero_bit(
549 (unsigned long *) lc->sync_bits,
572 lc->region_count, 550 lc->region_count,
573 lc->sync_search); 551 lc->sync_search);
574 lc->sync_search = *region + 1; 552 lc->sync_search = *region + 1;