dm cache metadata: use dm_bitset_new() to create the dirty bitset in format 2
authorJoe Thornber <ejt@redhat.com>
Thu, 22 Sep 2016 14:45:21 +0000 (10:45 -0400)
committerMike Snitzer <snitzer@redhat.com>
Thu, 16 Feb 2017 18:12:49 +0000 (13:12 -0500)
Big speed up with large configs.

Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
drivers/md/dm-cache-metadata.c

index 5a5ef996a26a7baa80b8fed217d89f6c1d8aad34..7e31a4b1c476be604dd40df2be33ab3cdfda6998 100644 (file)
@@ -1547,10 +1547,16 @@ static int __set_dirty_bits_v1(struct dm_cache_metadata *cmd, unsigned nr_bits,
        return 0;
 }
 
+static int is_dirty_callback(uint32_t index, bool *value, void *context)
+{
+       unsigned long *bits = context;
+       *value = test_bit(index, bits);
+       return 0;
+}
+
 static int __set_dirty_bits_v2(struct dm_cache_metadata *cmd, unsigned nr_bits, unsigned long *bits)
 {
        int r = 0;
-       unsigned i;
 
        /* nr_bits is really just a sanity check */
        if (nr_bits != from_cblock(cmd->cache_blocks)) {
@@ -1558,18 +1564,12 @@ static int __set_dirty_bits_v2(struct dm_cache_metadata *cmd, unsigned nr_bits,
                return -EINVAL;
        }
 
-       for (i = 0; i < nr_bits; i++) {
-               if (test_bit(i, bits))
-                       r = dm_bitset_set_bit(&cmd->dirty_info, cmd->dirty_root, i, &cmd->dirty_root);
-               else
-                       r = dm_bitset_clear_bit(&cmd->dirty_info, cmd->dirty_root, i, &cmd->dirty_root);
-
-               if (r)
-                       return r;
-       }
+       r = dm_bitset_del(&cmd->dirty_info, cmd->dirty_root);
+       if (r)
+               return r;
 
        cmd->changed = true;
-       return dm_bitset_flush(&cmd->dirty_info, cmd->dirty_root, &cmd->dirty_root);
+       return dm_bitset_new(&cmd->dirty_info, &cmd->dirty_root, nr_bits, is_dirty_callback, bits);
 }
 
 int dm_cache_set_dirty_bits(struct dm_cache_metadata *cmd,