dm integrity: use discard support when recalculating
authorMikulas Patocka <mpatocka@redhat.com>
Wed, 28 Apr 2021 21:00:23 +0000 (17:00 -0400)
committerMike Snitzer <snitzer@redhat.com>
Fri, 30 Apr 2021 18:02:06 +0000 (14:02 -0400)
If we have discard support we don't have to recalculate hash - we can
just fill the metadata with the discard pattern.

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

index 4565816..781942a 100644 (file)
@@ -2689,26 +2689,30 @@ next_chunk:
        if (unlikely(dm_integrity_failed(ic)))
                goto err;
 
-       io_req.bi_op = REQ_OP_READ;
-       io_req.bi_op_flags = 0;
-       io_req.mem.type = DM_IO_VMA;
-       io_req.mem.ptr.addr = ic->recalc_buffer;
-       io_req.notify.fn = NULL;
-       io_req.client = ic->io;
-       io_loc.bdev = ic->dev->bdev;
-       io_loc.sector = get_data_sector(ic, area, offset);
-       io_loc.count = n_sectors;
+       if (!ic->discard) {
+               io_req.bi_op = REQ_OP_READ;
+               io_req.bi_op_flags = 0;
+               io_req.mem.type = DM_IO_VMA;
+               io_req.mem.ptr.addr = ic->recalc_buffer;
+               io_req.notify.fn = NULL;
+               io_req.client = ic->io;
+               io_loc.bdev = ic->dev->bdev;
+               io_loc.sector = get_data_sector(ic, area, offset);
+               io_loc.count = n_sectors;
 
-       r = dm_io(&io_req, 1, &io_loc, NULL);
-       if (unlikely(r)) {
-               dm_integrity_io_error(ic, "reading data", r);
-               goto err;
-       }
+               r = dm_io(&io_req, 1, &io_loc, NULL);
+               if (unlikely(r)) {
+                       dm_integrity_io_error(ic, "reading data", r);
+                       goto err;
+               }
 
-       t = ic->recalc_tags;
-       for (i = 0; i < n_sectors; i += ic->sectors_per_block) {
-               integrity_sector_checksum(ic, logical_sector + i, ic->recalc_buffer + (i << SECTOR_SHIFT), t);
-               t += ic->tag_size;
+               t = ic->recalc_tags;
+               for (i = 0; i < n_sectors; i += ic->sectors_per_block) {
+                       integrity_sector_checksum(ic, logical_sector + i, ic->recalc_buffer + (i << SECTOR_SHIFT), t);
+                       t += ic->tag_size;
+               }
+       } else {
+               t = ic->recalc_tags + (n_sectors >> ic->sb->log2_sectors_per_block) * ic->tag_size;
        }
 
        metadata_block = get_metadata_sector_and_offset(ic, area, offset, &metadata_offset);
@@ -4364,11 +4368,13 @@ try_smaller_buffer:
                        goto bad;
                }
                INIT_WORK(&ic->recalc_work, integrity_recalc);
-               ic->recalc_buffer = vmalloc(RECALC_SECTORS << SECTOR_SHIFT);
-               if (!ic->recalc_buffer) {
-                       ti->error = "Cannot allocate buffer for recalculating";
-                       r = -ENOMEM;
-                       goto bad;
+               if (!ic->discard) {
+                       ic->recalc_buffer = vmalloc(RECALC_SECTORS << SECTOR_SHIFT);
+                       if (!ic->recalc_buffer) {
+                               ti->error = "Cannot allocate buffer for recalculating";
+                               r = -ENOMEM;
+                               goto bad;
+                       }
                }
                ic->recalc_tags = kvmalloc_array(RECALC_SECTORS >> ic->sb->log2_sectors_per_block,
                                                 ic->tag_size, GFP_KERNEL);
@@ -4377,6 +4383,9 @@ try_smaller_buffer:
                        r = -ENOMEM;
                        goto bad;
                }
+               if (ic->discard)
+                       memset(ic->recalc_tags, DISCARD_FILLER,
+                              (RECALC_SECTORS >> ic->sb->log2_sectors_per_block) * ic->tag_size);
        } else {
                if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) {
                        ti->error = "Recalculate can only be specified with internal_hash";
@@ -4570,7 +4579,7 @@ static void dm_integrity_dtr(struct dm_target *ti)
 
 static struct target_type integrity_target = {
        .name                   = "integrity",
-       .version                = {1, 8, 0},
+       .version                = {1, 9, 0},
        .module                 = THIS_MODULE,
        .features               = DM_TARGET_SINGLETON | DM_TARGET_INTEGRITY,
        .ctr                    = dm_integrity_ctr,