]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
dm integrity: add the "reset_recalculate" feature flag
authorMikulas Patocka <mpatocka@redhat.com>
Tue, 23 Mar 2021 14:59:45 +0000 (10:59 -0400)
committerMike Snitzer <snitzer@redhat.com>
Fri, 26 Mar 2021 18:53:42 +0000 (14:53 -0400)
Add a new flag "reset_recalculate" that will restart recalculating
from the beginning of the device. It can be used if we want to change
the hash function. Example:

dmsetup remove_all
rmmod brd
set -e
modprobe brd rd_size=1048576
dmsetup create in --table '0 2000000 integrity /dev/ram0 0 16 J 2 internal_hash:sha256 recalculate'
sleep 10
dmsetup status
dmsetup remove in
dmsetup create in --table '0 2000000 integrity /dev/ram0 0 16 J 2 internal_hash:sha3-256 reset_recalculate'

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
drivers/md/dm-integrity.c

index 46b5d542b8fe6a373efa06ca1a2284f9e490141a..fed8a7ccd7f9119272385c8021f3cb0acafb6507 100644 (file)
@@ -262,6 +262,7 @@ struct dm_integrity_c {
        bool journal_uptodate;
        bool just_formatted;
        bool recalculate_flag;
+       bool reset_recalculate_flag;
        bool discard;
        bool fix_padding;
        bool fix_hmac;
@@ -3134,7 +3135,8 @@ static void dm_integrity_resume(struct dm_target *ti)
                rw_journal_sectors(ic, REQ_OP_READ, 0, 0,
                                   ic->n_bitmap_blocks * (BITMAP_BLOCK_SIZE >> SECTOR_SHIFT), NULL);
                if (ic->mode == 'B') {
-                       if (ic->sb->log2_blocks_per_bitmap_bit == ic->log2_blocks_per_bitmap_bit) {
+                       if (ic->sb->log2_blocks_per_bitmap_bit == ic->log2_blocks_per_bitmap_bit &&
+                           !ic->reset_recalculate_flag) {
                                block_bitmap_copy(ic, ic->recalc_bitmap, ic->journal);
                                block_bitmap_copy(ic, ic->may_write_bitmap, ic->journal);
                                if (!block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors,
@@ -3156,7 +3158,8 @@ static void dm_integrity_resume(struct dm_target *ti)
                        }
                } else {
                        if (!(ic->sb->log2_blocks_per_bitmap_bit == ic->log2_blocks_per_bitmap_bit &&
-                             block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, BITMAP_OP_TEST_ALL_CLEAR))) {
+                             block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, BITMAP_OP_TEST_ALL_CLEAR)) ||
+                           ic->reset_recalculate_flag) {
                                ic->sb->flags |= cpu_to_le32(SB_FLAG_RECALCULATING);
                                ic->sb->recalc_sector = cpu_to_le64(0);
                        }
@@ -3169,6 +3172,10 @@ static void dm_integrity_resume(struct dm_target *ti)
                        dm_integrity_io_error(ic, "writing superblock", r);
        } else {
                replay_journal(ic);
+               if (ic->reset_recalculate_flag) {
+                       ic->sb->flags |= cpu_to_le32(SB_FLAG_RECALCULATING);
+                       ic->sb->recalc_sector = cpu_to_le64(0);
+               }
                if (ic->mode == 'B') {
                        ic->sb->flags |= cpu_to_le32(SB_FLAG_DIRTY_BITMAP);
                        ic->sb->log2_blocks_per_bitmap_bit = ic->log2_blocks_per_bitmap_bit;
@@ -3242,6 +3249,7 @@ static void dm_integrity_status(struct dm_target *ti, status_type_t type,
                arg_count += !!ic->meta_dev;
                arg_count += ic->sectors_per_block != 1;
                arg_count += !!(ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING));
+               arg_count += ic->reset_recalculate_flag;
                arg_count += ic->discard;
                arg_count += ic->mode == 'J';
                arg_count += ic->mode == 'J';
@@ -3261,6 +3269,8 @@ static void dm_integrity_status(struct dm_target *ti, status_type_t type,
                        DMEMIT(" block_size:%u", ic->sectors_per_block << SECTOR_SHIFT);
                if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING))
                        DMEMIT(" recalculate");
+               if (ic->reset_recalculate_flag)
+                       DMEMIT(" reset_recalculate");
                if (ic->discard)
                        DMEMIT(" allow_discards");
                DMEMIT(" journal_sectors:%u", ic->initial_sectors - SB_SECTORS);
@@ -3914,7 +3924,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
        unsigned extra_args;
        struct dm_arg_set as;
        static const struct dm_arg _args[] = {
-               {0, 17, "Invalid number of feature args"},
+               {0, 18, "Invalid number of feature args"},
        };
        unsigned journal_sectors, interleave_sectors, buffer_sectors, journal_watermark, sync_msec;
        bool should_write_sb;
@@ -4058,6 +4068,9 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
                                goto bad;
                } else if (!strcmp(opt_string, "recalculate")) {
                        ic->recalculate_flag = true;
+               } else if (!strcmp(opt_string, "reset_recalculate")) {
+                       ic->recalculate_flag = true;
+                       ic->reset_recalculate_flag = true;
                } else if (!strcmp(opt_string, "allow_discards")) {
                        ic->discard = true;
                } else if (!strcmp(opt_string, "fix_padding")) {
@@ -4554,7 +4567,7 @@ static void dm_integrity_dtr(struct dm_target *ti)
 
 static struct target_type integrity_target = {
        .name                   = "integrity",
-       .version                = {1, 7, 0},
+       .version                = {1, 8, 0},
        .module                 = THIS_MODULE,
        .features               = DM_TARGET_SINGLETON | DM_TARGET_INTEGRITY,
        .ctr                    = dm_integrity_ctr,