diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/md/dm-integrity.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 54b3fe1403a8..42be03bbfafa 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/rbtree.h> | 15 | #include <linux/rbtree.h> |
| 16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
| 17 | #include <linux/random.h> | 17 | #include <linux/random.h> |
| 18 | #include <linux/reboot.h> | ||
| 18 | #include <crypto/hash.h> | 19 | #include <crypto/hash.h> |
| 19 | #include <crypto/skcipher.h> | 20 | #include <crypto/skcipher.h> |
| 20 | #include <linux/async_tx.h> | 21 | #include <linux/async_tx.h> |
| @@ -257,6 +258,8 @@ struct dm_integrity_c { | |||
| 257 | struct alg_spec journal_mac_alg; | 258 | struct alg_spec journal_mac_alg; |
| 258 | 259 | ||
| 259 | atomic64_t number_of_mismatches; | 260 | atomic64_t number_of_mismatches; |
| 261 | |||
| 262 | struct notifier_block reboot_notifier; | ||
| 260 | }; | 263 | }; |
| 261 | 264 | ||
| 262 | struct dm_integrity_range { | 265 | struct dm_integrity_range { |
| @@ -2717,11 +2720,27 @@ clear_journal: | |||
| 2717 | init_journal_node(&ic->journal_tree[i]); | 2720 | init_journal_node(&ic->journal_tree[i]); |
| 2718 | } | 2721 | } |
| 2719 | 2722 | ||
| 2723 | static int dm_integrity_reboot(struct notifier_block *n, unsigned long code, void *x) | ||
| 2724 | { | ||
| 2725 | struct dm_integrity_c *ic = container_of(n, struct dm_integrity_c, reboot_notifier); | ||
| 2726 | |||
| 2727 | if (ic->mode == 'B') { | ||
| 2728 | DEBUG_print("dm_integrity_reboot\n"); | ||
| 2729 | cancel_delayed_work_sync(&ic->bitmap_flush_work); | ||
| 2730 | queue_delayed_work(ic->commit_wq, &ic->bitmap_flush_work, 0); | ||
| 2731 | flush_workqueue(ic->commit_wq); | ||
| 2732 | } | ||
| 2733 | |||
| 2734 | return NOTIFY_DONE; | ||
| 2735 | } | ||
| 2736 | |||
| 2720 | static void dm_integrity_postsuspend(struct dm_target *ti) | 2737 | static void dm_integrity_postsuspend(struct dm_target *ti) |
| 2721 | { | 2738 | { |
| 2722 | struct dm_integrity_c *ic = (struct dm_integrity_c *)ti->private; | 2739 | struct dm_integrity_c *ic = (struct dm_integrity_c *)ti->private; |
| 2723 | int r; | 2740 | int r; |
| 2724 | 2741 | ||
| 2742 | WARN_ON(unregister_reboot_notifier(&ic->reboot_notifier)); | ||
| 2743 | |||
| 2725 | del_timer_sync(&ic->autocommit_timer); | 2744 | del_timer_sync(&ic->autocommit_timer); |
| 2726 | 2745 | ||
| 2727 | WRITE_ONCE(ic->suspending, 1); | 2746 | WRITE_ONCE(ic->suspending, 1); |
| @@ -2829,6 +2848,11 @@ static void dm_integrity_resume(struct dm_target *ti) | |||
| 2829 | recalc_write_super(ic); | 2848 | recalc_write_super(ic); |
| 2830 | } | 2849 | } |
| 2831 | } | 2850 | } |
| 2851 | |||
| 2852 | ic->reboot_notifier.notifier_call = dm_integrity_reboot; | ||
| 2853 | ic->reboot_notifier.next = NULL; | ||
| 2854 | ic->reboot_notifier.priority = INT_MAX - 1; /* be notified after md and before hardware drivers */ | ||
| 2855 | WARN_ON(register_reboot_notifier(&ic->reboot_notifier)); | ||
| 2832 | } | 2856 | } |
| 2833 | 2857 | ||
| 2834 | static void dm_integrity_status(struct dm_target *ti, status_type_t type, | 2858 | static void dm_integrity_status(struct dm_target *ti, status_type_t type, |
