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; |
