diff options
Diffstat (limited to 'drivers/md/dm-snap-persistent.c')
-rw-r--r-- | drivers/md/dm-snap-persistent.c | 80 |
1 files changed, 42 insertions, 38 deletions
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 135c2f1fdbfc..d1f1d7017103 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c | |||
@@ -58,25 +58,30 @@ | |||
58 | #define NUM_SNAPSHOT_HDR_CHUNKS 1 | 58 | #define NUM_SNAPSHOT_HDR_CHUNKS 1 |
59 | 59 | ||
60 | struct disk_header { | 60 | struct disk_header { |
61 | uint32_t magic; | 61 | __le32 magic; |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * Is this snapshot valid. There is no way of recovering | 64 | * Is this snapshot valid. There is no way of recovering |
65 | * an invalid snapshot. | 65 | * an invalid snapshot. |
66 | */ | 66 | */ |
67 | uint32_t valid; | 67 | __le32 valid; |
68 | 68 | ||
69 | /* | 69 | /* |
70 | * Simple, incrementing version. no backward | 70 | * Simple, incrementing version. no backward |
71 | * compatibility. | 71 | * compatibility. |
72 | */ | 72 | */ |
73 | uint32_t version; | 73 | __le32 version; |
74 | 74 | ||
75 | /* In sectors */ | 75 | /* In sectors */ |
76 | uint32_t chunk_size; | 76 | __le32 chunk_size; |
77 | }; | 77 | } __packed; |
78 | 78 | ||
79 | struct disk_exception { | 79 | struct disk_exception { |
80 | __le64 old_chunk; | ||
81 | __le64 new_chunk; | ||
82 | } __packed; | ||
83 | |||
84 | struct core_exception { | ||
80 | uint64_t old_chunk; | 85 | uint64_t old_chunk; |
81 | uint64_t new_chunk; | 86 | uint64_t new_chunk; |
82 | }; | 87 | }; |
@@ -169,10 +174,9 @@ static int alloc_area(struct pstore *ps) | |||
169 | if (!ps->area) | 174 | if (!ps->area) |
170 | goto err_area; | 175 | goto err_area; |
171 | 176 | ||
172 | ps->zero_area = vmalloc(len); | 177 | ps->zero_area = vzalloc(len); |
173 | if (!ps->zero_area) | 178 | if (!ps->zero_area) |
174 | goto err_zero_area; | 179 | goto err_zero_area; |
175 | memset(ps->zero_area, 0, len); | ||
176 | 180 | ||
177 | ps->header_area = vmalloc(len); | 181 | ps->header_area = vmalloc(len); |
178 | if (!ps->header_area) | 182 | if (!ps->header_area) |
@@ -396,32 +400,32 @@ static struct disk_exception *get_exception(struct pstore *ps, uint32_t index) | |||
396 | } | 400 | } |
397 | 401 | ||
398 | static void read_exception(struct pstore *ps, | 402 | static void read_exception(struct pstore *ps, |
399 | uint32_t index, struct disk_exception *result) | 403 | uint32_t index, struct core_exception *result) |
400 | { | 404 | { |
401 | struct disk_exception *e = get_exception(ps, index); | 405 | struct disk_exception *de = get_exception(ps, index); |
402 | 406 | ||
403 | /* copy it */ | 407 | /* copy it */ |
404 | result->old_chunk = le64_to_cpu(e->old_chunk); | 408 | result->old_chunk = le64_to_cpu(de->old_chunk); |
405 | result->new_chunk = le64_to_cpu(e->new_chunk); | 409 | result->new_chunk = le64_to_cpu(de->new_chunk); |
406 | } | 410 | } |
407 | 411 | ||
408 | static void write_exception(struct pstore *ps, | 412 | static void write_exception(struct pstore *ps, |
409 | uint32_t index, struct disk_exception *de) | 413 | uint32_t index, struct core_exception *e) |
410 | { | 414 | { |
411 | struct disk_exception *e = get_exception(ps, index); | 415 | struct disk_exception *de = get_exception(ps, index); |
412 | 416 | ||
413 | /* copy it */ | 417 | /* copy it */ |
414 | e->old_chunk = cpu_to_le64(de->old_chunk); | 418 | de->old_chunk = cpu_to_le64(e->old_chunk); |
415 | e->new_chunk = cpu_to_le64(de->new_chunk); | 419 | de->new_chunk = cpu_to_le64(e->new_chunk); |
416 | } | 420 | } |
417 | 421 | ||
418 | static void clear_exception(struct pstore *ps, uint32_t index) | 422 | static void clear_exception(struct pstore *ps, uint32_t index) |
419 | { | 423 | { |
420 | struct disk_exception *e = get_exception(ps, index); | 424 | struct disk_exception *de = get_exception(ps, index); |
421 | 425 | ||
422 | /* clear it */ | 426 | /* clear it */ |
423 | e->old_chunk = 0; | 427 | de->old_chunk = 0; |
424 | e->new_chunk = 0; | 428 | de->new_chunk = 0; |
425 | } | 429 | } |
426 | 430 | ||
427 | /* | 431 | /* |
@@ -437,13 +441,13 @@ static int insert_exceptions(struct pstore *ps, | |||
437 | { | 441 | { |
438 | int r; | 442 | int r; |
439 | unsigned int i; | 443 | unsigned int i; |
440 | struct disk_exception de; | 444 | struct core_exception e; |
441 | 445 | ||
442 | /* presume the area is full */ | 446 | /* presume the area is full */ |
443 | *full = 1; | 447 | *full = 1; |
444 | 448 | ||
445 | for (i = 0; i < ps->exceptions_per_area; i++) { | 449 | for (i = 0; i < ps->exceptions_per_area; i++) { |
446 | read_exception(ps, i, &de); | 450 | read_exception(ps, i, &e); |
447 | 451 | ||
448 | /* | 452 | /* |
449 | * If the new_chunk is pointing at the start of | 453 | * If the new_chunk is pointing at the start of |
@@ -451,7 +455,7 @@ static int insert_exceptions(struct pstore *ps, | |||
451 | * is we know that we've hit the end of the | 455 | * is we know that we've hit the end of the |
452 | * exceptions. Therefore the area is not full. | 456 | * exceptions. Therefore the area is not full. |
453 | */ | 457 | */ |
454 | if (de.new_chunk == 0LL) { | 458 | if (e.new_chunk == 0LL) { |
455 | ps->current_committed = i; | 459 | ps->current_committed = i; |
456 | *full = 0; | 460 | *full = 0; |
457 | break; | 461 | break; |
@@ -460,13 +464,13 @@ static int insert_exceptions(struct pstore *ps, | |||
460 | /* | 464 | /* |
461 | * Keep track of the start of the free chunks. | 465 | * Keep track of the start of the free chunks. |
462 | */ | 466 | */ |
463 | if (ps->next_free <= de.new_chunk) | 467 | if (ps->next_free <= e.new_chunk) |
464 | ps->next_free = de.new_chunk + 1; | 468 | ps->next_free = e.new_chunk + 1; |
465 | 469 | ||
466 | /* | 470 | /* |
467 | * Otherwise we add the exception to the snapshot. | 471 | * Otherwise we add the exception to the snapshot. |
468 | */ | 472 | */ |
469 | r = callback(callback_context, de.old_chunk, de.new_chunk); | 473 | r = callback(callback_context, e.old_chunk, e.new_chunk); |
470 | if (r) | 474 | if (r) |
471 | return r; | 475 | return r; |
472 | } | 476 | } |
@@ -563,7 +567,7 @@ static int persistent_read_metadata(struct dm_exception_store *store, | |||
563 | ps->exceptions_per_area = (ps->store->chunk_size << SECTOR_SHIFT) / | 567 | ps->exceptions_per_area = (ps->store->chunk_size << SECTOR_SHIFT) / |
564 | sizeof(struct disk_exception); | 568 | sizeof(struct disk_exception); |
565 | ps->callbacks = dm_vcalloc(ps->exceptions_per_area, | 569 | ps->callbacks = dm_vcalloc(ps->exceptions_per_area, |
566 | sizeof(*ps->callbacks)); | 570 | sizeof(*ps->callbacks)); |
567 | if (!ps->callbacks) | 571 | if (!ps->callbacks) |
568 | return -ENOMEM; | 572 | return -ENOMEM; |
569 | 573 | ||
@@ -641,12 +645,12 @@ static void persistent_commit_exception(struct dm_exception_store *store, | |||
641 | { | 645 | { |
642 | unsigned int i; | 646 | unsigned int i; |
643 | struct pstore *ps = get_info(store); | 647 | struct pstore *ps = get_info(store); |
644 | struct disk_exception de; | 648 | struct core_exception ce; |
645 | struct commit_callback *cb; | 649 | struct commit_callback *cb; |
646 | 650 | ||
647 | de.old_chunk = e->old_chunk; | 651 | ce.old_chunk = e->old_chunk; |
648 | de.new_chunk = e->new_chunk; | 652 | ce.new_chunk = e->new_chunk; |
649 | write_exception(ps, ps->current_committed++, &de); | 653 | write_exception(ps, ps->current_committed++, &ce); |
650 | 654 | ||
651 | /* | 655 | /* |
652 | * Add the callback to the back of the array. This code | 656 | * Add the callback to the back of the array. This code |
@@ -670,7 +674,7 @@ static void persistent_commit_exception(struct dm_exception_store *store, | |||
670 | * If we completely filled the current area, then wipe the next one. | 674 | * If we completely filled the current area, then wipe the next one. |
671 | */ | 675 | */ |
672 | if ((ps->current_committed == ps->exceptions_per_area) && | 676 | if ((ps->current_committed == ps->exceptions_per_area) && |
673 | zero_disk_area(ps, ps->current_area + 1)) | 677 | zero_disk_area(ps, ps->current_area + 1)) |
674 | ps->valid = 0; | 678 | ps->valid = 0; |
675 | 679 | ||
676 | /* | 680 | /* |
@@ -701,7 +705,7 @@ static int persistent_prepare_merge(struct dm_exception_store *store, | |||
701 | chunk_t *last_new_chunk) | 705 | chunk_t *last_new_chunk) |
702 | { | 706 | { |
703 | struct pstore *ps = get_info(store); | 707 | struct pstore *ps = get_info(store); |
704 | struct disk_exception de; | 708 | struct core_exception ce; |
705 | int nr_consecutive; | 709 | int nr_consecutive; |
706 | int r; | 710 | int r; |
707 | 711 | ||
@@ -722,9 +726,9 @@ static int persistent_prepare_merge(struct dm_exception_store *store, | |||
722 | ps->current_committed = ps->exceptions_per_area; | 726 | ps->current_committed = ps->exceptions_per_area; |
723 | } | 727 | } |
724 | 728 | ||
725 | read_exception(ps, ps->current_committed - 1, &de); | 729 | read_exception(ps, ps->current_committed - 1, &ce); |
726 | *last_old_chunk = de.old_chunk; | 730 | *last_old_chunk = ce.old_chunk; |
727 | *last_new_chunk = de.new_chunk; | 731 | *last_new_chunk = ce.new_chunk; |
728 | 732 | ||
729 | /* | 733 | /* |
730 | * Find number of consecutive chunks within the current area, | 734 | * Find number of consecutive chunks within the current area, |
@@ -733,9 +737,9 @@ static int persistent_prepare_merge(struct dm_exception_store *store, | |||
733 | for (nr_consecutive = 1; nr_consecutive < ps->current_committed; | 737 | for (nr_consecutive = 1; nr_consecutive < ps->current_committed; |
734 | nr_consecutive++) { | 738 | nr_consecutive++) { |
735 | read_exception(ps, ps->current_committed - 1 - nr_consecutive, | 739 | read_exception(ps, ps->current_committed - 1 - nr_consecutive, |
736 | &de); | 740 | &ce); |
737 | if (de.old_chunk != *last_old_chunk - nr_consecutive || | 741 | if (ce.old_chunk != *last_old_chunk - nr_consecutive || |
738 | de.new_chunk != *last_new_chunk - nr_consecutive) | 742 | ce.new_chunk != *last_new_chunk - nr_consecutive) |
739 | break; | 743 | break; |
740 | } | 744 | } |
741 | 745 | ||
@@ -753,7 +757,7 @@ static int persistent_commit_merge(struct dm_exception_store *store, | |||
753 | for (i = 0; i < nr_merged; i++) | 757 | for (i = 0; i < nr_merged; i++) |
754 | clear_exception(ps, ps->current_committed - 1 - i); | 758 | clear_exception(ps, ps->current_committed - 1 - i); |
755 | 759 | ||
756 | r = area_io(ps, WRITE); | 760 | r = area_io(ps, WRITE_FLUSH_FUA); |
757 | if (r < 0) | 761 | if (r < 0) |
758 | return r; | 762 | return r; |
759 | 763 | ||