dm integrity: count and display checksum failures
authorMikulas Patocka <mpatocka@redhat.com>
Fri, 21 Jul 2017 16:00:00 +0000 (12:00 -0400)
committerMike Snitzer <snitzer@redhat.com>
Mon, 28 Aug 2017 15:47:17 +0000 (11:47 -0400)
This changes DM integrity to count the number of checksum failures and
report the counter in response to STATUSTYPE_INFO request (via 'dmsetup
status').

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

index 689f89d..47fd409 100644 (file)
@@ -225,6 +225,8 @@ struct dm_integrity_c {
        struct alg_spec internal_hash_alg;
        struct alg_spec journal_crypt_alg;
        struct alg_spec journal_mac_alg;
+
+       atomic64_t number_of_mismatches;
 };
 
 struct dm_integrity_range {
@@ -309,6 +311,8 @@ static void dm_integrity_dtr(struct dm_target *ti);
 
 static void dm_integrity_io_error(struct dm_integrity_c *ic, const char *msg, int err)
 {
+       if (err == -EILSEQ)
+               atomic64_inc(&ic->number_of_mismatches);
        if (!cmpxchg(&ic->failed, 0, err))
                DMERR("Error on %s: %d", msg, err);
 }
@@ -1273,6 +1277,7 @@ again:
                                        DMERR("Checksum failed at sector 0x%llx",
                                              (unsigned long long)(sector - ((r + ic->tag_size - 1) / ic->tag_size)));
                                        r = -EILSEQ;
+                                       atomic64_inc(&ic->number_of_mismatches);
                                }
                                if (likely(checksums != checksums_onstack))
                                        kfree(checksums);
@@ -2230,7 +2235,7 @@ static void dm_integrity_status(struct dm_target *ti, status_type_t type,
 
        switch (type) {
        case STATUSTYPE_INFO:
-               result[0] = '\0';
+               DMEMIT("%llu", (unsigned long long)atomic64_read(&ic->number_of_mismatches));
                break;
 
        case STATUSTYPE_TABLE: {
@@ -2803,6 +2808,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
        bio_list_init(&ic->flush_bio_list);
        init_waitqueue_head(&ic->copy_to_journal_wait);
        init_completion(&ic->crypto_backoff);
+       atomic64_set(&ic->number_of_mismatches, 0);
 
        r = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &ic->dev);
        if (r) {
@@ -3199,7 +3205,7 @@ static void dm_integrity_dtr(struct dm_target *ti)
 
 static struct target_type integrity_target = {
        .name                   = "integrity",
-       .version                = {1, 0, 0},
+       .version                = {1, 1, 0},
        .module                 = THIS_MODULE,
        .features               = DM_TARGET_SINGLETON | DM_TARGET_INTEGRITY,
        .ctr                    = dm_integrity_ctr,