aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/dm-integrity.c24
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
262struct dm_integrity_range { 265struct 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
2723static 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
2720static void dm_integrity_postsuspend(struct dm_target *ti) 2737static 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
2834static void dm_integrity_status(struct dm_target *ti, status_type_t type, 2858static void dm_integrity_status(struct dm_target *ti, status_type_t type,