diff options
Diffstat (limited to 'drivers/md/dm-log.c')
-rw-r--r-- | drivers/md/dm-log.c | 48 |
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 | ||
118 | struct log_header { | 118 | struct 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 | */ |
167 | static inline int log_test_bit(uint32_t *bs, unsigned bit) | 166 | static 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 | ||
172 | static inline void log_set_bit(struct log_c *l, | 171 | static 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 | ||
179 | static inline void log_clear_bit(struct log_c *l, | 178 | static 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 | *--------------------------------------------------------------*/ |
242 | static 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 | |||
250 | static 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 | |||
259 | static int read_bits(struct log_c *log) | 246 | static 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 | ||
274 | static int write_bits(struct log_c *log) | 259 | static 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; |