Commit 1f5a7759 authored by Mikulas Patocka's avatar Mikulas Patocka Committed by Mike Snitzer

dm integrity: handle machine reboot in bitmap mode

When in bitmap mode the bitmap must be cleared when rebooting.  This
commit adds the reboot hook.
Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 468dfca3
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/rbtree.h> #include <linux/rbtree.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/reboot.h>
#include <crypto/hash.h> #include <crypto/hash.h>
#include <crypto/skcipher.h> #include <crypto/skcipher.h>
#include <linux/async_tx.h> #include <linux/async_tx.h>
...@@ -257,6 +258,8 @@ struct dm_integrity_c { ...@@ -257,6 +258,8 @@ struct dm_integrity_c {
struct alg_spec journal_mac_alg; struct alg_spec journal_mac_alg;
atomic64_t number_of_mismatches; atomic64_t number_of_mismatches;
struct notifier_block reboot_notifier;
}; };
struct dm_integrity_range { struct dm_integrity_range {
...@@ -2717,11 +2720,27 @@ static void replay_journal(struct dm_integrity_c *ic) ...@@ -2717,11 +2720,27 @@ static void replay_journal(struct dm_integrity_c *ic)
init_journal_node(&ic->journal_tree[i]); init_journal_node(&ic->journal_tree[i]);
} }
static int dm_integrity_reboot(struct notifier_block *n, unsigned long code, void *x)
{
struct dm_integrity_c *ic = container_of(n, struct dm_integrity_c, reboot_notifier);
if (ic->mode == 'B') {
DEBUG_print("dm_integrity_reboot\n");
cancel_delayed_work_sync(&ic->bitmap_flush_work);
queue_delayed_work(ic->commit_wq, &ic->bitmap_flush_work, 0);
flush_workqueue(ic->commit_wq);
}
return NOTIFY_DONE;
}
static void dm_integrity_postsuspend(struct dm_target *ti) static void dm_integrity_postsuspend(struct dm_target *ti)
{ {
struct dm_integrity_c *ic = (struct dm_integrity_c *)ti->private; struct dm_integrity_c *ic = (struct dm_integrity_c *)ti->private;
int r; int r;
WARN_ON(unregister_reboot_notifier(&ic->reboot_notifier));
del_timer_sync(&ic->autocommit_timer); del_timer_sync(&ic->autocommit_timer);
WRITE_ONCE(ic->suspending, 1); WRITE_ONCE(ic->suspending, 1);
...@@ -2829,6 +2848,11 @@ static void dm_integrity_resume(struct dm_target *ti) ...@@ -2829,6 +2848,11 @@ static void dm_integrity_resume(struct dm_target *ti)
recalc_write_super(ic); recalc_write_super(ic);
} }
} }
ic->reboot_notifier.notifier_call = dm_integrity_reboot;
ic->reboot_notifier.next = NULL;
ic->reboot_notifier.priority = INT_MAX - 1; /* be notified after md and before hardware drivers */
WARN_ON(register_reboot_notifier(&ic->reboot_notifier));
} }
static void dm_integrity_status(struct dm_target *ti, status_type_t type, static void dm_integrity_status(struct dm_target *ti, status_type_t type,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment