diff options
-rw-r--r-- | drivers/md/dm-log.c | 89 | ||||
-rw-r--r-- | drivers/md/dm-log.h | 84 | ||||
-rw-r--r-- | drivers/md/dm-raid1.c | 36 | ||||
-rw-r--r-- | drivers/md/dm.h | 6 | ||||
-rw-r--r-- | include/linux/device-mapper.h | 2 |
5 files changed, 114 insertions, 103 deletions
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 14f785fc308a..b776701cc8fa 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c | |||
@@ -12,13 +12,14 @@ | |||
12 | 12 | ||
13 | #include "dm-log.h" | 13 | #include "dm-log.h" |
14 | #include "dm-io.h" | 14 | #include "dm-io.h" |
15 | #include "dm.h" | ||
15 | 16 | ||
16 | #define DM_MSG_PREFIX "dirty region log" | 17 | #define DM_MSG_PREFIX "dirty region log" |
17 | 18 | ||
18 | static LIST_HEAD(_log_types); | 19 | static LIST_HEAD(_log_types); |
19 | static DEFINE_SPINLOCK(_lock); | 20 | static DEFINE_SPINLOCK(_lock); |
20 | 21 | ||
21 | int dm_register_dirty_log_type(struct dirty_log_type *type) | 22 | int dm_dirty_log_type_register(struct dm_dirty_log_type *type) |
22 | { | 23 | { |
23 | spin_lock(&_lock); | 24 | spin_lock(&_lock); |
24 | type->use_count = 0; | 25 | type->use_count = 0; |
@@ -27,8 +28,9 @@ int dm_register_dirty_log_type(struct dirty_log_type *type) | |||
27 | 28 | ||
28 | return 0; | 29 | return 0; |
29 | } | 30 | } |
31 | EXPORT_SYMBOL(dm_dirty_log_type_register); | ||
30 | 32 | ||
31 | int dm_unregister_dirty_log_type(struct dirty_log_type *type) | 33 | int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type) |
32 | { | 34 | { |
33 | spin_lock(&_lock); | 35 | spin_lock(&_lock); |
34 | 36 | ||
@@ -41,10 +43,11 @@ int dm_unregister_dirty_log_type(struct dirty_log_type *type) | |||
41 | 43 | ||
42 | return 0; | 44 | return 0; |
43 | } | 45 | } |
46 | EXPORT_SYMBOL(dm_dirty_log_type_unregister); | ||
44 | 47 | ||
45 | static struct dirty_log_type *_get_type(const char *type_name) | 48 | static struct dm_dirty_log_type *_get_type(const char *type_name) |
46 | { | 49 | { |
47 | struct dirty_log_type *type; | 50 | struct dm_dirty_log_type *type; |
48 | 51 | ||
49 | spin_lock(&_lock); | 52 | spin_lock(&_lock); |
50 | list_for_each_entry (type, &_log_types, list) | 53 | list_for_each_entry (type, &_log_types, list) |
@@ -79,10 +82,10 @@ static struct dirty_log_type *_get_type(const char *type_name) | |||
79 | * | 82 | * |
80 | * Returns: dirty_log_type* on success, NULL on failure | 83 | * Returns: dirty_log_type* on success, NULL on failure |
81 | */ | 84 | */ |
82 | static struct dirty_log_type *get_type(const char *type_name) | 85 | static struct dm_dirty_log_type *get_type(const char *type_name) |
83 | { | 86 | { |
84 | char *p, *type_name_dup; | 87 | char *p, *type_name_dup; |
85 | struct dirty_log_type *type; | 88 | struct dm_dirty_log_type *type; |
86 | 89 | ||
87 | type = _get_type(type_name); | 90 | type = _get_type(type_name); |
88 | if (type) | 91 | if (type) |
@@ -111,7 +114,7 @@ static struct dirty_log_type *get_type(const char *type_name) | |||
111 | return type; | 114 | return type; |
112 | } | 115 | } |
113 | 116 | ||
114 | static void put_type(struct dirty_log_type *type) | 117 | static void put_type(struct dm_dirty_log_type *type) |
115 | { | 118 | { |
116 | spin_lock(&_lock); | 119 | spin_lock(&_lock); |
117 | if (!--type->use_count) | 120 | if (!--type->use_count) |
@@ -119,11 +122,12 @@ static void put_type(struct dirty_log_type *type) | |||
119 | spin_unlock(&_lock); | 122 | spin_unlock(&_lock); |
120 | } | 123 | } |
121 | 124 | ||
122 | struct dirty_log *dm_create_dirty_log(const char *type_name, struct dm_target *ti, | 125 | struct dm_dirty_log *dm_dirty_log_create(const char *type_name, |
123 | unsigned int argc, char **argv) | 126 | struct dm_target *ti, |
127 | unsigned int argc, char **argv) | ||
124 | { | 128 | { |
125 | struct dirty_log_type *type; | 129 | struct dm_dirty_log_type *type; |
126 | struct dirty_log *log; | 130 | struct dm_dirty_log *log; |
127 | 131 | ||
128 | log = kmalloc(sizeof(*log), GFP_KERNEL); | 132 | log = kmalloc(sizeof(*log), GFP_KERNEL); |
129 | if (!log) | 133 | if (!log) |
@@ -144,13 +148,15 @@ struct dirty_log *dm_create_dirty_log(const char *type_name, struct dm_target *t | |||
144 | 148 | ||
145 | return log; | 149 | return log; |
146 | } | 150 | } |
151 | EXPORT_SYMBOL(dm_dirty_log_create); | ||
147 | 152 | ||
148 | void dm_destroy_dirty_log(struct dirty_log *log) | 153 | void dm_dirty_log_destroy(struct dm_dirty_log *log) |
149 | { | 154 | { |
150 | log->type->dtr(log); | 155 | log->type->dtr(log); |
151 | put_type(log->type); | 156 | put_type(log->type); |
152 | kfree(log); | 157 | kfree(log); |
153 | } | 158 | } |
159 | EXPORT_SYMBOL(dm_dirty_log_destroy); | ||
154 | 160 | ||
155 | /*----------------------------------------------------------------- | 161 | /*----------------------------------------------------------------- |
156 | * Persistent and core logs share a lot of their implementation. | 162 | * Persistent and core logs share a lot of their implementation. |
@@ -216,7 +222,7 @@ struct log_c { | |||
216 | * The touched member needs to be updated every time we access | 222 | * The touched member needs to be updated every time we access |
217 | * one of the bitsets. | 223 | * one of the bitsets. |
218 | */ | 224 | */ |
219 | static inline int log_test_bit(uint32_t *bs, unsigned bit) | 225 | static inline int log_test_bit(uint32_t *bs, unsigned bit) |
220 | { | 226 | { |
221 | return ext2_test_bit(bit, (unsigned long *) bs) ? 1 : 0; | 227 | return ext2_test_bit(bit, (unsigned long *) bs) ? 1 : 0; |
222 | } | 228 | } |
@@ -303,7 +309,7 @@ static inline int write_header(struct log_c *log) | |||
303 | * argv contains region_size followed optionally by [no]sync | 309 | * argv contains region_size followed optionally by [no]sync |
304 | *--------------------------------------------------------------*/ | 310 | *--------------------------------------------------------------*/ |
305 | #define BYTE_SHIFT 3 | 311 | #define BYTE_SHIFT 3 |
306 | static int create_log_context(struct dirty_log *log, struct dm_target *ti, | 312 | static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, |
307 | unsigned int argc, char **argv, | 313 | unsigned int argc, char **argv, |
308 | struct dm_dev *dev) | 314 | struct dm_dev *dev) |
309 | { | 315 | { |
@@ -435,7 +441,7 @@ static int create_log_context(struct dirty_log *log, struct dm_target *ti, | |||
435 | return 0; | 441 | return 0; |
436 | } | 442 | } |
437 | 443 | ||
438 | static int core_ctr(struct dirty_log *log, struct dm_target *ti, | 444 | static int core_ctr(struct dm_dirty_log *log, struct dm_target *ti, |
439 | unsigned int argc, char **argv) | 445 | unsigned int argc, char **argv) |
440 | { | 446 | { |
441 | return create_log_context(log, ti, argc, argv, NULL); | 447 | return create_log_context(log, ti, argc, argv, NULL); |
@@ -448,7 +454,7 @@ static void destroy_log_context(struct log_c *lc) | |||
448 | kfree(lc); | 454 | kfree(lc); |
449 | } | 455 | } |
450 | 456 | ||
451 | static void core_dtr(struct dirty_log *log) | 457 | static void core_dtr(struct dm_dirty_log *log) |
452 | { | 458 | { |
453 | struct log_c *lc = (struct log_c *) log->context; | 459 | struct log_c *lc = (struct log_c *) log->context; |
454 | 460 | ||
@@ -461,7 +467,7 @@ static void core_dtr(struct dirty_log *log) | |||
461 | * | 467 | * |
462 | * argv contains log_device region_size followed optionally by [no]sync | 468 | * argv contains log_device region_size followed optionally by [no]sync |
463 | *--------------------------------------------------------------*/ | 469 | *--------------------------------------------------------------*/ |
464 | static int disk_ctr(struct dirty_log *log, struct dm_target *ti, | 470 | static int disk_ctr(struct dm_dirty_log *log, struct dm_target *ti, |
465 | unsigned int argc, char **argv) | 471 | unsigned int argc, char **argv) |
466 | { | 472 | { |
467 | int r; | 473 | int r; |
@@ -486,7 +492,7 @@ static int disk_ctr(struct dirty_log *log, struct dm_target *ti, | |||
486 | return 0; | 492 | return 0; |
487 | } | 493 | } |
488 | 494 | ||
489 | static void disk_dtr(struct dirty_log *log) | 495 | static void disk_dtr(struct dm_dirty_log *log) |
490 | { | 496 | { |
491 | struct log_c *lc = (struct log_c *) log->context; | 497 | struct log_c *lc = (struct log_c *) log->context; |
492 | 498 | ||
@@ -515,7 +521,7 @@ static void fail_log_device(struct log_c *lc) | |||
515 | dm_table_event(lc->ti->table); | 521 | dm_table_event(lc->ti->table); |
516 | } | 522 | } |
517 | 523 | ||
518 | static int disk_resume(struct dirty_log *log) | 524 | static int disk_resume(struct dm_dirty_log *log) |
519 | { | 525 | { |
520 | int r; | 526 | int r; |
521 | unsigned i; | 527 | unsigned i; |
@@ -571,38 +577,38 @@ static int disk_resume(struct dirty_log *log) | |||
571 | return r; | 577 | return r; |
572 | } | 578 | } |
573 | 579 | ||
574 | static uint32_t core_get_region_size(struct dirty_log *log) | 580 | static uint32_t core_get_region_size(struct dm_dirty_log *log) |
575 | { | 581 | { |
576 | struct log_c *lc = (struct log_c *) log->context; | 582 | struct log_c *lc = (struct log_c *) log->context; |
577 | return lc->region_size; | 583 | return lc->region_size; |
578 | } | 584 | } |
579 | 585 | ||
580 | static int core_resume(struct dirty_log *log) | 586 | static int core_resume(struct dm_dirty_log *log) |
581 | { | 587 | { |
582 | struct log_c *lc = (struct log_c *) log->context; | 588 | struct log_c *lc = (struct log_c *) log->context; |
583 | lc->sync_search = 0; | 589 | lc->sync_search = 0; |
584 | return 0; | 590 | return 0; |
585 | } | 591 | } |
586 | 592 | ||
587 | static int core_is_clean(struct dirty_log *log, region_t region) | 593 | static int core_is_clean(struct dm_dirty_log *log, region_t region) |
588 | { | 594 | { |
589 | struct log_c *lc = (struct log_c *) log->context; | 595 | struct log_c *lc = (struct log_c *) log->context; |
590 | return log_test_bit(lc->clean_bits, region); | 596 | return log_test_bit(lc->clean_bits, region); |
591 | } | 597 | } |
592 | 598 | ||
593 | static int core_in_sync(struct dirty_log *log, region_t region, int block) | 599 | static int core_in_sync(struct dm_dirty_log *log, region_t region, int block) |
594 | { | 600 | { |
595 | struct log_c *lc = (struct log_c *) log->context; | 601 | struct log_c *lc = (struct log_c *) log->context; |
596 | return log_test_bit(lc->sync_bits, region); | 602 | return log_test_bit(lc->sync_bits, region); |
597 | } | 603 | } |
598 | 604 | ||
599 | static int core_flush(struct dirty_log *log) | 605 | static int core_flush(struct dm_dirty_log *log) |
600 | { | 606 | { |
601 | /* no op */ | 607 | /* no op */ |
602 | return 0; | 608 | return 0; |
603 | } | 609 | } |
604 | 610 | ||
605 | static int disk_flush(struct dirty_log *log) | 611 | static int disk_flush(struct dm_dirty_log *log) |
606 | { | 612 | { |
607 | int r; | 613 | int r; |
608 | struct log_c *lc = (struct log_c *) log->context; | 614 | struct log_c *lc = (struct log_c *) log->context; |
@@ -620,19 +626,19 @@ static int disk_flush(struct dirty_log *log) | |||
620 | return r; | 626 | return r; |
621 | } | 627 | } |
622 | 628 | ||
623 | static void core_mark_region(struct dirty_log *log, region_t region) | 629 | static void core_mark_region(struct dm_dirty_log *log, region_t region) |
624 | { | 630 | { |
625 | struct log_c *lc = (struct log_c *) log->context; | 631 | struct log_c *lc = (struct log_c *) log->context; |
626 | log_clear_bit(lc, lc->clean_bits, region); | 632 | log_clear_bit(lc, lc->clean_bits, region); |
627 | } | 633 | } |
628 | 634 | ||
629 | static void core_clear_region(struct dirty_log *log, region_t region) | 635 | static void core_clear_region(struct dm_dirty_log *log, region_t region) |
630 | { | 636 | { |
631 | struct log_c *lc = (struct log_c *) log->context; | 637 | struct log_c *lc = (struct log_c *) log->context; |
632 | log_set_bit(lc, lc->clean_bits, region); | 638 | log_set_bit(lc, lc->clean_bits, region); |
633 | } | 639 | } |
634 | 640 | ||
635 | static int core_get_resync_work(struct dirty_log *log, region_t *region) | 641 | static int core_get_resync_work(struct dm_dirty_log *log, region_t *region) |
636 | { | 642 | { |
637 | struct log_c *lc = (struct log_c *) log->context; | 643 | struct log_c *lc = (struct log_c *) log->context; |
638 | 644 | ||
@@ -655,7 +661,7 @@ static int core_get_resync_work(struct dirty_log *log, region_t *region) | |||
655 | return 1; | 661 | return 1; |
656 | } | 662 | } |
657 | 663 | ||
658 | static void core_set_region_sync(struct dirty_log *log, region_t region, | 664 | static void core_set_region_sync(struct dm_dirty_log *log, region_t region, |
659 | int in_sync) | 665 | int in_sync) |
660 | { | 666 | { |
661 | struct log_c *lc = (struct log_c *) log->context; | 667 | struct log_c *lc = (struct log_c *) log->context; |
@@ -670,7 +676,7 @@ static void core_set_region_sync(struct dirty_log *log, region_t region, | |||
670 | } | 676 | } |
671 | } | 677 | } |
672 | 678 | ||
673 | static region_t core_get_sync_count(struct dirty_log *log) | 679 | static region_t core_get_sync_count(struct dm_dirty_log *log) |
674 | { | 680 | { |
675 | struct log_c *lc = (struct log_c *) log->context; | 681 | struct log_c *lc = (struct log_c *) log->context; |
676 | 682 | ||
@@ -681,7 +687,7 @@ static region_t core_get_sync_count(struct dirty_log *log) | |||
681 | if (lc->sync != DEFAULTSYNC) \ | 687 | if (lc->sync != DEFAULTSYNC) \ |
682 | DMEMIT("%ssync ", lc->sync == NOSYNC ? "no" : "") | 688 | DMEMIT("%ssync ", lc->sync == NOSYNC ? "no" : "") |
683 | 689 | ||
684 | static int core_status(struct dirty_log *log, status_type_t status, | 690 | static int core_status(struct dm_dirty_log *log, status_type_t status, |
685 | char *result, unsigned int maxlen) | 691 | char *result, unsigned int maxlen) |
686 | { | 692 | { |
687 | int sz = 0; | 693 | int sz = 0; |
@@ -701,7 +707,7 @@ static int core_status(struct dirty_log *log, status_type_t status, | |||
701 | return sz; | 707 | return sz; |
702 | } | 708 | } |
703 | 709 | ||
704 | static int disk_status(struct dirty_log *log, status_type_t status, | 710 | static int disk_status(struct dm_dirty_log *log, status_type_t status, |
705 | char *result, unsigned int maxlen) | 711 | char *result, unsigned int maxlen) |
706 | { | 712 | { |
707 | int sz = 0; | 713 | int sz = 0; |
@@ -723,7 +729,7 @@ static int disk_status(struct dirty_log *log, status_type_t status, | |||
723 | return sz; | 729 | return sz; |
724 | } | 730 | } |
725 | 731 | ||
726 | static struct dirty_log_type _core_type = { | 732 | static struct dm_dirty_log_type _core_type = { |
727 | .name = "core", | 733 | .name = "core", |
728 | .module = THIS_MODULE, | 734 | .module = THIS_MODULE, |
729 | .ctr = core_ctr, | 735 | .ctr = core_ctr, |
@@ -741,7 +747,7 @@ static struct dirty_log_type _core_type = { | |||
741 | .status = core_status, | 747 | .status = core_status, |
742 | }; | 748 | }; |
743 | 749 | ||
744 | static struct dirty_log_type _disk_type = { | 750 | static struct dm_dirty_log_type _disk_type = { |
745 | .name = "disk", | 751 | .name = "disk", |
746 | .module = THIS_MODULE, | 752 | .module = THIS_MODULE, |
747 | .ctr = disk_ctr, | 753 | .ctr = disk_ctr, |
@@ -764,14 +770,14 @@ int __init dm_dirty_log_init(void) | |||
764 | { | 770 | { |
765 | int r; | 771 | int r; |
766 | 772 | ||
767 | r = dm_register_dirty_log_type(&_core_type); | 773 | r = dm_dirty_log_type_register(&_core_type); |
768 | if (r) | 774 | if (r) |
769 | DMWARN("couldn't register core log"); | 775 | DMWARN("couldn't register core log"); |
770 | 776 | ||
771 | r = dm_register_dirty_log_type(&_disk_type); | 777 | r = dm_dirty_log_type_register(&_disk_type); |
772 | if (r) { | 778 | if (r) { |
773 | DMWARN("couldn't register disk type"); | 779 | DMWARN("couldn't register disk type"); |
774 | dm_unregister_dirty_log_type(&_core_type); | 780 | dm_dirty_log_type_unregister(&_core_type); |
775 | } | 781 | } |
776 | 782 | ||
777 | return r; | 783 | return r; |
@@ -779,15 +785,10 @@ int __init dm_dirty_log_init(void) | |||
779 | 785 | ||
780 | void __exit dm_dirty_log_exit(void) | 786 | void __exit dm_dirty_log_exit(void) |
781 | { | 787 | { |
782 | dm_unregister_dirty_log_type(&_disk_type); | 788 | dm_dirty_log_type_unregister(&_disk_type); |
783 | dm_unregister_dirty_log_type(&_core_type); | 789 | dm_dirty_log_type_unregister(&_core_type); |
784 | } | 790 | } |
785 | 791 | ||
786 | EXPORT_SYMBOL(dm_register_dirty_log_type); | ||
787 | EXPORT_SYMBOL(dm_unregister_dirty_log_type); | ||
788 | EXPORT_SYMBOL(dm_create_dirty_log); | ||
789 | EXPORT_SYMBOL(dm_destroy_dirty_log); | ||
790 | |||
791 | module_init(dm_dirty_log_init); | 792 | module_init(dm_dirty_log_init); |
792 | module_exit(dm_dirty_log_exit); | 793 | module_exit(dm_dirty_log_exit); |
793 | 794 | ||
diff --git a/drivers/md/dm-log.h b/drivers/md/dm-log.h index 3fae87eb5963..2da48a857cb9 100644 --- a/drivers/md/dm-log.h +++ b/drivers/md/dm-log.h | |||
@@ -1,52 +1,58 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2003 Sistina Software | 2 | * Copyright (C) 2003 Sistina Software |
3 | * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * Device-Mapper dirty region log. | ||
3 | * | 6 | * |
4 | * This file is released under the LGPL. | 7 | * This file is released under the LGPL. |
5 | */ | 8 | */ |
6 | 9 | ||
7 | #ifndef DM_DIRTY_LOG | 10 | #ifndef _LINUX_DM_DIRTY_LOG |
8 | #define DM_DIRTY_LOG | 11 | #define _LINUX_DM_DIRTY_LOG |
12 | |||
13 | #ifdef __KERNEL__ | ||
9 | 14 | ||
10 | #include "dm.h" | 15 | #include <linux/types.h> |
16 | #include <linux/device-mapper.h> | ||
11 | 17 | ||
12 | typedef sector_t region_t; | 18 | typedef sector_t region_t; |
13 | 19 | ||
14 | struct dirty_log_type; | 20 | struct dm_dirty_log_type; |
15 | 21 | ||
16 | struct dirty_log { | 22 | struct dm_dirty_log { |
17 | struct dirty_log_type *type; | 23 | struct dm_dirty_log_type *type; |
18 | void *context; | 24 | void *context; |
19 | }; | 25 | }; |
20 | 26 | ||
21 | struct dirty_log_type { | 27 | struct dm_dirty_log_type { |
22 | struct list_head list; | 28 | struct list_head list; |
23 | const char *name; | 29 | const char *name; |
24 | struct module *module; | 30 | struct module *module; |
25 | unsigned int use_count; | 31 | unsigned use_count; |
26 | 32 | ||
27 | int (*ctr)(struct dirty_log *log, struct dm_target *ti, | 33 | int (*ctr)(struct dm_dirty_log *log, struct dm_target *ti, |
28 | unsigned int argc, char **argv); | 34 | unsigned argc, char **argv); |
29 | void (*dtr)(struct dirty_log *log); | 35 | void (*dtr)(struct dm_dirty_log *log); |
30 | 36 | ||
31 | /* | 37 | /* |
32 | * There are times when we don't want the log to touch | 38 | * There are times when we don't want the log to touch |
33 | * the disk. | 39 | * the disk. |
34 | */ | 40 | */ |
35 | int (*presuspend)(struct dirty_log *log); | 41 | int (*presuspend)(struct dm_dirty_log *log); |
36 | int (*postsuspend)(struct dirty_log *log); | 42 | int (*postsuspend)(struct dm_dirty_log *log); |
37 | int (*resume)(struct dirty_log *log); | 43 | int (*resume)(struct dm_dirty_log *log); |
38 | 44 | ||
39 | /* | 45 | /* |
40 | * Retrieves the smallest size of region that the log can | 46 | * Retrieves the smallest size of region that the log can |
41 | * deal with. | 47 | * deal with. |
42 | */ | 48 | */ |
43 | uint32_t (*get_region_size)(struct dirty_log *log); | 49 | uint32_t (*get_region_size)(struct dm_dirty_log *log); |
44 | 50 | ||
45 | /* | 51 | /* |
46 | * A predicate to say whether a region is clean or not. | 52 | * A predicate to say whether a region is clean or not. |
47 | * May block. | 53 | * May block. |
48 | */ | 54 | */ |
49 | int (*is_clean)(struct dirty_log *log, region_t region); | 55 | int (*is_clean)(struct dm_dirty_log *log, region_t region); |
50 | 56 | ||
51 | /* | 57 | /* |
52 | * Returns: 0, 1, -EWOULDBLOCK, < 0 | 58 | * Returns: 0, 1, -EWOULDBLOCK, < 0 |
@@ -59,13 +65,14 @@ struct dirty_log_type { | |||
59 | * passed to a daemon to deal with, since a daemon is | 65 | * passed to a daemon to deal with, since a daemon is |
60 | * allowed to block. | 66 | * allowed to block. |
61 | */ | 67 | */ |
62 | int (*in_sync)(struct dirty_log *log, region_t region, int can_block); | 68 | int (*in_sync)(struct dm_dirty_log *log, region_t region, |
69 | int can_block); | ||
63 | 70 | ||
64 | /* | 71 | /* |
65 | * Flush the current log state (eg, to disk). This | 72 | * Flush the current log state (eg, to disk). This |
66 | * function may block. | 73 | * function may block. |
67 | */ | 74 | */ |
68 | int (*flush)(struct dirty_log *log); | 75 | int (*flush)(struct dm_dirty_log *log); |
69 | 76 | ||
70 | /* | 77 | /* |
71 | * Mark an area as clean or dirty. These functions may | 78 | * Mark an area as clean or dirty. These functions may |
@@ -73,8 +80,8 @@ struct dirty_log_type { | |||
73 | * be extremely rare (eg, allocating another chunk of | 80 | * be extremely rare (eg, allocating another chunk of |
74 | * memory for some reason). | 81 | * memory for some reason). |
75 | */ | 82 | */ |
76 | void (*mark_region)(struct dirty_log *log, region_t region); | 83 | void (*mark_region)(struct dm_dirty_log *log, region_t region); |
77 | void (*clear_region)(struct dirty_log *log, region_t region); | 84 | void (*clear_region)(struct dm_dirty_log *log, region_t region); |
78 | 85 | ||
79 | /* | 86 | /* |
80 | * Returns: <0 (error), 0 (no region), 1 (region) | 87 | * Returns: <0 (error), 0 (no region), 1 (region) |
@@ -88,44 +95,39 @@ struct dirty_log_type { | |||
88 | * tells you if an area is synchronised, the other | 95 | * tells you if an area is synchronised, the other |
89 | * assigns recovery work. | 96 | * assigns recovery work. |
90 | */ | 97 | */ |
91 | int (*get_resync_work)(struct dirty_log *log, region_t *region); | 98 | int (*get_resync_work)(struct dm_dirty_log *log, region_t *region); |
92 | 99 | ||
93 | /* | 100 | /* |
94 | * This notifies the log that the resync status of a region | 101 | * This notifies the log that the resync status of a region |
95 | * has changed. It also clears the region from the recovering | 102 | * has changed. It also clears the region from the recovering |
96 | * list (if present). | 103 | * list (if present). |
97 | */ | 104 | */ |
98 | void (*set_region_sync)(struct dirty_log *log, | 105 | void (*set_region_sync)(struct dm_dirty_log *log, |
99 | region_t region, int in_sync); | 106 | region_t region, int in_sync); |
100 | 107 | ||
101 | /* | 108 | /* |
102 | * Returns the number of regions that are in sync. | 109 | * Returns the number of regions that are in sync. |
103 | */ | 110 | */ |
104 | region_t (*get_sync_count)(struct dirty_log *log); | 111 | region_t (*get_sync_count)(struct dm_dirty_log *log); |
105 | 112 | ||
106 | /* | 113 | /* |
107 | * Support function for mirror status requests. | 114 | * Support function for mirror status requests. |
108 | */ | 115 | */ |
109 | int (*status)(struct dirty_log *log, status_type_t status_type, | 116 | int (*status)(struct dm_dirty_log *log, status_type_t status_type, |
110 | char *result, unsigned int maxlen); | 117 | char *result, unsigned maxlen); |
111 | }; | 118 | }; |
112 | 119 | ||
113 | int dm_register_dirty_log_type(struct dirty_log_type *type); | 120 | int dm_dirty_log_type_register(struct dm_dirty_log_type *type); |
114 | int dm_unregister_dirty_log_type(struct dirty_log_type *type); | 121 | int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type); |
115 | |||
116 | 122 | ||
117 | /* | 123 | /* |
118 | * Make sure you use these two functions, rather than calling | 124 | * Make sure you use these two functions, rather than calling |
119 | * type->constructor/destructor() directly. | 125 | * type->constructor/destructor() directly. |
120 | */ | 126 | */ |
121 | struct dirty_log *dm_create_dirty_log(const char *type_name, struct dm_target *ti, | 127 | struct dm_dirty_log *dm_dirty_log_create(const char *type_name, |
122 | unsigned int argc, char **argv); | 128 | struct dm_target *ti, |
123 | void dm_destroy_dirty_log(struct dirty_log *log); | 129 | unsigned argc, char **argv); |
124 | 130 | void dm_dirty_log_destroy(struct dm_dirty_log *log); | |
125 | /* | ||
126 | * init/exit functions. | ||
127 | */ | ||
128 | int dm_dirty_log_init(void); | ||
129 | void dm_dirty_log_exit(void); | ||
130 | 131 | ||
131 | #endif | 132 | #endif /* __KERNEL__ */ |
133 | #endif /* _LINUX_DM_DIRTY_LOG_H */ | ||
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 32c7c6d10939..5beeced4e522 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -74,7 +74,7 @@ struct region_hash { | |||
74 | unsigned region_shift; | 74 | unsigned region_shift; |
75 | 75 | ||
76 | /* holds persistent region state */ | 76 | /* holds persistent region state */ |
77 | struct dirty_log *log; | 77 | struct dm_dirty_log *log; |
78 | 78 | ||
79 | /* hash table */ | 79 | /* hash table */ |
80 | rwlock_t hash_lock; | 80 | rwlock_t hash_lock; |
@@ -184,7 +184,7 @@ static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw); | |||
184 | #define MIN_REGIONS 64 | 184 | #define MIN_REGIONS 64 |
185 | #define MAX_RECOVERY 1 | 185 | #define MAX_RECOVERY 1 |
186 | static int rh_init(struct region_hash *rh, struct mirror_set *ms, | 186 | static int rh_init(struct region_hash *rh, struct mirror_set *ms, |
187 | struct dirty_log *log, uint32_t region_size, | 187 | struct dm_dirty_log *log, uint32_t region_size, |
188 | region_t nr_regions) | 188 | region_t nr_regions) |
189 | { | 189 | { |
190 | unsigned int nr_buckets, max_buckets; | 190 | unsigned int nr_buckets, max_buckets; |
@@ -249,7 +249,7 @@ static void rh_exit(struct region_hash *rh) | |||
249 | } | 249 | } |
250 | 250 | ||
251 | if (rh->log) | 251 | if (rh->log) |
252 | dm_destroy_dirty_log(rh->log); | 252 | dm_dirty_log_destroy(rh->log); |
253 | if (rh->region_pool) | 253 | if (rh->region_pool) |
254 | mempool_destroy(rh->region_pool); | 254 | mempool_destroy(rh->region_pool); |
255 | vfree(rh->buckets); | 255 | vfree(rh->buckets); |
@@ -831,7 +831,7 @@ static void do_recovery(struct mirror_set *ms) | |||
831 | { | 831 | { |
832 | int r; | 832 | int r; |
833 | struct region *reg; | 833 | struct region *reg; |
834 | struct dirty_log *log = ms->rh.log; | 834 | struct dm_dirty_log *log = ms->rh.log; |
835 | 835 | ||
836 | /* | 836 | /* |
837 | * Start quiescing some regions. | 837 | * Start quiescing some regions. |
@@ -1017,7 +1017,7 @@ static void __bio_mark_nosync(struct mirror_set *ms, | |||
1017 | { | 1017 | { |
1018 | unsigned long flags; | 1018 | unsigned long flags; |
1019 | struct region_hash *rh = &ms->rh; | 1019 | struct region_hash *rh = &ms->rh; |
1020 | struct dirty_log *log = ms->rh.log; | 1020 | struct dm_dirty_log *log = ms->rh.log; |
1021 | struct region *reg; | 1021 | struct region *reg; |
1022 | region_t region = bio_to_region(rh, bio); | 1022 | region_t region = bio_to_region(rh, bio); |
1023 | int recovering = 0; | 1023 | int recovering = 0; |
@@ -1301,7 +1301,7 @@ static void do_mirror(struct work_struct *work) | |||
1301 | static struct mirror_set *alloc_context(unsigned int nr_mirrors, | 1301 | static struct mirror_set *alloc_context(unsigned int nr_mirrors, |
1302 | uint32_t region_size, | 1302 | uint32_t region_size, |
1303 | struct dm_target *ti, | 1303 | struct dm_target *ti, |
1304 | struct dirty_log *dl) | 1304 | struct dm_dirty_log *dl) |
1305 | { | 1305 | { |
1306 | size_t len; | 1306 | size_t len; |
1307 | struct mirror_set *ms = NULL; | 1307 | struct mirror_set *ms = NULL; |
@@ -1401,12 +1401,12 @@ static int get_mirror(struct mirror_set *ms, struct dm_target *ti, | |||
1401 | /* | 1401 | /* |
1402 | * Create dirty log: log_type #log_params <log_params> | 1402 | * Create dirty log: log_type #log_params <log_params> |
1403 | */ | 1403 | */ |
1404 | static struct dirty_log *create_dirty_log(struct dm_target *ti, | 1404 | static struct dm_dirty_log *create_dirty_log(struct dm_target *ti, |
1405 | unsigned int argc, char **argv, | 1405 | unsigned int argc, char **argv, |
1406 | unsigned int *args_used) | 1406 | unsigned int *args_used) |
1407 | { | 1407 | { |
1408 | unsigned int param_count; | 1408 | unsigned int param_count; |
1409 | struct dirty_log *dl; | 1409 | struct dm_dirty_log *dl; |
1410 | 1410 | ||
1411 | if (argc < 2) { | 1411 | if (argc < 2) { |
1412 | ti->error = "Insufficient mirror log arguments"; | 1412 | ti->error = "Insufficient mirror log arguments"; |
@@ -1425,7 +1425,7 @@ static struct dirty_log *create_dirty_log(struct dm_target *ti, | |||
1425 | return NULL; | 1425 | return NULL; |
1426 | } | 1426 | } |
1427 | 1427 | ||
1428 | dl = dm_create_dirty_log(argv[0], ti, param_count, argv + 2); | 1428 | dl = dm_dirty_log_create(argv[0], ti, param_count, argv + 2); |
1429 | if (!dl) { | 1429 | if (!dl) { |
1430 | ti->error = "Error creating mirror dirty log"; | 1430 | ti->error = "Error creating mirror dirty log"; |
1431 | return NULL; | 1431 | return NULL; |
@@ -1433,7 +1433,7 @@ static struct dirty_log *create_dirty_log(struct dm_target *ti, | |||
1433 | 1433 | ||
1434 | if (!_check_region_size(ti, dl->type->get_region_size(dl))) { | 1434 | if (!_check_region_size(ti, dl->type->get_region_size(dl))) { |
1435 | ti->error = "Invalid region size"; | 1435 | ti->error = "Invalid region size"; |
1436 | dm_destroy_dirty_log(dl); | 1436 | dm_dirty_log_destroy(dl); |
1437 | return NULL; | 1437 | return NULL; |
1438 | } | 1438 | } |
1439 | 1439 | ||
@@ -1494,7 +1494,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1494 | int r; | 1494 | int r; |
1495 | unsigned int nr_mirrors, m, args_used; | 1495 | unsigned int nr_mirrors, m, args_used; |
1496 | struct mirror_set *ms; | 1496 | struct mirror_set *ms; |
1497 | struct dirty_log *dl; | 1497 | struct dm_dirty_log *dl; |
1498 | 1498 | ||
1499 | dl = create_dirty_log(ti, argc, argv, &args_used); | 1499 | dl = create_dirty_log(ti, argc, argv, &args_used); |
1500 | if (!dl) | 1500 | if (!dl) |
@@ -1506,7 +1506,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1506 | if (!argc || sscanf(argv[0], "%u", &nr_mirrors) != 1 || | 1506 | if (!argc || sscanf(argv[0], "%u", &nr_mirrors) != 1 || |
1507 | nr_mirrors < 2 || nr_mirrors > DM_KCOPYD_MAX_REGIONS + 1) { | 1507 | nr_mirrors < 2 || nr_mirrors > DM_KCOPYD_MAX_REGIONS + 1) { |
1508 | ti->error = "Invalid number of mirrors"; | 1508 | ti->error = "Invalid number of mirrors"; |
1509 | dm_destroy_dirty_log(dl); | 1509 | dm_dirty_log_destroy(dl); |
1510 | return -EINVAL; | 1510 | return -EINVAL; |
1511 | } | 1511 | } |
1512 | 1512 | ||
@@ -1514,13 +1514,13 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1514 | 1514 | ||
1515 | if (argc < nr_mirrors * 2) { | 1515 | if (argc < nr_mirrors * 2) { |
1516 | ti->error = "Too few mirror arguments"; | 1516 | ti->error = "Too few mirror arguments"; |
1517 | dm_destroy_dirty_log(dl); | 1517 | dm_dirty_log_destroy(dl); |
1518 | return -EINVAL; | 1518 | return -EINVAL; |
1519 | } | 1519 | } |
1520 | 1520 | ||
1521 | ms = alloc_context(nr_mirrors, dl->type->get_region_size(dl), ti, dl); | 1521 | ms = alloc_context(nr_mirrors, dl->type->get_region_size(dl), ti, dl); |
1522 | if (!ms) { | 1522 | if (!ms) { |
1523 | dm_destroy_dirty_log(dl); | 1523 | dm_dirty_log_destroy(dl); |
1524 | return -ENOMEM; | 1524 | return -ENOMEM; |
1525 | } | 1525 | } |
1526 | 1526 | ||
@@ -1732,7 +1732,7 @@ out: | |||
1732 | static void mirror_presuspend(struct dm_target *ti) | 1732 | static void mirror_presuspend(struct dm_target *ti) |
1733 | { | 1733 | { |
1734 | struct mirror_set *ms = (struct mirror_set *) ti->private; | 1734 | struct mirror_set *ms = (struct mirror_set *) ti->private; |
1735 | struct dirty_log *log = ms->rh.log; | 1735 | struct dm_dirty_log *log = ms->rh.log; |
1736 | 1736 | ||
1737 | atomic_set(&ms->suspend, 1); | 1737 | atomic_set(&ms->suspend, 1); |
1738 | 1738 | ||
@@ -1761,7 +1761,7 @@ static void mirror_presuspend(struct dm_target *ti) | |||
1761 | static void mirror_postsuspend(struct dm_target *ti) | 1761 | static void mirror_postsuspend(struct dm_target *ti) |
1762 | { | 1762 | { |
1763 | struct mirror_set *ms = ti->private; | 1763 | struct mirror_set *ms = ti->private; |
1764 | struct dirty_log *log = ms->rh.log; | 1764 | struct dm_dirty_log *log = ms->rh.log; |
1765 | 1765 | ||
1766 | if (log->type->postsuspend && log->type->postsuspend(log)) | 1766 | if (log->type->postsuspend && log->type->postsuspend(log)) |
1767 | /* FIXME: need better error handling */ | 1767 | /* FIXME: need better error handling */ |
@@ -1771,7 +1771,7 @@ static void mirror_postsuspend(struct dm_target *ti) | |||
1771 | static void mirror_resume(struct dm_target *ti) | 1771 | static void mirror_resume(struct dm_target *ti) |
1772 | { | 1772 | { |
1773 | struct mirror_set *ms = ti->private; | 1773 | struct mirror_set *ms = ti->private; |
1774 | struct dirty_log *log = ms->rh.log; | 1774 | struct dm_dirty_log *log = ms->rh.log; |
1775 | 1775 | ||
1776 | atomic_set(&ms->suspend, 0); | 1776 | atomic_set(&ms->suspend, 0); |
1777 | if (log->type->resume && log->type->resume(log)) | 1777 | if (log->type->resume && log->type->resume(log)) |
@@ -1809,7 +1809,7 @@ static int mirror_status(struct dm_target *ti, status_type_t type, | |||
1809 | { | 1809 | { |
1810 | unsigned int m, sz = 0; | 1810 | unsigned int m, sz = 0; |
1811 | struct mirror_set *ms = (struct mirror_set *) ti->private; | 1811 | struct mirror_set *ms = (struct mirror_set *) ti->private; |
1812 | struct dirty_log *log = ms->rh.log; | 1812 | struct dm_dirty_log *log = ms->rh.log; |
1813 | char buffer[ms->nr_mirrors + 1]; | 1813 | char buffer[ms->nr_mirrors + 1]; |
1814 | 1814 | ||
1815 | switch (type) { | 1815 | switch (type) { |
diff --git a/drivers/md/dm.h b/drivers/md/dm.h index b4584a39383b..17f2d6a8b124 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h | |||
@@ -189,4 +189,10 @@ int dm_lock_for_deletion(struct mapped_device *md); | |||
189 | 189 | ||
190 | void dm_kobject_uevent(struct mapped_device *md); | 190 | void dm_kobject_uevent(struct mapped_device *md); |
191 | 191 | ||
192 | /* | ||
193 | * Dirty log | ||
194 | */ | ||
195 | int dm_dirty_log_init(void); | ||
196 | void dm_dirty_log_exit(void); | ||
197 | |||
192 | #endif | 198 | #endif |
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index cb784579956b..4db23378cfb1 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h | |||
@@ -10,6 +10,8 @@ | |||
10 | 10 | ||
11 | #ifdef __KERNEL__ | 11 | #ifdef __KERNEL__ |
12 | 12 | ||
13 | #include <linux/bio.h> | ||
14 | |||
13 | struct dm_target; | 15 | struct dm_target; |
14 | struct dm_table; | 16 | struct dm_table; |
15 | struct dm_dev; | 17 | struct dm_dev; |